Configure a different certificate for Cassandra, Elasticsearch, Filebeat and Kibana

1. Certificate Requirements

The Cassandra certificate must include the following:

Key Usage

  • Client Authentication

  • Server Authentication

Subject Alternative Names (SAN)

  • All server IP addresses

  • The Cassandra DNS name

Example:

10.204.60.1
10.204.60.2
10.204.60.3
10.204.60.4
10.204.60.5
10.204.60.6
cassandra.dev.local



2. Generating the Certificate

There are two supported methods:

Option 1 — Generate a CSR

Create a configuration file for the CSR.

Example cassandra.cnf:

[ req ]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
req_extensions = req_ext
prompt = no

[ req_distinguished_name ]
C   = RO
ST  = RO
L   = Bucharest
O   = VeridiumID
OU  = Veridium
CN  = cassandra.dev.local

[ v3_req ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth

[req_ext]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = 10.204.60.1
DNS.2 = 10.204.60.2
DNS.3 = 10.204.60.3
DNS.4 = 10.204.60.4
DNS.5 = 10.204.60.5
DNS.6 = 10.204.60.6
DNS.7 = cassandra.dev.local

Generate the private key and CSR:

openssl genrsa -out cassandra.key 2048
openssl req -new -key cassandra.key -out cassandra.csr -config cassandra.cnf

Send cassandra.csr to your Certificate Authority for signing.


Option 2 — Use an Existing PFX Certificate

If a .pfx file is provided containing:

  • private key

  • certificate

  • certificate chain

Convert it using:

/etc/veridiumid/scripts/convert_haproxy_cert.sh file.pfx


3. Verify the Certificate

Ensure the certificate contains the correct usages:

openssl x509 -in server.pem -text -noout | grep "Extended Key Usage" -A4

Expected output:

X509v3 Extended Key Usage:
TLS Web Server Authentication
TLS Web Client Authentication

4. Import the Intermediate Certificate

The intermediate certificate must be added to both:

  • Veridium Truststore

  • ILP Truststore

4.1 Import in WebSecAdmin

Add the certificate to the Truststore via the WebSecAdmin interface.


4.2 Import on ILP Nodes

Run on each node:

passkeystore=`grep CASSANDRA_KEYSTORE_PASS_ENV /etc/default/veridiumid/uba_variables | awk -F'"' '{print $2}'`
keytool -importcert -keystore /opt/veridiumid/uba/TrustStore.jks -storepass $passkeystore -file intermediate.pem
cat intermediate.pem >> /opt/veridiumid/uba/TrustStore.pem

Update ILP truststore variable:

cat /etc/default/veridiumid/uba_variables | grep TRUSTSTORE_ENV | awk -F'\"' '{print $2}' | base64 -d > cert_ilp.pem
cat intermediate.pem >> cert_ilp.pem
sed -i "/TRUSTSTORE_ENV=(.*)/d" /etc/default/veridiumid/uba_variables
echo "TRUSTSTORE_ENV=\""$(base64 -w0 cert_ilp.pem)\" >> /etc/default/veridiumid/uba_variables


5. Configure Cassandra

Perform the following on each Cassandra node.

5.1 Prepare the Certificate Bundle

Combine the key, signed certificate, and intermediate chain:

cat cassandra.key > server.pem
cat cassandraSigned.pem >> server.pem
cat intermediate.pem >> server.pem


5.2 Define Paths and Password

CURRENT_TIMESTAMP=`date +"%Y%m%d%H%M%S%3N"`

CAS_KEYSTORE=/opt/veridiumid/cassandra/conf/KeyStore.jks
CAS_TRUSTSTORE=/opt/veridiumid/cassandra/conf/TrustStore.jks

CAS_PASS=$(grep "truststore_password" /opt/veridiumid/cassandra/conf/cassandra.yaml | awk -F' ' '{print $2}' | sort -u)

5.3 Backup Existing Stores

cp $CAS_KEYSTORE $CAS_KEYSTORE.$CURRENT_TIMESTAMP
cp $CAS_TRUSTSTORE $CAS_TRUSTSTORE.$CURRENT_TIMESTAMP

5.4 Create Keystore

openssl pkcs12 -export -in server.pem -inkey server.pem -name 'tomcat' -out KeyStore.jks -passout pass:${CAS_PASS}

5.5 Update Truststore

cp $CAS_TRUSTSTORE TrustStore.jks

echo "yes" | keytool -import -alias cassandra -file intermediate.pem -storetype JKS -keystore TrustStore.jks -storepass ${CAS_PASS}

5.6 Convert to PKCS12

keytool -importkeystore -srckeystore KeyStore.jks -destkeystore KeyStore.jks -srcstoretype jks -deststoretype pkcs12 -srcstorepass ${CAS_PASS} -keypass ${CAS_PASS} -deststorepass ${CAS_PASS} -noprompt
keytool -importkeystore -srckeystore TrustStore.jks -destkeystore TrustStore.jks -srcstoretype jks -deststoretype pkcs12 -srcstorepass ${CAS_PASS} -keypass ${CAS_PASS} -deststorepass ${CAS_PASS} -noprompt

5.7 Rolling Restart (Avoid Downtime)

Step 1 — Update Truststore

cp TrustStore.jks ${CAS_TRUSTSTORE}
systemctl restart ver_cassandra

Perform a rolling restart across all nodes.


Step 2 — Update Keystore

cp KeyStore.jks $CAS_KEYSTORE
systemctl restart ver_cassandra

6. Configure Elasticsearch

Reuse Cassandra keystore and truststore.

CURRENT_TIMESTAMP=`date +"%Y%m%d%H%M%S%3N"`

CAS_KEYSTORE=/opt/veridiumid/cassandra/conf/KeyStore.jks
CAS_TRUSTSTORE=/opt/veridiumid/cassandra/conf/TrustStore.jks

CAS_PASS=$(grep "truststore_password" /opt/veridiumid/cassandra/conf/cassandra.yaml | awk -F' ' '{print $2}' | sort -u)

ELK_KEYSTORE=/opt/veridiumid/elasticsearch/config/certs/KeyStore.p12
ELK_TRUSTSTORE=/opt/veridiumid/elasticsearch/config/certs/TrustStore.p12

ELK_PASS=$(/opt/veridiumid/elasticsearch/bin/elasticsearch-keystore show xpack.security.transport.ssl.keystore.secure_password)

Backup Existing Files

cp $CAS_KEYSTORE $CAS_KEYSTORE.$CURRENT_TIMESTAMP
cp $CAS_TRUSTSTORE $CAS_TRUSTSTORE.$CURRENT_TIMESTAMP
cp $ELK_KEYSTORE $ELK_KEYSTORE.$CURRENT_TIMESTAMP
cp $ELK_TRUSTSTORE $ELK_TRUSTSTORE.$CURRENT_TIMESTAMP

Replace Elasticsearch Stores

cp $CAS_KEYSTORE $ELK_KEYSTORE
cp $CAS_TRUSTSTORE $ELK_TRUSTSTORE

Update passwords:

keytool -storepasswd -new $ELK_PASS -keystore $ELK_KEYSTORE -storepass $CAS_PASS
keytool -storepasswd -new $ELK_PASS -keystore $ELK_TRUSTSTORE -storepass $CAS_PASS

Disable Shard Allocation

eops -x=PUT -p=/_cluster/settings -d="{\"transient\":{\"cluster.routing.allocation.enable\":\"none\"}}"

Restart Elasticsearch:

systemctl restart ver_elasticsearch

Re-enable allocation:

eops -x=PUT -p=/_cluster/settings -d="{\"transient\":{\"cluster.routing.allocation.enable\":\"all\"}}"

7. Configure Kafka (if needed)

Reuse Cassandra keystore and truststore.

Bash
CURRENT_TIMESTAMP=`date +"%Y%m%d%H%M%S%3N"`

CAS_PASS=$(grep "truststore_password" /opt/veridiumid/cassandra/conf/cassandra.yaml | awk -F' ' '{print $2}' | sort -u)
CAS_KEYSTORE=/opt/veridiumid/cassandra/conf/KeyStore.jks
CAS_TRUSTSTORE=/opt/veridiumid/cassandra/conf/TrustStore.jks

KAFKA_KEYSTORE=/opt/veridiumid/uba/kafka/certs/KeyStore.p12
KAFKA_TRUSTSTORE=/opt/veridiumid/uba/kafka/certs/TrustStore.p12


Backup Existing Files

cp $KAFKA_KEYSTORE $KAFKA_KEYSTORE.$CURRENT_TIMESTAMP
cp $KAFKA_TRUSTSTORE $KAFKA_TRUSTSTORE.$CURRENT_TIMESTAMP

Replace Kafka Stores

cp $CAS_KEYSTORE $KAFKA_KEYSTORE
cp $CAS_TRUSTSTORE $KAFKA_TRUSTSTORE

Check the password is the same:

Bash
echo $CAS_PASS
grep ssl.keystore.password /opt/veridiumid/uba/kafka/config/server.properties
##keytool -storepasswd -new $ELK_PASS -keystore $ELK_KEYSTORE -storepass $CAS_PASS
##keytool -storepasswd -new $ELK_PASS -keystore $ELK_TRUSTSTORE -storepass $CAS_PASS

Restart kafka

systemctl restart uba-kafka



8. Configure Filebeat and Kibana

Filebeat and Kibana must trust the same CA.

Extract the certificates from the Cassandra truststore:

CAS_TRUSTSTORE=/opt/veridiumid/cassandra/conf/TrustStore.jks

CAS_PASS=$(grep "truststore_password" /opt/veridiumid/cassandra/conf/cassandra.yaml | awk -F' ' '{print $2}' | sort -u)

keytool -list -rfc -keystore $CAS_TRUSTSTORE -storepass $CAS_PASS | awk '/-----BEGIN CERTIFICATE-----/,/-----END CERTIFICATE-----/' > /tmp/all-certs.pem

Important

The extracted file may not include the entire chain.

If necessary, manually append:

  • intermediate certificate

  • root certificate

Otherwise Kibana and Filebeat will fail to start.


Deploy CA File

Copy the CA bundle:

cp /tmp/all-certs.pem /opt/veridiumid/kibana/config/certs/ca.pem
cp /tmp/all-certs.pem /opt/veridiumid/filebeat/config/certs/ca.pem

Restart services:

systemctl restart ver_kibana
systemctl restart ver_filebeat


Last updated: