﻿---
title: Tutorial 2: Customize TLS/SSL certificates for a self-managed Elastic Stack
description: This tutorial is a follow-on to Tutorial 1: Installing a self-managed Elastic Stack. The first tutorial describes how to configure a multi-node Elasticsearch...
url: https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/deploy/self-managed/tutorial-self-managed-secure
products:
  - Elastic Stack
  - Elasticsearch
  - Kibana
applies_to:
  - Self-managed Elastic deployments: Generally available
---

# Tutorial 2: Customize TLS/SSL certificates for a self-managed Elastic Stack
This tutorial is a follow-on to [Tutorial 1: Installing a self-managed Elastic Stack](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/deploy/self-managed/tutorial-self-managed-install). The first tutorial describes how to configure a multi-node Elasticsearch cluster and then set up Kibana, followed by Fleet Server and Elastic Agent. It relies on the Elasticsearch [automatic security setup](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/security/self-auto-setup) and the self-signed certificate generated by the Fleet Server Quick Start flow, as described in its [security overview](/elastic/docs-builder/docs/3028/deploy-manage/deploy/self-managed/tutorial-self-managed-install#security-overview).
With this tutorial, you can replace or extend that default setup by generating and configuring your own certificates across the Elastic Stack. For example, you might want to:
- Use certificates signed by your organization's certificate authority or by a public CA.
- Create a new private CA and certificates for the Elasticsearch transport or HTTP layers.
- Configure HTTPS for browser-to-Kibana communication (**highly recommended**).
- Customize TLS for Fleet Server and Elastic Agent communication.
- Use a shared CA for all public-facing endpoints (Elasticsearch HTTP, Kibana, Fleet Server) while keeping a separate trust domain for Elasticsearch transport.

<note>
  You do not need to complete every step in this tutorial. Depending on your requirements, you can follow only the sections relevant to your use case (for example, configuring HTTPS for Kibana, or securing Fleet Server and Elastic Agent communication with CA-signed certificates).
</note>


## Customizing certificates across the Elastic Stack

Beginning with Elastic 8.0, security is enabled in the Elastic Stack by default. These steps show how to transition from the automatic certificate configuration to a manually managed model that aligns with your PKI, trust, and HTTPS requirements.
Depending on your design, you will generate or provide certificate material for the Elasticsearch transport layer, the Elasticsearch HTTP layer, browser-to-Kibana HTTPS, and the TLS connections used by Fleet Server and Elastic Agent.
The process is organized into the following steps:
- [Prerequisites and assumptions](#install-stack-demo-secure-prereqs)
- [Step 1: Generate a new self-signed CA certificate](#install-stack-demo-secure-ca)
- [Step 2: Generate a new certificate for the transport layer](#install-stack-demo-secure-transport)
- [Step 3: Generate new certificate(s) for the HTTP layer](#install-stack-demo-secure-http)
- [Step 4: Configure security on additional Elasticsearch nodes](#install-stack-demo-secure-second-node)
- [Step 5: Generate server-side and client-side certificates for Kibana](#install-stack-demo-secure-kib-es)
- [Step 6: Install Fleet with SSL certificates configured](#install-stack-demo-secure-fleet)
- [Step 7: Install Elastic Agent](#install-stack-demo-secure-agent)
- [Step 8: View your system data](#install-stack-demo-secure-view-data)
- [Next steps](#install-stack-demo-secure-next-steps)

It should take between one and two hours to complete these steps.

## Prerequisites and assumptions

Before starting, you'll need to have set up an on-premises Elasticsearch cluster with Kibana, following the steps in [Tutorial 1: Installing a self-managed Elastic Stack](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/deploy/self-managed/tutorial-self-managed-install).
The examples in this guide use RPM packages to install the Elastic Stack components on hosts running Red Hat Enterprise Linux 8. The steps for other install methods and operating systems are similar, and can be found in the documentation linked from each section.
Special considerations such as firewalls and proxy servers are not covered here.

## Step 1: Generate a new self-signed CA certificate

In a production environment you would typically use the CA certificate from your own organization, along with the certificate files generated for the hosts where the Elastic Stack is being installed. For demonstration purposes, we'll use the Elastic certificate utility to configure a self-signed CA certificate.
1. On the first node in your Elasticsearch cluster, stop the Elasticsearch service:
   ```shell
   sudo systemctl stop elasticsearch.service
   ```
2. Generate a CA certificate using the provided certificate utility, `elasticsearch-certutil`. The location of the utility depends on the installation method you used to install Elasticsearch. Refer to [`elasticsearch-certutil`](https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3028/reference/elasticsearch/command-line-tools/certutil) for the command details and to [Different CA](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/security/different-ca) for details about the procedure as a whole.

Run the following command. When prompted, specify a unique name for the output file, such as `elastic-stack-ca.zip`:
```shell
sudo /usr/share/elasticsearch/bin/elasticsearch-certutil ca -pem
```

1. Move the output file to the `/etc/elasticsearch/certs` directory. This directory is created automatically when you install Elasticsearch.
   ```shell
   sudo mv /usr/share/elasticsearch/elastic-stack-ca.zip /etc/elasticsearch/certs/
   ```
2. Unzip the file:
   ```shell
   sudo unzip -d /etc/elasticsearch/certs /etc/elasticsearch/certs/elastic-stack-ca.zip
   ```
3. View the files that were unpacked into a new `ca` directory:
   ```shell
   sudo ls /etc/elasticsearch/certs/ca/
   ```
   - `ca.crt`: The generated certificate (or you can substitute this with your own certificate, signed by your organization's certificate authority)
- `ca.key`: The certificate authority's private key
   These steps to generate new self-signed CA certificates need to be done only on the first Elasticsearch node. The other Elasticsearch nodes will use the same `ca.crt` and `ca.key` files.
4. From the `/etc/elasticsearch/certs/ca/` directory, import the newly created CA certificate into the Elasticsearch truststore. This step ensures that your cluster trusts the new CA certificate.
   <note>
   On a new installation a new keystore and truststore are created automatically. If you're running these steps on an existing Elasticsearch installation and you know the password to the keystore and the truststore, follow the instructions in [Different CA](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/security/different-ca)  to import the CA certificate.
   </note>
   Run the `keytool` command as shown, replacing `<password>` with a unique password for the truststore, and store the password securely:
   ```shell
   sudo /usr/share/elasticsearch/jdk/bin/keytool -importcert -trustcacerts -noprompt -keystore /etc/elasticsearch/certs/elastic-stack-ca.p12 -storepass <password> -alias new-ca -file /etc/elasticsearch/certs/ca/ca.crt
   ```
5. Ensure that the new key was added to the keystore:
   ```shell
   sudo /usr/share/elasticsearch/jdk/bin/keytool -keystore /etc/elasticsearch/certs/elastic-stack-ca.p12 -list
   ```
   <note>
   The keytool utility is provided as part of the Elasticsearch installation and is located at: `/usr/share/elasticsearch/jdk/bin/keytool` on RPM installations.
   </note>
   Enter your password when prompted. The result should show the details for your newly added key:
   ```text
   Keystore type: jks
   Keystore provider: SUN
   Your keystore contains 1 entry
   new-ca, Jul 12, 2023, trustedCertEntry,
   Certificate fingerprint (SHA-256): F0:86:6B:57:FC...
   ```


## Step 2: Generate a new certificate for the transport layer

This guide assumes the use of self-signed certificates, but the process to import CA-signed certificates is the same. If you're using a CA provided by your organization, you need to generate Certificate Signing Requests (CSRs) and then use the signed certificates in this step. Once the certificates are generated, whether self-signed or CA-signed, the steps are the same.
1. From the Elasticsearch installation directory, using the newly-created CA certificate and private key, create a new certificate for your elasticsearch node:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca-cert /etc/elasticsearch/certs/ca/ca.crt --ca-key /etc/elasticsearch/certs/ca/ca.key
   ```
   When prompted, choose an output file name (you can use the default `elastic-certificates.p12`) and a password for the certificate.
2. Move the generated file to the `/etc/elasticsearch/certs` directory:
   ```shell
   sudo mv /usr/share/elasticsearch/elastic-certificates.p12 /etc/elasticsearch/certs/
   ```
   <important>
   If you're running these steps on a production cluster that already contains data: In a cluster with multiple Elasticsearch nodes, before proceeding you first need to perform a [Rolling restart](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/maintenance/start-stop-services/full-cluster-restart-rolling-restart-procedures) beginning with the node where you're updating the keystore. Stop at the `Perform any needed changes` step, and then proceed to the next step in this guide. In a single node cluster, always stop Elasticsearch before proceeding.
   </important>
3. Because you've created a new truststore and keystore, you need to update the `/etc/elasticsearch/elasticsearch.yml` settings file with the new truststore and keystore filenames.
   Open the Elasticsearch configuration file in a text editor and adjust the following values to reflect the newly created keystore and truststore filenames and paths:
   ```yaml
   xpack.security.transport.ssl:
      ...
      keystore.path: /etc/elasticsearch/certs/elastic-certificates.p12
      truststore.path: /etc/elasticsearch/certs/elastic-stack-ca.p12
   ```


### Update the Elasticsearch keystore

Elasticsearch uses a separate keystore to hold the passwords of the keystores and truststores holding the CA and node certificates created in the previous steps. Access to this keystore is through the use of a utility called `elasticsearch-keystore`.
1. From the Elasticsearch installation directory, list the contents of the existing keystore:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore list
   ```
   The results should be like the following:
   ```yaml
   keystore.seed
   xpack.security.http.ssl.keystore.secure_password
   xpack.security.transport.ssl.keystore.secure_password
   xpack.security.transport.ssl.truststore.secure_password
   ```
   Notice that there are entries for:
   - the `transport.ssl.truststore` that holds the CA certificate
- the `transport.ssl.keystore` that holds the CA-signed certificates
- the `http.ssl.keystore` for the HTTP layer.
   These entries were created at installation and need to be replaced with the passwords to the newly-created truststore and keystores.
2. Remove the existing keystore values for the default transport keystore and truststore:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore remove xpack.security.transport.ssl.keystore.secure_password

   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore remove xpack.security.transport.ssl.truststore.secure_password
   ```
3. Update the `elasticsearch-keystore` with the passwords for the new keystore and truststore created in the previous steps. This ensures that Elasticsearch can read the new stores:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password

   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
   ```


## Step 3: Generate new certificate(s) for the HTTP layer

Now that communication between Elasticsearch nodes (the transport layer) has been secured with SSL certificates, the same must be done for the communications that use the REST API, including Kibana, clients, and any other components on the HTTP layer.
1. Similar to the process for the transport layer, on the first node in your Elasticsearch cluster use the certificate utility to generate a CA certificate for HTTP communications:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-certutil http
   ```
   Respond to the command prompts as follows:
   - When asked if you want to generate a CSR, enter `n`.
- When asked if you want to use an existing CA, enter `y`.
   <note>
   If you're using your organization's CA certificate, specify that certificate and key in the following two steps.
   </note>
   - Provide the absolute path to your newly created CA certificate: `/etc/elasticsearch/certs/ca/ca.crt`.
- Provide the absolute path to your newly created CA key: `/etc/elasticsearch/certs/ca/ca.key`.
- Enter an expiration value for your certificate. You can enter the validity period in years, months, or days. For example, enter `1y` for one year.
- When asked if you want to generate one certificate per node, enter `y`.
   You'll be guided through the creation of certificates for each node. Each certificate will have its own private key, and will be issued for a specific hostname or IP address.
   1. Enter the hostname for your first Elasticsearch node, for example `mynode-es1`.
   ```shell
   mynode-es1
   ```
2. When prompted, confirm that the settings are correct.
3. Add the network IP address that clients can use to connect to the first Elasticsearch node. This is the same value that's described in Step 2 of [Tutorial 1: Installing a self-managed Elastic Stack](/elastic/docs-builder/docs/3028/deploy-manage/deploy/self-managed/tutorial-self-managed-install#install-stack-self-elasticsearch-config), for example `10.128.0.84`.
   ```shell
   10.128.0.84
   ```
4. When prompted, confirm that the settings are correct.
5. When prompted, choose to generate additional certificates, and then repeat the previous steps to add hostname and IP settings for each node in your Elasticsearch cluster.
6. Provide a password for the generated `http.p12` keystore file.
7. The generated files will be included in a zip archive. At the prompt, provide a path and filename for where the archive should be created.
   For this example we use: `/etc/elasticsearch/certs/elasticsearch-ssl-http.zip`:
   ```text
   What filename should be used for the output zip file? [/usr/share/elasticsearch/elasticsearch-ssl-http.zip] /etc/elasticsearch/certs/elasticsearch-ssl-http.zip
   ```
2. Earlier, when you generated the certificate for the transport layer, the default filename was `elastic-certificates.p12`. Now, when generating a certificate for the HTTP layer, the default filename is `http.p12`. This matches the name of the existing HTTP layer certificate file from when the initial Elasticsearch cluster was first installed.
   To avoid any possible name collisions, rename the existing `http.p12` file to distinguish it from the newly-created keystore:
   ```shell
   sudo mv /etc/elasticsearch/certs/http.p12 /etc/elasticsearch/certs/http-old.p12
   ```
3. Unzip the generated `elasticsearch-ssl-http.zip` archive:
   ```shell
   sudo unzip -d /usr/share/elasticsearch/ /etc/elasticsearch/certs/elasticsearch-ssl-http.zip
   ```
4. When the archive is unpacked, the certificate files are located in separate directories for each Elasticsearch node and for the Kibana node.
   You can run a recursive `ls` command to view the file structure:
   ```shell
   ls -lR /usr/share/elasticsearch/elasticsearch /usr/share/elasticsearch/kibana
   ```
   Example output:
   ```text
   elasticsearch:
   total 0
   drwxr-xr-x. 2 root root 56 Dec 12 19:13 mynode-es1
   ...
   kibana:
   total 12
   -rw-r--r--. 1 root root 1200 Dec 12 19:04 elasticsearch-ca.pem
   ...
   ```
5. Replace your existing keystore with the new keystore. The location of your certificate directory may be different than what is shown here, depending on the installation method you chose.
   Run the `mv` command, replacing `<es1-hostname>` with the hostname of your initial Elasticsearch node:
   ```shell
   sudo mv /usr/share/elasticsearch/elasticsearch/<es1-hostname>/http.p12 /etc/elasticsearch/certs/
   ```
6. Because this is a new keystore, the Elasticsearch configuration file needs to be updated with the path to its location. Open `/etc/elasticsearch/elasticsearch.yml` and update the HTTP SSL settings with the new path:
   ```yaml
   xpack.security.http.ssl:
     enabled: true
     #keystore.path: certs/http.p12
     keystore.path: /etc/elasticsearch/certs/http.p12
   ```
7. Since you also generated a new keystore password, the Elasticsearch keystore needs to be updated as well. From the Elasticsearch installation directory, first remove the existing HTTP keystore entry:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore remove xpack.security.http.ssl.keystore.secure_password
   ```
8. Add the updated HTTP keystore password, using the password you generated for this keystore:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.http.ssl.keystore.secure_password
   ```
9. Because we've added files to the Elasticsearch configuration directory during this tutorial, we need to ensure that the permissions and ownership are correct before restarting Elasticsearch.
   1. Change the files to be owned by `root:elasticsearch`:
   ```shell
   sudo chown -R root:elasticsearch /etc/elasticsearch/certs/
   ```
   1. Set the files in `/etc/elasticsearch/certs` to have read and write permissions by the owner (`root`) and read permission by the `elastic` user:
   ```shell
   sudo chmod 640 /etc/elasticsearch/certs/elastic-certificates.p12
   sudo chmod 640 /etc/elasticsearch/certs/elastic-stack-ca.p12
   sudo chmod 640 /etc/elasticsearch/certs/http_ca.crt
   sudo chmod 640 /etc/elasticsearch/certs/http.p12
   ```
   1. Change the `/etc/elasticsearch/certs` and `/etc/elasticsearch/certs/ca` directories to be executable by the owner:
   ```shell
   sudo chmod 750 /etc/elasticsearch/certs
   sudo chmod 750 /etc/elasticsearch/certs/ca
   ```
10. Restart the Elasticsearch service:
   ```shell
   sudo systemctl start elasticsearch.service
   ```
11. Run the status command to confirm that Elasticsearch is running:
   ```shell
   sudo systemctl status elasticsearch.service
   ```
   In the event of any problems, you can also monitor the Elasticsearch logs for any issues by tailing the Elasticsearch log file:
   ```shell
   sudo tail -f /var/log/elasticsearch/elasticsearch-demo.log
   ```
   A line in the log file like the following indicates that SSL has been properly configured:
   ```text
   [2023-07-12T13:11:29,154][INFO ][o.e.x.s.Security         ] [es-ssl-test] Security is enabled
   ```


## Step 4: Configure security on additional Elasticsearch nodes

Now that the security is configured for the first Elasticsearch node, some steps need to be repeated on each additional Elasticsearch node.
1. To avoid filename collisions, on each additional Elasticsearch node rename the existing `http.p12` file in the `/etc/elasticsearch/certs/` directory:
   ```shell
   mv http.p12 http-old.p12
   ```
2. Copy the CA and truststore files that you generated on the first Elasticsearch node so that they can be reused on all other nodes:
   - Copy the `/ca` directory (that contains `ca.crt` and `ca.key`) from `/etc/elasticsearch/certs/` on the first Elasticsearch node to the same path on all other Elasticsearch nodes.
- Copy the `elastic-stack-ca.p12` file from `/etc/elasticsearch/certs/` to the `/etc/elasticsearch/certs/` directory on all other Elasticsearch nodes.
- Copy the `http.p12` file from each node directory in `/usr/share/elasticsearch/elasticsearch` (that is, `elasticsearch/mynode-es1`, `elasticsearch/mynode-es2` and `elasticsearch/mynode-es3`) to the `/etc/elasticsearch/certs/` directory on each corresponding cluster node.
3. On each Elasticsearch node, repeat the steps to generate a new certificate for the transport layer:
   1. Stop the Elasticsearch service:
   ```shell
   sudo systemctl stop elasticsearch.service
   ```
2. From the `/etc/elasticsearch/certs` directory, create a new certificate for the Elasticsearch node:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --ca-cert /etc/elasticsearch/certs/ca/ca.crt --ca-key /etc/elasticsearch/certs/ca/ca.key
   ```
   When prompted, choose an output file name and specify a password for the certificate. For this example, we'll use `/etc/elasticsearch/certs/elastic-certificates.p12`.
   1. Update the `/etc/elasticsearch/elasticsearch.yml` settings file with the new truststore and keystore filename and path:
   ```yaml
   xpack.security.transport.ssl:
      ...
      keystore.path: /etc/elasticsearch/certs/elastic-certificates.p12
      truststore.path: /etc/elasticsearch/certs/elastic-stack-ca.p12
   ```
2. List the content of the Elasticsearch keystore:
   ```shell
   /usr/share/elasticsearch/bin/elasticsearch-keystore list
   ```
3. Remove the existing keystore values for the default transport keystore and truststore:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore remove xpack.security.transport.ssl.keystore.secure_password

   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore remove xpack.security.transport.ssl.truststore.secure_password
   ```
4. Update the `elasticsearch-keystore` with the passwords for the new keystore and truststore:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.transport.ssl.keystore.secure_password

   sudo /usr/share/elasticsearch/bin/elasticsearch-keystore add xpack.security.transport.ssl.truststore.secure_password
   ```
4. For the HTTP layer, the certificates have been generated already on the first Elasticsearch node. Each additional Elasticsearch node needs to be configured to use the new certificates.
   1. Update the `/etc/elasticsearch/elasticsearch.yml` settings file with the new truststore and keystore filenames:
   ```yaml
   xpack.security.http.ssl:
     enabled: true
     #keystore.path: certs/http.p12
     keystore.path: /etc/elasticsearch/certs/http.p12
   ```
2. Remove the existing HTTP keystore entry, add the updated HTTP keystore password, change certificate files to be owned by `root:elasticsearch`, set permissions, and change directory permissions (same commands as in Step 3).
5. Restart the Elasticsearch service:
   ```shell
   sudo systemctl start elasticsearch.service
   ```
6. Run the status command to confirm that Elasticsearch is running:
   ```shell
   sudo systemctl status elasticsearch.service
   ```


## Step 5: Generate server-side and client-side certificates for Kibana

Now that the transport and HTTP layers are configured with encryption using the new certificates, there are two more tasks that must be accomplished for end-to-end connectivity to Elasticsearch: Set up certificates for encryption between Kibana and Elasticsearch, and between the client browser and Kibana.
For additional details about any of these steps, refer to [Mutual TLS authentication between Kibana and Elasticsearch](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/security/kibana-es-mutual-tls) and [Encrypt traffic between your browser and Kibana](/elastic/docs-builder/docs/3028/deploy-manage/security/set-up-basic-security-plus-https#encrypt-kibana-browser).
1. In Step 3, when you generated a new certificate for the HTTP layer, the process created an archive `elasticsearch-ssl-http.zip`.
   From the `kibana` directory in the expanded archive, copy the `elasticsearch-ca.pem` file to the Kibana host machine.
2. On the Kibana host machine, copy `elasticsearch-ca.pem` to the Kibana configuration directory (depending on the installation method that you used, the location of the configuration directory may be different from what's shown):
   ```shell
   mv elasticsearch-ca.pem /etc/kibana
   ```
3. Stop the Kibana service:
   ```shell
   sudo systemctl stop kibana.service
   ```
4. Update the `/etc/kibana/kibana.yml` settings file to reflect the location of the `elasticsearch-ca.pem`:
   ```yaml
   elasticsearch.ssl.certificateAuthorities: [/etc/kibana/elasticsearch-ca.pem]
   ```
5. Log in to the first Elasticsearch node and use the certificate utility to generate a certificate bundle for the Kibana server. This certificate will be used to encrypt the traffic between Kibana and the client's browser. In the command, replace `<DNS name>` and `<IP address>` with the name and IP address of your Kibana server host:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --name kibana-server --ca-cert /etc/elasticsearch/certs/ca/ca.crt --ca-key /etc/elasticsearch/certs/ca/ca.key  --dns <DNS name> --ip <IP address> --pem
   ```
   When prompted, specify a unique name for the output file, such as `kibana-cert-bundle.zip`.
6. Copy the generated archive over to your Kibana host and unpack it:
   ```shell
   sudo unzip kibana-cert-bundle.zip
   ```
   The unpacked archive will create a directory, `kibana-server`, containing the new Kibana key and certificate (e.g. `kibana-server.crt`, `kibana-server.key`).
7. Copy the certificate and key into `/etc/kibana`:
   ```shell
   sudo cp kibana-server.crt /etc/kibana/
   sudo cp kibana-server.key /etc/kibana/
   ```
8. Update the permissions on the certificate files. From inside the `/etc/kibana` directory, run:
   ```shell
   sudo chmod 640 *.crt
   sudo chmod 640 *.key
   ```
9. Open `/etc/kibana/kibana.yml` and make the following changes:
   ```yaml
   server.ssl.certificate: /etc/kibana/kibana-server.crt
   server.ssl.key: /etc/kibana/kibana-server.key
   server.ssl.enabled: true
   ```
   Keep the file open for the next step.
10. To ensure that Kibana sessions are not invalidated, set up an encryption key by assigning any string of 32 characters or longer to the `xpack.security.encryptionKey` setting (this string will be configured in `kibana.yml` and does not need to be remembered). To generate a random string, you can use the following bash commands:
   ```shell
   cat /dev/urandom | tr -dc 'a-z0-9' | fold -w 32 | head -n 1
   ```
   Using your own string or the output of the above command sequence, add the encryption key setting to `/etc/kibana/kibana.yml`:
   ```shell
   xpack.security.encryptionKey: previously_create_string
   ```
   Save and close the file.
11. Restart the Kibana service:
   ```shell
   sudo systemctl start kibana.service
   ```
12. Confirm that Kibana is running:
   ```shell
   sudo systemctl status kibana.service
   ```
   If everything is configured correctly, connection to Elasticsearch will be established and Kibana will start normally.
13. You can also view the Kibana log file to gather more detail:
   ```shell
   tail -f /var/log/kibana/kibana.log
   ```
   In the log file you should find a `Kibana is now available` message.
14. You should now have an end-to-end ecnrypted deployment with Elasticsearch and Kibana that provides encryption between both the cluster nodes and Kibana, and HTTPS access to Kibana.
15. Log in using the `elastic` user and password that you configured in Step 1 of [Tutorial 1: Installing a self-managed Elastic Stack](/elastic/docs-builder/docs/3028/deploy-manage/deploy/self-managed/tutorial-self-managed-install#install-stack-self-elasticsearch-first).

Congratulations! You've successfully updated the SSL certificates between Elasticsearch and Kibana.

## Step 6: Install Fleet with SSL certificates configured

Now that Kibana is up and running, you can proceed to install Fleet Server, which will manage the Elastic Agent that we'll set up in a later step.
Refer to [Deploy on-premises and self-managed](https://www.elastic.co/elastic/docs-builder/docs/3028/reference/fleet/add-fleet-server-on-prem) and [Configure SSL/TLS for self-managed Fleet Servers](https://www.elastic.co/elastic/docs-builder/docs/3028/reference/fleet/secure-connections) for more detail.
1. Log in to the first Elasticsearch node and use the certificate utility to generate a certificate bundle for Fleet Server. In the command, replace `<DNS name>` and `<IP address>` with the name and IP address of your Fleet Server host:
   ```shell
   sudo /usr/share/elasticsearch/bin/elasticsearch-certutil cert --name fleet-server --ca-cert /etc/elasticsearch/certs/ca/ca.crt --ca-key /etc/elasticsearch/certs/ca/ca.key  --dns <DNS name> --ip <IP address> --pem
   ```
   When prompted, specify a unique name for the output file, such as `fleet-cert-bundle.zip`.
2. On your Fleet Server host, create a directory for the certificate files:
   ```shell
   sudo mkdir /etc/fleet
   ```
3. Copy the generated archive over to your Fleet Server host and unpack it into `/etc/fleet/`:
   - `/etc/fleet/fleet-server.crt`
- `/etc/fleet/fleet-server.key`
4. From the first Elasticsearch node, copy the `ca.crt` file into the `/etc/fleet/` directory on the Fleet Server host and rename it to `es-ca.crt`:
   - `/etc/fleet/es-ca.crt`
5. Update the permissions on the certificate files to ensure that they’re readable. From inside the `/etc/fleet` directory, run:
   ```shell
   sudo chmod 640 *.crt
   sudo chmod 640 *.key
   ```
6. Now that the certificate files are in place, on the Fleet Server host create a working directory for the installation package:
   ```shell
   mkdir fleet-install-files
   ```
7. Change into the new directory:
   ```shell
   cd fleet-install-files
   ```
8. In the terminal, run the `ifconfig` command and copy the value shown for the host IP address. You'll need this value later.
9. In your web browser, open Kibana **Management -> Fleet**, click **Add Fleet Server**, and select the **Advanced** tab.
10. On the **Create a policy for Fleet Server** step, keep the default Fleet Server policy name. Leave the option to collect system logs and metrics selected. Click **Create policy**. The policy takes a minute or so to create.

11 On the **Choose a deployment mode for security** step, select **Production**. This enables you to provide your own certificates.
1. On the **Add your Fleet Server host** step:
   1. Specify a name for your Fleet Server host.
2. Specify the host URL where Elastic Agents will reach Fleet Server (e.g. `https://10.128.0.203:8220`). Refer to [Default port assignments](/elastic/docs-builder/docs/3028/reference/fleet/add-fleet-server-on-prem#default-port-assignments-on-prem) for reference.
3. Click **Add host**.
2. On the **Generate a service token** step, generate the token and save the output. The token will also be propagated automatically to the command to install Fleet Server.
3. On the **Install Fleet Server to a centralized host** step, select the **Linux Tar** tab (or the tab for your host OS). TAR/ZIP packages are recommended over RPM/DEB system packages, since only the former support upgrading Fleet Server using Fleet.
4. Run the first three commands. The command will, respectively:
   1. Download the Fleet Server package from the Elastic Artifact Registry.
2. Unpack the package archive.
3. Change into the directory containing the install binaries.
5. Before running the `elastic-agent install` command:
   1. Update the paths to the correct file locations:
   - The Elasticsearch CA file (`es-ca.crt`)
- The Fleet Server certificate (`fleet-server.crt`)
- The Fleet Server key (`fleet-server.key`); get the CA fingerprint by running on an Elasticsearch host:
2. The `fleet-server-es-ca-trusted-fingerprint` also needs to be updated. On any of your Elasticsearch hosts, run the following command to get the correct fingerprint to use:
   ```shell
   grep -v ^- /etc/elasticsearch/certs/ca/ca.crt | base64 -d | sha256sum
   ```
   Save the fingerprint value. You’ll need it in a later step.
   Replace the `fleet-server-es-ca-trusted-fingerprint setting` with the returned value. Your updated command should be similar to the following:
   ```shell
    sudo ./elastic-agent install -url=https://10.128.0.208:8220 \
      --fleet-server-es=https://10.128.0.84:9200 \
      --fleet-server-service-token=<token> \
      --fleet-server-policy=fleet-server-policy \
      --fleet-server-es-ca-trusted-fingerprint=<fingerprint> \
      --certificate-authorities=/etc/fleet/es-ca.crt \
      --fleet-server-cert=/etc/fleet/fleet-server.crt \
      --fleet-server-cert-key=/etc/fleet/fleet-server.key \
      --fleet-server-port=8220
   ```
   Refer to [`elastic-agent install`](/elastic/docs-builder/docs/3028/reference/fleet/agent-command-reference#elastic-agent-install-command) for all options.
6. Run the `elastic-agent install` command to install Fleet Server.
   When prompted, confirm that Elastic Agent should run as a service. If everything goes well, the install will complete successfully:
   ```shell
   Elastic Agent has been successfully installed.
   ```
   <tip>
   Wondering why the command refers to {[agent]} rather than Fleet Server? Fleet Server is actually a subprocess that runs inside Elastic Agent with a special
   Fleet Server policy. Refer to [Fleet Server](/elastic/docs-builder/docs/3028/reference/fleet#fleet-server-intro) to learn more.
   </tip>
7. In the Kibana **Add a Fleet Server** flyout, wait for confirmation that Fleet Server has connected, then close the flyout.
   Fleet Server is now fully set up!
8. Before proceeding to install {[agent]}, there are a few steps needed to update the `kibana.yml` settings file with the Elasticsearch CA fingerprint:
   1. On your Kibana host, stop the Kibana service:
   ```shell
   sudo systemctl stop kibana.service
   ```
2. Open `/etc/kibana/kibana.yml` for editing.
3. Find the `xpack.fleet.outputs` setting.
4. Update `ca_trusted_fingerprint` to the value you captured earlier, when you ran the `grep` command on the Elasticsearch `ca.crt` file.
   The updated entry in `kibana.yml` should be like the following:
   ```shell
   xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: [`https://10.128.0.84:9200`], ca_trusted_fingerprint: 92b51cf91e7fa311f8c84849224d448ca44824eb}]
   ```
5. Save your changes.
6. Restart Kibana:
   ```shell
   sudo systemctl start kibana.service
   ```
   Kibana is now configured with the correct fingerprint for Elastic Agent to access Elasticsearch. You’re now ready to set up Elastic Agent!


## Step 7: Install Elastic Agent

Next, we'll install Elastic Agent on another host and use the System integration to monitor system logs and metrics. See [Configure SSL/TLS for self-managed Fleet Servers](https://www.elastic.co/docs/fleet/current/secure-connections.html) for more detail.
1. Log in to the host where you'd like to set up Elastic Agent.
2. Create a directory for the Elasticsearch certificate file:
   ```shell
   sudo mkdir /etc/agent
   ```
3. From the first Elasticsearch node, copy the `ca.crt` file into `/etc/agent/` on the agent host and rename it to `es-ca.crt`:
   - /etc/fleet/es-ca.crt
4. Create a working directory for the installation package:
   ```shell
   mkdir agent-install-files
   ```
5. Change into the new directory:
   ```shell
   cd agent-install-files
   ```
6. In Kibana, go to **Management -> Fleet**. On the **Agents** tab, you should see your new Fleet Server policy running with a healthy status.
7. Click **Add agent**, choose a policy name (e.g. `Demo Agent Policy`), and leave **Collect system logs and metrics** enabled (this adds the [System integration](https://docs.elastic.co/integrations/system)). Click **Create policy**.
8. For the **Enroll in Fleet?** step, leave **Enroll in Fleet** selected.
9. On the **Install Elastic Agent on your host** step, select the **Linux Tar** tab, or use the tab matching your operating system where you're setting up Fleet Server.
   As with Fleet Server, note that TAR/ZIP packages are recommended over RPM/DEB system packages, since only the former support upgrading Elastic Agent using Fleet.
   Run the first three commands in the terminal on your {[agent]} host. These commands will, respectively:
   1. Download the Elastic Agent package from the Elastic Artifact Registry.
2. Unpack the package archive.
3. Change into the directory containing the install binaries.
10. Before running the provided `elastic-agent install` command, you'll need to make a few changes:
   1. For the `--url` parameter, confirm that the port number is `8220` (this is the default port for on-premises Fleet Server).
2. Add a `--certificate-authorities` parameter with the full path of your CA certificate file. For example, `--certificate-authorities=/etc/agent/es-ca.crt`.
   The result should be like the following:
   ```shell
   sudo ./elastic-agent install \
   --url=https://10.128.0.203:8220 \
   --enrollment-token=<token> \
   --certificate-authorities=/etc/agent/es-ca.crt
   ```
11. Run the `elastic-agent install` command. Enter `Y` when prompted. Wait for the **Add agent** flyout to show the agent as connected and for **Confirm incoming data** to complete, then close the flyout.

Your new Elastic Agent is now installed and enrolled with Fleet Server.

## Step 8: View your system data

Now that all of the components have been installed, it's time to view your system data.
**View your system log data:**
1. Open the Kibana menu and go to **Analytics -> Dashboard**.
2. In the query field, search for `Logs System`.
3. Select the `[Logs System] Syslog dashboard` link. The Kibana Dashboard opens with visualizations of Syslog events, hostnames and processes, and more.

**View your system metrics data:**
1. Open the Kibana menu and return to **Analytics -> Dashboard**.
2. In the query field, search for `Metrics System`.
3. Select the `[Metrics System] Host overview` link. The Kibana Dashboard opens with visualizations of host metrics including CPU usage, memory usage, running processes, and others.

![Sample Kibana dashboard](https://www.elastic.co/elastic/docs-builder/docs/3028/deploy-manage/images/install-stack-metrics-dashboard.png)
Congratulations! You've successfully configured security for Elasticsearch, Kibana, Fleet, and Elastic Agent using your own trusted CA-signed certificates.

## Next steps

Now that you’ve successfully installed and secured an on-premises Elastic Stack, learn how to bring in data and start exploring:
- Do you have data ready to ingest? Learn how to [bring your data to Elastic](https://www.elastic.co/elastic/docs-builder/docs/3028/manage-data/ingest).
- Use [Elastic Observability](https://www.elastic.co/observability) to unify your logs, infrastructure metrics, uptime, and application performance data.
- Want to protect your endpoints from security threats? Try [Elastic Security](https://www.elastic.co/security). Adding endpoint protection is just another integration that you add to the agent policy!