262 lines
12 KiB
Plaintext
262 lines
12 KiB
Plaintext
[[ssl-tls]]
|
|
=== Setting Up SSL/TLS on a Cluster
|
|
|
|
Shield enables you to encrypt traffic to and from nodes in your Elasticsearch cluster. Connections
|
|
are secured using Transport Layer Security (TLS).
|
|
|
|
WARNING: Nodes that do not have encryption enabled send passwords in plain text.
|
|
|
|
To enable encryption, you need to perform the following steps on each node in the cluster:
|
|
|
|
. <<installing-node-certificates, Install an X.509 certificate>>.
|
|
|
|
. <<configure-ssl, Configure the node>> to:
|
|
.. Identify itself using its signed certificate.
|
|
.. Enable SSL on the transport and HTTP layers.
|
|
.. Disable multicast.
|
|
|
|
. Restart Elasticsearch.
|
|
|
|
[[installing-node-certificates]]
|
|
==== Installing Node Certificates
|
|
|
|
Node certificates should be signed by a certificate authority (CA) that is trusted by every node
|
|
in the cluster. You can use a third-party CA, your organization's existing CA, or
|
|
<<certificate-authority, set up a certificate authority>> specifically for signing node certificates.
|
|
|
|
When a client connects to a node using SSL/TLS, the node presents its certificate to the
|
|
client and proves that it owns the private key linked with the certificate. The client then
|
|
determines if the node's certificate is valid, trusted, and matches the hostname or IP address
|
|
it is trying to connect to. A node acts as a client when connecting to other nodes in the cluster,
|
|
so every node must trust all of the other nodes in the cluster.
|
|
|
|
NOTE: While it is technically possible to use self-signed certificates, we strongly recommend using certificates signed by a CA to establish trust between nodes. Self-signed certificates must be trusted individually, which means that each node must have every other node's certificate installed. If you add a node to the cluster, you have to install the new node's self-signed certificate on all of the existing nodes and restart them. When you use CA-signed certificates, the existing nodes just need to trust the CA used to sign the new node's certificate. (You should use the same CA to sign all of your node certificates.)
|
|
|
|
To install a signed certificate, you need to:
|
|
|
|
. <<private-key, Create a keystore and generate a certificate for the node>>.
|
|
. <<generate-csr, Create a certificate signing request (CSR)>>.
|
|
. <<send-csr, Send the certificate to your CA for signing>>.
|
|
. <<install-signed-cert, Add the signed certificate to the node's keystore>>.
|
|
|
|
[[private-key]]
|
|
===== Creating a Keystore and Generating a Certificate
|
|
To create a keystore and generate a node certificate:
|
|
|
|
. Create a node keystore and import your CA's certificate with https://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html[Java Keytool]. This configures the node to trust certificates signed by the CA. For Elasticsearch
|
|
to access the keystore, it must be located under the Elasticsearch configuration directory. For example, the following command creates a keystore for `node01` and and imports the CA certificate `cacert.pem`.
|
|
+
|
|
[source,shell]
|
|
--------------------------------------------------
|
|
cd CONFIG_DIR/shield
|
|
keytool -importcert -keystore node01.jks -file cacert.pem -alias my_ca
|
|
--------------------------------------------------
|
|
+
|
|
The Java keystore file (.jks) securely stores certificates for the node. The CA cert must be a
|
|
PEM encoded certificate.
|
|
+
|
|
When you create a keystore, you are prompted to set a password. This password protects the
|
|
integrity of the keystore. You need to provide it whenever you interact with the keystore.
|
|
+
|
|
IMPORTANT: When the CA certificate expires, you must update the node's keystore with the new CA
|
|
certificate.
|
|
+
|
|
You can also store the CA certificate in a separate truststore. For more
|
|
information, see <<create-truststore, Configuring a Truststore>>.
|
|
|
|
. Generate a private key and certificate for the node with Java Keytool. For example, the following
|
|
command creates a key and certificate for `node01`:
|
|
+
|
|
[source,shell]
|
|
--------------------------------------------------
|
|
keytool -genkey -alias node01 -keystore node01.jks -keyalg RSA -keysize 2048 -validity 712 -ext san=dns:node01.example.com,ip:192.168.1.1
|
|
--------------------------------------------------
|
|
+
|
|
This command creates an RSA private key with a key size of 2048 bits and a public certificate that
|
|
is valid for 712 days. The key and certificate are stored in the `node01.jks` keystore.
|
|
+
|
|
The `san` value specifies all alternative names for the node. The generated certificate is valid for the DNS names and IP addresses specified as alternative names. You can specify multiple DNS or IP address entries as a comma-separated list.
|
|
+
|
|
[IMPORTANT]
|
|
.Specifying the Node Identity
|
|
==========================
|
|
With SSL/TLS is enabled, when node A connects to node B, node A normally verifies the identity of
|
|
node B by checking the identity information specified in node B's certificate. This means that you
|
|
must include node identity information when you create a node's certificate.
|
|
|
|
The recommended way to specify the node identity when creating a certificate is to specify the
|
|
`-ext` option and list all of the node's names and IP addresses in the `san`
|
|
(Subject Alternative Name) attribute.
|
|
|
|
If you use a commercial CA, the DNS names and IP addresses used to identify a node must be publicly resolvable. Internal DNS names and private IP addresses are not accepted due to
|
|
https://cabforum.org/internal-names/[security concerns].
|
|
|
|
If you need to use private DNS names and IP addresses, using an internal CA is the most secure
|
|
option. It enables you to specify node identities and ensure node identities are verified when
|
|
nodes connect. If you must use a commercial CA and private DNS names or IP addresses, you cannot
|
|
include the node identity in the certificate, so the only option is to disable
|
|
<<ref-ssl-tls-settings, hostname verification>>.
|
|
==========================
|
|
+
|
|
When you run `keytool -genkey`, Keytool prompts you for the information needed to populate the
|
|
node's distinguished name that's stored the certificate. For example:
|
|
+
|
|
[source, shell]
|
|
--------------------------------------------------
|
|
What is your first and last name?
|
|
[Unknown]: Elasticsearch node01 <1>
|
|
What is the name of your organizational unit?
|
|
[Unknown]: test
|
|
What is the name of your organization?
|
|
[Unknown]: Elasticsearch
|
|
What is the name of your City or Locality?
|
|
[Unknown]: Amsterdam
|
|
What is the name of your State or Province?
|
|
[Unknown]: Amsterdam
|
|
What is the two-letter country code for this unit?
|
|
[Unknown]: NL
|
|
Is CN=Elasticsearch node01, OU=test, O=elasticsearch, L=Amsterdam, ST=Amsterdam, C=NL correct?
|
|
[no]: yes
|
|
|
|
Enter key password for <node01> <2>
|
|
(RETURN if same as keystore password):
|
|
--------------------------------------------------
|
|
<1> Provides information about the node that this certificate is intended for. In the past, this field specified the node's identity using a DNS name, but that behavior has been deprecated.
|
|
<2> If you don't specify a password for the certificate, the keystore password is used.
|
|
|
|
[float]
|
|
[[generate-csr]]
|
|
===== Creating a Certificate Signing Request
|
|
|
|
A node's certificate needs to be signed by a trusted CA for the certificate to be trusted. To get a certificate signed, you need to create a certificate signing request (CSR) and send it to your CA.
|
|
|
|
To create a CSR with Java Keytool, use the `keytool t-certreq` command. You specify the same alias, keystore, key algorithm, and DNS names and IP addresses that you used when you created the node certificate. Specify where you want to store the CSR with the `-file` option.
|
|
|
|
[source, shell]
|
|
--------------------------------------------------
|
|
keytool -certreq -alias node01 -keystore node01.jks -file node01.csr -keyalg rsa -ext san=dns:node01.example.com,ip:192.168.1.1
|
|
--------------------------------------------------
|
|
|
|
[float]
|
|
[[send-csr]]
|
|
===== Send the Signing Request
|
|
|
|
To get a signed certificate, send the generated CSR file to your CA. The CA will sign it and send
|
|
you the signed version of the certificate.
|
|
|
|
NOTE: If you are running your own CA, see <<sign-csr, Signing CSRs>> for signing instructions.
|
|
|
|
[float]
|
|
[[install-signed-cert]]
|
|
===== Install the Signed Certificate
|
|
|
|
To install the signed certificate, use `keytool -importcert` to add it to the node's keystore. You
|
|
specify the same alias and keystore that you used when you created the node certificate.
|
|
|
|
[source, shell]
|
|
--------------------------------------------------
|
|
cd CONFIG_DIR/shield
|
|
keytool -importcert -keystore node01.jks -file node01-signed.crt -alias node01
|
|
--------------------------------------------------
|
|
|
|
[NOTE]
|
|
==========================
|
|
If you attempt to import a PEM-encoded certificate that contains extra text headers, you might get
|
|
the error: `java.security.cert.CertificateParsingException: invalid DER-encoded certificate data`.
|
|
Use the following `openssl` command to remove the extra headers and then use `keytool` to import
|
|
the certificate.
|
|
|
|
[source, shell]
|
|
--------------------------------------------------
|
|
openssl x509 -in node01-signed.crt -out node01-signed-noheaders.crt
|
|
--------------------------------------------------
|
|
==========================
|
|
|
|
[[enable-ssl]]
|
|
==== Enabling SSL in the Node Configuration
|
|
|
|
Once you have added the signed certificate to the node's keystore, you need to modify the node
|
|
configuration to enable SSL.
|
|
|
|
NOTE: All SSL/TLS related node settings that are considered to be highly sensitive and therefore
|
|
are not exposed via the {ref}/cluster-nodes-info.html#cluster-nodes-info[nodes info API].
|
|
|
|
[[configure-ssl]]
|
|
To enable SSL, make the following changes in `elasticsearch.yml`:
|
|
|
|
. Specify the location of the node's keystore and the password(s) needed to access the node's
|
|
certificate. For example:
|
|
+
|
|
[source, yaml]
|
|
--------------------------------------------------
|
|
shield.ssl.keystore.path: /home/es/config/shield/node01.jks <1>
|
|
shield.ssl.keystore.password: myPass <2>
|
|
shield.ssl.keystore.key_password: myKeyPass <3>
|
|
--------------------------------------------------
|
|
<1> The full path to the node keystore file. This must be a location within the Elasticsearch
|
|
configuration directory.
|
|
<2> The password used to access the keystore.
|
|
<3> The password used to access the certificate. This is only required if you specified a separate
|
|
certificate password when generating the certificate.
|
|
|
|
. Enable SSL on the transport networking layer to ensure that communication between nodes is
|
|
encrypted:
|
|
+
|
|
[source, yaml]
|
|
--------------------------------------------------
|
|
shield.transport.ssl: true
|
|
--------------------------------------------------
|
|
+
|
|
NOTE: Transport clients can only connect to the cluster with a valid username and password even if
|
|
this setting is disabled.
|
|
|
|
. Enable SSL on the HTTP layer to ensure that communication between HTTP clients and the cluster is encrypted:
|
|
+
|
|
[source, yaml]
|
|
--------------------------------------------------
|
|
shield.http.ssl: true
|
|
--------------------------------------------------
|
|
+
|
|
NOTE: HTTP clients can only connect to the cluster with a valid username and password even if this
|
|
setting is disabled.
|
|
|
|
. Disable {ref}/modules-discovery.html[multicast discovery]:
|
|
+
|
|
[source, yaml]
|
|
--------------------------------------------------
|
|
discovery.zen.ping.multicast.enabled: false
|
|
discovery.zen.ping.unicast.hosts: ["node01:9300", "node02:9301"]
|
|
--------------------------------------------------
|
|
|
|
. Restart Elasticsearch so these configuration changes take effect.
|
|
|
|
[[create-truststore]]
|
|
==== Configuring a Separate Truststore
|
|
You can store trusted CA certificates in a node's keystore, or create a separate truststore for CA
|
|
certificates.
|
|
|
|
To use a separate truststore:
|
|
|
|
. Create a node truststore and import the CA certificate(s) you want to trust with Java Keytool. For example, the following command imports the CA certificate `cacert.pem` into `truststore.jks`. If the specified truststore doesn't exist, it is created.
|
|
+
|
|
[source,shell]
|
|
--------------------------------------------------
|
|
cd CONFIG_DIR/shield
|
|
keytool -importcert -keystore truststore.jks -file cacert.pem
|
|
--------------------------------------------------
|
|
+
|
|
When you create a truststore, you are prompted to set a password. This password protects the
|
|
integrity of the truststore. You need to provide it whenever you interact with the truststore.
|
|
|
|
. In `elasticsearch.yml`, specify the location of the node's truststore and the password needed to
|
|
access it. For example:
|
|
+
|
|
[source, yaml]
|
|
--------------------------------------------------
|
|
shield.ssl.truststore.path: /home/es/config/shield/truststore.jks <1>
|
|
shield.ssl.truststore.password: myPass <2>
|
|
--------------------------------------------------
|
|
<1> The full path to the truststore file. This must be a location within the
|
|
Elasticsearch configuration directory.
|
|
<2> The password needed to access the truststore.
|