Set up comprehensive SSL/TLS encryption for Apache Cassandra with client-to-node and node-to-node security, certificate management, and production-grade authentication hardening.
Prerequisites
- Root or sudo access
- Apache Cassandra 4.0 or higher
- Java 11 or higher
- Basic understanding of SSL/TLS concepts
What this solves
Apache Cassandra clusters handle sensitive data that requires encryption in transit and strong authentication. This tutorial configures SSL/TLS encryption for both client-to-node and node-to-node communication, sets up certificate-based authentication, and implements security hardening measures for production environments.
Step-by-step configuration
Install Cassandra and Java
Install Apache Cassandra and Java Development Kit required for SSL operations.
wget -q -O - https://www.apache.org/dist/cassandra/KEYS | sudo apt-key add -
echo "deb https://debian.cassandra.apache.org 40x main" | sudo tee -a /etc/apt/sources.list.d/cassandra.sources.list
sudo apt update
sudo apt install -y cassandra openjdk-11-jdk-headless
Create SSL certificate directories
Set up directory structure for storing SSL certificates with proper permissions.
sudo mkdir -p /etc/cassandra/ssl/{keystore,truststore,certs}
sudo chown -R cassandra:cassandra /etc/cassandra/ssl
sudo chmod 750 /etc/cassandra/ssl
sudo chmod 750 /etc/cassandra/ssl/{keystore,truststore,certs}
Generate Certificate Authority
Create a private Certificate Authority for signing Cassandra node certificates.
cd /etc/cassandra/ssl/certs
sudo openssl genrsa -out ca-key.pem 4096
sudo openssl req -new -x509 -key ca-key.pem -out ca-cert.pem -days 3650 -subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=CassandraCA"
Generate node certificates
Create SSL certificates for each Cassandra node in your cluster.
# Generate private key for node
sudo openssl genrsa -out node1-key.pem 2048
Create certificate signing request
sudo openssl req -new -key node1-key.pem -out node1.csr -subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=cassandra-node1.example.com"
Sign the certificate with CA
sudo openssl x509 -req -in node1.csr -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out node1-cert.pem -days 365 -extensions v3_req -extfile <(echo "[v3_req]
subjectAltName=DNS:cassandra-node1.example.com,DNS:localhost,IP:127.0.0.1")
Set proper permissions
sudo chown cassandra:cassandra /etc/cassandra/ssl/certs/*
sudo chmod 600 /etc/cassandra/ssl/certs/*-key.pem
sudo chmod 644 /etc/cassandra/ssl/certs/*-cert.pem /etc/cassandra/ssl/certs/ca-cert.pem
Create Java keystores
Convert PEM certificates to Java keystores required by Cassandra.
# Create PKCS12 keystore
sudo openssl pkcs12 -export -in /etc/cassandra/ssl/certs/node1-cert.pem -inkey /etc/cassandra/ssl/certs/node1-key.pem -out /etc/cassandra/ssl/keystore/node1.p12 -name node1 -CAfile /etc/cassandra/ssl/certs/ca-cert.pem -caname root -password pass:cassandra123
Convert to JKS format
sudo keytool -importkeystore -deststorepass cassandra123 -destkeypass cassandra123 -destkeystore /etc/cassandra/ssl/keystore/node1.jks -srckeystore /etc/cassandra/ssl/keystore/node1.p12 -srcstoretype PKCS12 -srcstorepass cassandra123 -alias node1
Create truststore with CA certificate
sudo keytool -import -alias ca -file /etc/cassandra/ssl/certs/ca-cert.pem -keystore /etc/cassandra/ssl/truststore/truststore.jks -storepass cassandra123 -noprompt
Set keystore permissions
sudo chown cassandra:cassandra /etc/cassandra/ssl/keystore/ /etc/cassandra/ssl/truststore/
sudo chmod 600 /etc/cassandra/ssl/keystore/ /etc/cassandra/ssl/truststore/
Configure client-to-node SSL encryption
Enable SSL encryption for client connections by modifying the Cassandra configuration.
# Client encryption options
client_encryption_options:
enabled: true
optional: false
keystore: /etc/cassandra/ssl/keystore/node1.jks
keystore_password: cassandra123
truststore: /etc/cassandra/ssl/truststore/truststore.jks
truststore_password: cassandra123
protocol: TLS
algorithm: SunX509
store_type: JKS
cipher_suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA]
require_client_auth: true
Configure node-to-node SSL encryption
Enable SSL encryption for inter-node communication within the cluster.
# Server encryption options
server_encryption_options:
internode_encryption: all
keystore: /etc/cassandra/ssl/keystore/node1.jks
keystore_password: cassandra123
truststore: /etc/cassandra/ssl/truststore/truststore.jks
truststore_password: cassandra123
protocol: TLS
algorithm: SunX509
store_type: JKS
cipher_suites: [TLS_RSA_WITH_AES_256_CBC_SHA, TLS_RSA_WITH_AES_128_CBC_SHA]
require_client_auth: true
Configure authentication and authorization
Enable password authentication and role-based access control.
# Authentication and authorization
authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer
role_manager: CassandraRoleManager
Network topology strategy for system_auth
system_auth_replication:
class: NetworkTopologyStrategy
datacenter1: 3
Configure SSL native transport port
Set the SSL-enabled native transport port for client connections.
# Native transport configuration
native_transport_port: 9042
native_transport_port_ssl: 9142
start_native_transport: true
Configure JVM SSL options
Set JVM SSL parameters for proper certificate validation.
# SSL debugging (remove in production)
-Djavax.net.debug=ssl
SSL trust store location
-Djavax.net.ssl.trustStore=/etc/cassandra/ssl/truststore/truststore.jks
-Djavax.net.ssl.trustStorePassword=cassandra123
SSL key store location
-Djavax.net.ssl.keyStore=/etc/cassandra/ssl/keystore/node1.jks
-Djavax.net.ssl.keyStorePassword=cassandra123
Disable hostname verification for self-signed certificates
-Dcom.datastax.driver.FORCE_NIO=true
Create SSL-enabled cqlshrc configuration
Configure cqlsh client to use SSL connections with certificate validation.
[connection]
hostname = 127.0.0.1
port = 9142
factory = cqlshlib.ssl.ssl_transport_factory
[ssl]
certfile = /etc/cassandra/ssl/certs/ca-cert.pem
validate = true
userkey = /etc/cassandra/ssl/certs/node1-key.pem
usercert = /etc/cassandra/ssl/certs/node1-cert.pem
version = TLSv1_2
sudo mkdir -p /home/cassandra/.cassandra
sudo chown cassandra:cassandra /home/cassandra/.cassandra
sudo chmod 755 /home/cassandra/.cassandra
Implement security hardening
Apply additional security configurations for production deployments.
# Security hardening options
enable_user_defined_functions: false
enable_scripted_user_defined_functions: false
enable_materialized_views: false
transparent_data_encryption_options:
enabled: false
chunk_length_in_kb: 64
cipher: AES/CBC/PKCS5Padding
key_alias: testing:1
key_provider:
- class_name: org.apache.cassandra.security.JKSKeyProvider
parameters:
- keystore: /etc/cassandra/ssl/keystore/node1.jks
keystore_password: cassandra123
store_type: JKS
key_password: cassandra123
Configure firewall rules
Set up firewall rules to restrict access to Cassandra SSL ports.
sudo ufw allow from 203.0.113.0/24 to any port 9142 comment 'Cassandra SSL client'
sudo ufw allow from 203.0.113.0/24 to any port 7001 comment 'Cassandra SSL inter-node'
sudo ufw allow from 203.0.113.0/24 to any port 7199 comment 'Cassandra JMX'
sudo ufw reload
Start and enable Cassandra service
Start Cassandra with SSL configuration and enable automatic startup.
sudo systemctl enable cassandra
sudo systemctl restart cassandra
sudo systemctl status cassandra
Create secure database users
Set up authenticated users with specific permissions.
# Connect using default cassandra user
cqlsh -u cassandra -p cassandra --ssl
Create application user with limited permissions
CREATE ROLE app_user WITH PASSWORD = 'SecurePass123!' AND LOGIN = true;
GRANT SELECT, INSERT, UPDATE, DELETE ON KEYSPACE myapp TO app_user;
Create monitoring user
CREATE ROLE monitor_user WITH PASSWORD = 'MonitorPass123!' AND LOGIN = true;
GRANT SELECT ON SYSTEM.LOCAL TO monitor_user;
GRANT SELECT ON SYSTEM.PEERS TO monitor_user;
Change default cassandra password
ALTER ROLE cassandra WITH PASSWORD = 'NewCassandraPass123!';
Configure certificate rotation
Set up automated certificate rotation using systemd timers.
#!/bin/bash
set -euo pipefail
CERT_DIR="/etc/cassandra/ssl/certs"
KEYSTORE_DIR="/etc/cassandra/ssl/keystore"
TRUSTSTORE_DIR="/etc/cassandra/ssl/truststore"
NODE_NAME="node1"
KEYSTORE_PASS="cassandra123"
cd "$CERT_DIR"
Check if certificate expires in 30 days
if openssl x509 -checkend 2592000 -noout -in "${NODE_NAME}-cert.pem"; then
echo "Certificate valid for 30+ days"
exit 0
fi
echo "Certificate expires soon, rotating..."
Generate new certificate
openssl genrsa -out "${NODE_NAME}-key-new.pem" 2048
openssl req -new -key "${NODE_NAME}-key-new.pem" -out "${NODE_NAME}-new.csr" -subj "/C=US/ST=State/L=City/O=Organization/OU=IT/CN=cassandra-${NODE_NAME}.example.com"
openssl x509 -req -in "${NODE_NAME}-new.csr" -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial -out "${NODE_NAME}-cert-new.pem" -days 365
Update keystore
openssl pkcs12 -export -in "${NODE_NAME}-cert-new.pem" -inkey "${NODE_NAME}-key-new.pem" -out "${KEYSTORE_DIR}/${NODE_NAME}-new.p12" -name "$NODE_NAME" -CAfile ca-cert.pem -caname root -password "pass:$KEYSTORE_PASS"
keytool -importkeystore -deststorepass "$KEYSTORE_PASS" -destkeypass "$KEYSTORE_PASS" -destkeystore "${KEYSTORE_DIR}/${NODE_NAME}-new.jks" -srckeystore "${KEYSTORE_DIR}/${NODE_NAME}-new.p12" -srcstoretype PKCS12 -srcstorepass "$KEYSTORE_PASS" -alias "$NODE_NAME"
Backup old certificates
cp "${NODE_NAME}-cert.pem" "${NODE_NAME}-cert.pem.bak"
cp "${NODE_NAME}-key.pem" "${NODE_NAME}-key.pem.bak"
cp "${KEYSTORE_DIR}/${NODE_NAME}.jks" "${KEYSTORE_DIR}/${NODE_NAME}.jks.bak"
Replace certificates
mv "${NODE_NAME}-cert-new.pem" "${NODE_NAME}-cert.pem"
mv "${NODE_NAME}-key-new.pem" "${NODE_NAME}-key.pem"
mv "${KEYSTORE_DIR}/${NODE_NAME}-new.jks" "${KEYSTORE_DIR}/${NODE_NAME}.jks"
Set permissions
chown cassandra:cassandra "${NODE_NAME}-cert.pem" "${NODE_NAME}-key.pem" "${KEYSTORE_DIR}/${NODE_NAME}.jks"
chmod 600 "${NODE_NAME}-key.pem" "${KEYSTORE_DIR}/${NODE_NAME}.jks"
chmod 644 "${NODE_NAME}-cert.pem"
Restart Cassandra
systemctl restart cassandra
echo "Certificate rotation completed"
sudo chmod +x /usr/local/bin/cassandra-cert-rotate.sh
Create systemd timer for certificate rotation
Schedule automatic certificate rotation checks.
[Unit]
Description=Cassandra Certificate Rotation
After=network.target
[Service]
Type=oneshot
User=root
ExecStart=/usr/local/bin/cassandra-cert-rotate.sh
TimeoutStartSec=300
[Unit]
Description=Run Cassandra Certificate Rotation Weekly
Requires=cassandra-cert-rotate.service
[Timer]
OnCalendar=weekly
Persistent=true
[Install]
WantedBy=timers.target
sudo systemctl enable cassandra-cert-rotate.timer
sudo systemctl start cassandra-cert-rotate.timer
Verify your setup
Test SSL connectivity and authentication to ensure proper configuration.
# Test SSL connection
cqlsh -u cassandra -p NewCassandraPass123! --ssl 127.0.0.1 9142
Verify SSL settings
nodetool status
nodetool info
Check certificate expiration
openssl x509 -in /etc/cassandra/ssl/certs/node1-cert.pem -noout -dates
Test authentication
cqlsh -u app_user -p SecurePass123! --ssl 127.0.0.1 9142
Verify encryption is working
netstat -tlnp | grep :9142
ss -tlnp | grep :7001
Common issues
| Symptom | Cause | Fix |
|---|---|---|
| cqlsh SSL connection refused | Wrong port or SSL not enabled | Check port 9142 is configured and client_encryption_options.enabled: true |
| Certificate verification failed | Hostname mismatch | Add proper SAN entries or use IP addresses in certificate |
| Keystore password error | Incorrect keystore password | Verify password matches in cassandra.yaml and keystore creation |
| Inter-node SSL handshake failure | Certificate not trusted | Ensure all nodes have CA certificate in truststore |
| Authentication failed after SSL | User not created or wrong password | Check LIST ROLES; and recreate user with correct password |
| Performance degradation | CPU overhead from encryption | Monitor CPU usage and consider hardware crypto acceleration |
SSL certificate management best practices
Implement these practices for robust certificate lifecycle management.
- Monitor certificate expiration dates with automated alerts
- Use separate certificates for each environment (dev, staging, production)
- Implement certificate revocation lists (CRL) for compromised certificates
- Store private keys securely with restricted file permissions
- Use certificate transparency logs for public-facing certificates
- Test certificate rotation procedures in non-production environments
- Document certificate authority chain and validation procedures
For advanced security configurations, consider implementing database-specific SSL hardening techniques and integrate with your existing security infrastructure.
Next steps
- Optimize Cassandra data modeling and query performance
- Set up Cassandra backup automation with nodetool
- Configure Cassandra multi-datacenter replication with SSL
- Implement Cassandra audit logging with security monitoring
- Set up Cassandra connection pooling with Java drivers
Running this in production?
Automated install script
Run this to automate the entire setup
#!/usr/bin/env bash
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Usage function
usage() {
echo "Usage: $0 [CLUSTER_NAME] [KEYSTORE_PASSWORD]"
echo " CLUSTER_NAME: Name for the Cassandra cluster (default: cassandra-cluster)"
echo " KEYSTORE_PASSWORD: Password for SSL keystore (default: generated)"
exit 1
}
# Error handling
cleanup() {
echo -e "${RED}[ERROR]${NC} Installation failed. Cleaning up..."
systemctl stop cassandra 2>/dev/null || true
rm -f /tmp/cassandra-ssl-setup.lock
}
trap cleanup ERR
# Check if running as root
if [[ $EUID -ne 0 ]]; then
echo -e "${RED}[ERROR]${NC} This script must be run as root"
exit 1
fi
# Parse arguments
CLUSTER_NAME="${1:-cassandra-cluster}"
KEYSTORE_PASS="${2:-$(openssl rand -base64 32 | tr -d '=+/' | cut -c1-25)}"
if [[ $# -gt 2 ]]; then
usage
fi
# Lock file to prevent multiple runs
LOCK_FILE="/tmp/cassandra-ssl-setup.lock"
if [[ -f "$LOCK_FILE" ]]; then
echo -e "${RED}[ERROR]${NC} Another instance is running"
exit 1
fi
touch "$LOCK_FILE"
echo -e "${GREEN}[INFO]${NC} Starting Cassandra SSL configuration for cluster: $CLUSTER_NAME"
# Auto-detect distribution
echo -e "${YELLOW}[1/8]${NC} Detecting distribution..."
if [[ ! -f /etc/os-release ]]; then
echo -e "${RED}[ERROR]${NC} Cannot detect distribution"
exit 1
fi
source /etc/os-release
case "$ID" in
ubuntu|debian)
PKG_MGR="apt"
PKG_UPDATE="apt update"
PKG_INSTALL="apt install -y"
JAVA_PKG="openjdk-11-jdk-headless"
CASSANDRA_USER="cassandra"
CASSANDRA_GROUP="cassandra"
CASSANDRA_HOME="/var/lib/cassandra"
CASSANDRA_CONF="/etc/cassandra"
;;
almalinux|rocky|centos|rhel|ol)
PKG_MGR="dnf"
PKG_UPDATE="dnf check-update || true"
PKG_INSTALL="dnf install -y"
JAVA_PKG="java-11-openjdk-headless"
CASSANDRA_USER="cassandra"
CASSANDRA_GROUP="cassandra"
CASSANDRA_HOME="/var/lib/cassandra"
CASSANDRA_CONF="/etc/cassandra/default.conf"
;;
fedora)
PKG_MGR="dnf"
PKG_UPDATE="dnf check-update || true"
PKG_INSTALL="dnf install -y"
JAVA_PKG="java-11-openjdk-headless"
CASSANDRA_USER="cassandra"
CASSANDRA_GROUP="cassandra"
CASSANDRA_HOME="/var/lib/cassandra"
CASSANDRA_CONF="/etc/cassandra/default.conf"
;;
amzn)
PKG_MGR="yum"
PKG_UPDATE="yum check-update || true"
PKG_INSTALL="yum install -y"
JAVA_PKG="java-11-amazon-corretto-headless"
CASSANDRA_USER="cassandra"
CASSANDRA_GROUP="cassandra"
CASSANDRA_HOME="/var/lib/cassandra"
CASSANDRA_CONF="/etc/cassandra/default.conf"
;;
*)
echo -e "${RED}[ERROR]${NC} Unsupported distribution: $ID"
exit 1
;;
esac
# Update package repositories
echo -e "${YELLOW}[2/8]${NC} Updating package repositories..."
$PKG_UPDATE > /dev/null
# Install prerequisites
echo -e "${YELLOW}[3/8]${NC} Installing prerequisites..."
$PKG_INSTALL wget curl gnupg2 openssl > /dev/null
# Install Java and Cassandra
echo -e "${YELLOW}[4/8]${NC} Installing Java and Cassandra..."
$PKG_INSTALL $JAVA_PKG > /dev/null
# Add Cassandra repository and install
case "$ID" in
ubuntu|debian)
wget -q -O - https://www.apache.org/dist/cassandra/KEYS | apt-key add - > /dev/null 2>&1
echo "deb https://debian.cassandra.apache.org 40x main" > /etc/apt/sources.list.d/cassandra.sources.list
apt update > /dev/null
$PKG_INSTALL cassandra > /dev/null
CASSANDRA_CONF="/etc/cassandra"
;;
*)
cat > /etc/yum.repos.d/cassandra.repo << 'EOF'
[cassandra]
name=Apache Cassandra
baseurl=https://redhat.cassandra.apache.org/40x/
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://www.apache.org/dist/cassandra/KEYS
EOF
$PKG_INSTALL cassandra > /dev/null
# Adjust config path for RHEL-based systems
if [[ -d "/etc/cassandra/default.conf" ]]; then
CASSANDRA_CONF="/etc/cassandra/default.conf"
elif [[ -d "/etc/cassandra" ]]; then
CASSANDRA_CONF="/etc/cassandra"
fi
;;
esac
# Create SSL directory structure
echo -e "${YELLOW}[5/8]${NC} Setting up SSL certificate infrastructure..."
SSL_DIR="$CASSANDRA_CONF/ssl"
mkdir -p "$SSL_DIR"
chown root:$CASSANDRA_GROUP "$SSL_DIR"
chmod 750 "$SSL_DIR"
# Generate SSL certificates
cd "$SSL_DIR"
# Create keystore for server certificate
keytool -genkeypair \
-keyalg RSA \
-alias cassandra \
-keystore cassandra-server-keystore.jks \
-storepass "$KEYSTORE_PASS" \
-keypass "$KEYSTORE_PASS" \
-validity 365 \
-keysize 2048 \
-dname "CN=$(hostname -f),OU=IT,O=$CLUSTER_NAME,L=City,ST=State,C=US" \
> /dev/null 2>&1
# Export certificate from keystore
keytool -export \
-alias cassandra \
-file cassandra-server-cert.crt \
-keystore cassandra-server-keystore.jks \
-storepass "$KEYSTORE_PASS" \
> /dev/null 2>&1
# Create truststore and import certificate
keytool -import \
-alias cassandra \
-file cassandra-server-cert.crt \
-keystore cassandra-server-truststore.jks \
-storepass "$KEYSTORE_PASS" \
-noprompt \
> /dev/null 2>&1
# Set proper permissions on SSL files
chown root:$CASSANDRA_GROUP *.jks *.crt
chmod 640 *.jks *.crt
# Configure Cassandra SSL settings
echo -e "${YELLOW}[6/8]${NC} Configuring Cassandra SSL encryption..."
CASSANDRA_YAML="$CASSANDRA_CONF/cassandra.yaml"
# Backup original configuration
cp "$CASSANDRA_YAML" "$CASSANDRA_YAML.backup.$(date +%Y%m%d_%H%M%S)"
# Configure client-to-node encryption
cat >> "$CASSANDRA_YAML" << EOF
# SSL Configuration added by installation script
client_encryption_options:
enabled: true
optional: false
keystore: $SSL_DIR/cassandra-server-keystore.jks
keystore_password: $KEYSTORE_PASS
truststore: $SSL_DIR/cassandra-server-truststore.jks
truststore_password: $KEYSTORE_PASS
protocol: TLS
algorithm: SunX509
store_type: JKS
cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
require_client_auth: false
# Inter-node encryption
server_encryption_options:
internode_encryption: all
keystore: $SSL_DIR/cassandra-server-keystore.jks
keystore_password: $KEYSTORE_PASS
truststore: $SSL_DIR/cassandra-server-truststore.jks
truststore_password: $KEYSTORE_PASS
protocol: TLS
algorithm: SunX509
store_type: JKS
cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA]
require_client_auth: false
# Enable authentication
authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer
EOF
# Configure JVM SSL options
echo -e "${YELLOW}[7/8]${NC} Configuring JVM SSL options..."
JVM_OPTS_FILE="$CASSANDRA_CONF/jvm.options"
if [[ -f "$JVM_OPTS_FILE" ]]; then
# Add SSL debugging and stronger protocols (commented out debugging for production)
cat >> "$JVM_OPTS_FILE" << EOF
# SSL Configuration
-Dcom.sun.management.jmxremote.ssl=true
-Dcom.sun.management.jmxremote.ssl.need.client.auth=false
-Dcom.sun.management.jmxremote.ssl.enabled.protocols=TLSv1.2,TLSv1.3
-Dcom.sun.management.jmxremote.ssl.enabled.cipher.suites=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
# -Djavax.net.debug=ssl (uncomment for SSL debugging)
EOF
fi
# Configure firewall
if command -v ufw > /dev/null 2>&1; then
# Ubuntu/Debian firewall
ufw allow 9042/tcp comment "Cassandra client SSL" > /dev/null 2>&1 || true
ufw allow 7001/tcp comment "Cassandra inter-node SSL" > /dev/null 2>&1 || true
elif command -v firewall-cmd > /dev/null 2>&1; then
# RHEL/CentOS firewall
firewall-cmd --permanent --add-port=9042/tcp > /dev/null 2>&1 || true
firewall-cmd --permanent --add-port=7001/tcp > /dev/null 2>&1 || true
firewall-cmd --reload > /dev/null 2>&1 || true
fi
# Start and enable Cassandra service
systemctl daemon-reload
systemctl enable cassandra > /dev/null 2>&1
systemctl start cassandra
# Wait for Cassandra to start
echo -e "${YELLOW}[8/8]${NC} Starting Cassandra and verifying SSL configuration..."
sleep 10
# Wait for Cassandra to be ready
for i in {1..30}; do
if netstat -tlnp 2>/dev/null | grep -q ":9042.*LISTEN" || ss -tlnp 2>/dev/null | grep -q ":9042"; then
break
fi
if [[ $i -eq 30 ]]; then
echo -e "${RED}[ERROR]${NC} Cassandra failed to start within 5 minutes"
exit 1
fi
sleep 10
done
# Verification checks
echo -e "${GREEN}[SUCCESS]${NC} Verifying installation..."
# Check if Cassandra is running
if ! systemctl is-active cassandra > /dev/null 2>&1; then
echo -e "${RED}[ERROR]${NC} Cassandra service is not running"
exit 1
fi
# Check SSL port
if ! netstat -tlnp 2>/dev/null | grep -q ":9042.*LISTEN" && ! ss -tlnp 2>/dev/null | grep -q ":9042"; then
echo -e "${RED}[ERROR]${NC} Cassandra SSL port 9042 is not listening"
exit 1
fi
# Save keystore password securely
echo "$KEYSTORE_PASS" > "$SSL_DIR/keystore_password"
chown root:$CASSANDRA_GROUP "$SSL_DIR/keystore_password"
chmod 640 "$SSL_DIR/keystore_password"
# Cleanup
rm -f "$LOCK_FILE"
echo -e "${GREEN}[SUCCESS]${NC} Cassandra SSL configuration completed successfully!"
echo ""
echo "SSL Configuration Summary:"
echo "========================="
echo "Cluster Name: $CLUSTER_NAME"
echo "SSL Directory: $SSL_DIR"
echo "Keystore Password: $KEYSTORE_PASS (also saved in $SSL_DIR/keystore_password)"
echo "Client SSL Port: 9042"
echo "Inter-node SSL Port: 7001"
echo ""
echo "Next Steps:"
echo "- Change default cassandra user password using cqlsh --ssl"
echo "- Copy SSL certificates to other cluster nodes"
echo "- Configure client applications to use SSL connection"
echo "- Test SSL connectivity: openssl s_client -connect $(hostname):9042"
Review the script before running. Execute with: bash install.sh