Creating Local SSL Certificate and Keystore Files
Use these steps as a general guide to create and distribute SSL certificates using OpenSSL and Java keytool.
Use SSL certificates for client-to-node encryption and node-to-node encryption. DataStax supports SSL using well-known Certificate Authority (CA) signed certificates for each node or you can create your own root CA. DataStax recommends using certificates signed by a well-known CA to reduce SSL certificate management tasks. However, you can use self-signed certificates with DataStax Enterprise (DSE), which supports SSL certificates in local and external keystores.
|
Use this method of generating a root key/certificate pair only for development and test environments. Secure these files, because anyone with access to the root CA files can sign certificates and authorize hosts as the root certificate authority. |
Creating your own CA in a production environments typically involves using an intermediary certificate chain, where the root CA signs one or more intermediate certificates with its private key. These intermediary certificates chain together to link back to the root CA, which owns one or more trusted roots.
OpsCenter Lifecycle Manager can configure DSE clusters to use client-to-node and node-to-node encryption and automate the process of preparing server certificates. See Configuring SSL using LCM.
|
DataStax recommends using a computer outside of the DSE environment to generate and manage SSL certificates. Complete the steps on a dedicated CA server that is fully secured and permanently isolated from the network. |
Using a well-known CA
If using a third-party signed certificate, or when adding a node using an existing root CA, skip to the steps for Creating a key and certificate for each node.
Creating a root CA certificate
In development and testing environments, you can set up your own root Certificate Authority (CA) to sign DataStax Enterprise (DSE) node certificates for SSL. In this model, generate your own root certificate that is to be used to sign the certificate on every node, generate certificates for individual nodes, sign them, and generate corresponding keystores for every node.
If you want to use a remote keystore provider instead, then see Using a remote keystore provider.
Procedure
-
Create a directory for the root CA signing certificate/key, and then change to that directory:
mkdir -p <rootca_path>cd <rootca_path>- rootca_path
-
Directory where the root certificate is created and stored. DataStax recommends securing this directory, ideally on a computer isolated from the network.
-
Create a
<rootca.conf>configuration file:touch rootca.conf- rootca.conf
-
Root CA configuration file.
-
Edit the
<rootca.conf>file and add the following minimal settings:# <rootca.conf> [ req ] distinguished_name = <CA_DN> prompt = no output_password = <rootca_password> default_bits = 2048 [ <CA_DN> ] C = <CC> O = <org_name> OU = <cluster_name> CN = <CA_CN>- CA_DN
-
Title for the section containing the Distinguished Name (DN) properties for the CA.
- rootca_password
-
Password for the generated file used to sign certificates.
- CC
-
Two letter country code, such as
USfor United States orJPfor Japan. - org_name
-
Name of your organization.
- cluster_name
-
Name of your DataStax Enterprise (DSE) cluster.
- CA_CN
-
Common Name (CN) for the root CA.
-
Use
opensslto create a root key/certificate pair:openssl req -config rootca.conf \ -new -x509 -nodes \ -keyout rootca.key \ -out rootca.crt \ -days 3650The
-x509option outputs a signed certificate used as the root CA. The number of days specified by the-daysoption affects the duration for which all signed certificates are valid. Indicating a higher number of days means that the certificates are valid for a longer period. In the previous example, the root CA is valid for3650days, which is approximately 10 years.Two files are created:
rootca.keyandrootca.crt. -
Verify the root certificate:
openssl x509 -in <rootca.crt> -text -nooutCertificate: Data: Version: 1 (0x0) Serial Number: <serial_number> (0xcd4bc943beeb35ce) Signature Algorithm: sha256WithRSAEncryption Issuer: C=US, O=datastax, OU=pw-j-dse, CN=rootCa Validity Not Before: Jul 23 20:15:06 2019 GMT Not After : Jul 23 20:15:06 2020 GMT Subject: C=US, O=datastax, OU=pw-j-dse, CN=rootCa Subject Public Key Info: Public Key Algorithm: rsaEncryption Public-Key: (2048 bit) Modulus: 00:d8:71:e0:51:07:ad:f1:f7:0b:4d:2c:10:4c:24: 19:9f:1f:d4:2a:a1:a6:89:3d:e1:12:81:3b:4d:bd: 2d:da:fb:9e:d5:c5:ba:ed:82:80:28:35:e5:00:86: ... Exponent: 65537 (0x10001) Signature Algorithm: sha256WithRSAEncryption 43:8d:98:8c:d7:26:52:41:ad:de:c9:80:8d:4f:d6:6e:21:69: 81:7d:eb:af:93:6e:15:ad:9d:fe:ee:1a:60:d6:aa:92:86:a2: fd:e1:8f:95:b9:ee:db:59:63:fd:cd:05:72:63:d6:6b:14:cf: ...
Creating a truststore for all nodes
Create a truststore that is used to ensure that all nodes recognize the certificate authority (CA). Even when using a well-known certificate authority, DataStax recommends creating a truststore with the signing CA certificate or certificate chain (following the instructions from your CA). Most well-known CA certificates are already available through the DataStax Enterprise (DSE) Java implementation.
Procedure
-
Create a single truststore, and add the root certificate to the truststore. For the
<keystore_type>, enterJKS:If prompted whether to import the certificate, enter
yes.keytool -keystore <dse-truststore.jks> \ -storetype <keystore_type> \ -importcert -file '<rootca.crt>' \ -keypass <keystore_password> \ -storepass <truststore_password> \ -alias <rootca_name> \ -noprompt- dse-truststore.jks
-
Truststore that contains the root certificate.
Use the same truststore that contains the root certificate on all nodes.
- keystore_type
-
Valid types are
JKS,JCEKS,PKCS11, orPKCS12. For file-based keystores, usePKCS12.DataStax supports
PKCS11as akeystore_typeon nodes withcassandraoradvancedworkloads. Theadvancedworkload support was added for DSE 6.8.2 and later. IfPKCS11is needed, inserver_encryption_optionsorclient_encryption_options, specify thekeystore_typeasPKCS11and thekeystoreasNONE.PKCS11is not supported as atruststore_type.Default:
JKS - rootca.crt
-
Certificate used to sign (authorize) DSE node SSL certificates.
- keystore_password
-
Password used to protect the private key of the key pair.
Default: none
- truststore_password
-
Password required to access the keystore.
Default: none
- rootca_name
-
Name (alias) used to identify the root certificate when importing into the node’s keystore. For example, in a
rootca.conffile, theCN = CA_CNentry shown in Creating a root CA certificate.A message displays indicating that the certificate was added. The truststore now contains a single entry.
Certificate was added to keystore
-
Verify the truststore to ensure that it contains the root certficate:
keytool -list \ -keystore <dse-truststore.jks> \ -storepass <truststore_password>The command output indicates the keystore type, provider, number of entries, creation date, and certification details.
Keystore type: jks Keystore provider: SUN Your keystore contains 1 entry <rootca_name>, Aug 8, 2019, trustedCertEntry, Certificate fingerprint (SHA1): <SHA1-has>h
Creating a key and certificate for each node
For each node in the cluster, create a keystore, key pair, and certificate signing request using the Fully Qualified Domain Name (FQDN) of the node.
|
These steps are required even when using a third-party CA, or when adding a node to an existing DSE environment with SSL enabled. |
Prerequisites
On each node, run the following command to obtain the FQDN for each node:
nslookup $(hostname --fqdn) && hostname --fqdn && hostname -i
Server: 10.200.1.10
Address: 10.200.1.10#53
Name: ip-10-200-182-183.example.com
Address: 10.200.182.183
ip-10-200-182-183.example.com
10.200.182.183
In this example, ip-10-200-182-183.example.com is the Common Name (CN), which is used to generate the SSL certificate.
The CN must match the DNS-resolvable host name.
Mismatches between the CN and node hostname cause an exception and the connection is refused.
SSL certificate doesn’t match exception
With dsetool and other tools that issue commands to the cluster, error messages indicate that the environment is not configured correctly. For example:
dsetool -h 10.236.136.55 reload_core keyspace_name.table_name deleteAll=true reindex=true distributed=false
...
javax.net.ssl.SSLException: Certificate for <node35.foo.com> doesn't match any of the subject alternative names: clustercert.foo.com
...
This message shows that 10.236.136.55 is being resolved to node35.foo.com, then node node35.foo.com is being asked for it’s certificate which is a generic certificate issued with a CN of clustercert.foo.com.
For security reasons, SSL verifies that node35.foo.com and clustercert.foo.com match.
If they don’t match, a certificate mismatch error occurs.
Do not use a generic certificate across multiple nodes because each node has a different name that won’t match.
Do not copy a certificate that is issued to one node over to another node.
Nodes must be configured with correct names that match the certificate CN.
You can use a wildcard in named certificates, like * in CN=*.foo.com, or any other matching mechanism allowed by SSL standards.
All others configurations where names mismatch will result in an error.
When testing connections with other tools, enable them with secure settings.
Avoid testing with insecure settings that do not require name matching.
For example, curl --insecure.
These insecure settings do not identify certificate mismatches and are not supported in DSE tools.
Procedure
-
Create a directory to store the keystores and change to the directory:
mkdir -p <dse/keystores>cd <dse/keystores> -
For each node, generate a keystore with key pair. Each node is to have its own keystore, such as
node1-keystore.jks:Ensure the passwords entered for <truststore_password> and <keystore_password> are the same. If the passwords are different, DSE fails to start and returns an error message: “Cannot recover key”.
keytool -genkeypair -keyalg RSA \ -alias <node_name> \ -keystore <node-keystore.jks> \ -storepass <truststore_password> \ -keypass <keystore_password> \ -validity 730 \ -keysize 2048 \ -dname "CN=<node_name>, OU=<cluster_name>, O=<org_name>, C=<CC>" \ -ext "san=ip:<node_ip_address>"The
-validityoption specifies the timeframe for which the generated key pair for the node is valid. In the previous example the key pair is valid for730days, which is approximately 2 years.- node_name
-
Fully Qualified Domain Name (FQDN) of the node, such as
ip-10-200-182-183.example.com. When using the FQDN as thenode_name, you can add the IP address as a subject alternative name (SAN) so that the certificate protects the IP address in addition to the domain name. - node-keystore.jks
-
Keystore for the individual node.
Default: none
- truststore_password
-
Password required to access the keystore.
Default: none
- keystore_password
-
Password used to protect the private key of the key pair.
Default: none
- cluster_name
-
Name of your DataStax Enterprise (DSE) cluster.
- org_name
-
Name of your organization.
- CC
-
Two letter country code, such as
USfor United States orJPfor Japan. - node_ip_address
-
When using the domain name as the node_name for the CA, add
san=ip:ip_addressto the-extoption. Using the IP address as a subject alternative name (SAN) ensures that the certificate protects the IP address in addition to the domain name.For example:
-ext "san=ip:10.200.100.52"
-
Verify each SSL keystore and key pair:
keytool -list \ -keystore <node-keystore.jks> \ -storepass <truststore_password>The command output indicates the keystore type, provider, and number of entries. The alias used the example is
dc1_node1.Keystore type: JKS Keystore provider: SUN Your keystore contains 1 entry dc1_node1, Jul 23, 2019, PrivateKeyEntry, Certificate fingerprint (SHA1): <SHA1_hash> -
Generate a signing request from each keystore:
keytool -keystore <node-keystore.jks> \ -alias <node_name> \ -certreq -file <signing_request.csr> \ -keypass <node-key_password> \ -storepass <keystore_password>- node-key_password
-
Password used to protect the individual private key.
Default: none
- keystore_password
-
Password used to protect the private key of the key pair.
Default: none
The certificate signing request file (
<signing_request.csr>) is created.
-
Repeat the previous steps on each node to generate a signing request, ensuring that the
dnameinformation matches the node information (such as<node_name>and<cluster_name>).
Signing the certificate signing request
For each node, sign the certificate signing request. If you created your own root CA, follow the instructions below. Alternatively, send the certificate signing request to a well-known CA for signing.
Procedure
-
Sign each node certificate:
openssl x509 -req -CA 'path/to/rootca.crt' \ -CAkey 'path/to/rootca.key' \ -in signing_request.csr \ -out signing_request.crt_signed \ -days 3650 \ -CAcreateserial \ -passin pass:rootca_password \ -extfile san_config_file.conf- signing_request.csr
-
Certificate signing request (CSR) that is passed to the Certificate Authority (CA) to sign the certificate. The CSR typically includes the public key plus associated metadata such as the Common Name (CN), Organization (O), Organization Unit (OU), and Country (C).
signing_request.crt_signed The signed certificate file to create, using the certificate signing request (CSR) (
signing_request.csr) as the input file. - san_config_file.conf
-
If using the domain name as the <node_name> and the node IP address as a Subject Alternative Name (SAN), create a temporary configuration file and pass it in using the
-extfileoption. In the configuration file, use thesubjectAltNameparameter to specify the DNS and IP. For example:subjectAltName=DNS:<node_name>,IP:<node_ip_address>You can specify multiple SANs in the same configuration file:
subjectAltName=DNS:domain1,IP:10.200.100.52 subjectAltName=DNS:domain1,IP:10.200.101.63 subjectAltName=DNS:domain1,IP:10.200.111.74 subjectAltName=DNS:domain1,IP:10.200.121.85Use the
<rootca_password>entered when Creating the root CA signing certificate.A signed certificate file
signing_request.crt_signedis created.
-
Verify that the root certificate file was properly signed:
openssl verify -CAfile '<path/to/rootca.crt>' <signing_request.crt_signed><signing_request>.crt_signed: OK -
Delete the temporary configuration
<file san_config_file>.confto protect theSANfor a node.rm -f <san_config_file.conf>
Importing the Signed Certificate into the Node Keystore
For each node in the cluster, create a keystore and import the signed certificate. The variables that you enter in the following commands must match the information that you entered in Creating a key and certificate for each node.
Procedure
-
Import the root certificate (
rootca.crt) into each node’s keystore:You created the root certificate when Creating a truststore for all nodes.
keytool -keystore <node-keystore.jks> \ -alias <rootca_name> \ -importcert -file '<path/to/rootca.crt>' \ -keypass <keystore_password> \ -storepass <truststore_password> \ -noprompt- rootca_name
-
Name (alias) used to identify the root certificate when importing into the node’s keystore. For example, in a
rootca.conffile, theCN = CA_CNentry shown in Creating a root CA certificate.If the signed certificate for the node is imported before the root certificate, an error occurs:
keytool error: java.lang.Exception: Failed to establish chain from reply
-
Import the node’s signed certificate (
signing_request.crt_signed) into the corresponding keystore on the node:keytool -keystore <node-keystore.jks> \ -alias <node_name> \ -importcert -file <signing_request.crt_signed> \ -keypass <node-key_password> \ -storepass <keystore_password> \ -nopromptThe alias
<node_name>must match thealias nameused to generate the signing request. See Creating a key and certificate for each node.Confirmation of the installation appears:
Certificate was added to keystore -
Verify your keystore again, which should now contain two entries. One entry is for the
node keystore, and the other for the imported root certificate:keytool -list \ -keystore <node-keystore.jks> \ -storepass <truststore_password>Each keystore entry is identified by the name you entered for the
-alias:Keystore type: jks Keystore provider: SUN Your keystore contains 2 entries <node_name>, Aug 8, 2019, trustedCertEntry, Certificate fingerprint (SHA1): <SHA1-hash> <rootca_name>, Aug 8, 2019, trustedCertEntry, Certificate fingerprint (SHA1): <SHA1-hash> -
Repeat the previous steps on each node to import the root certificate, and then import the signed certificate into the keystore.