Configure ScyllaDB SSL encryption and authentication with certificate management and security hardening

Advanced 45 min May 04, 2026 94 views
Ubuntu 24.04 Debian 12 AlmaLinux 9 Rocky Linux 9

Secure your ScyllaDB cluster with comprehensive SSL/TLS encryption for client connections and inter-node communication. This tutorial covers certificate generation, authentication setup, and production security hardening.

Prerequisites

  • Root access to ScyllaDB servers
  • Basic knowledge of SSL/TLS concepts
  • Understanding of ScyllaDB cluster topology
  • Network access between cluster nodes

What this solves

ScyllaDB clusters need SSL encryption to protect data in transit and authentication to control access. This tutorial sets up comprehensive security including client-server SSL, inter-node encryption, certificate management, and role-based authentication. You'll secure both external client connections and internal cluster communication.

Step-by-step configuration

Install ScyllaDB and SSL tools

First install ScyllaDB and the SSL certificate tools needed for encryption.

sudo apt update
wget -qO - https://downloads.scylladb.com/deb/ubuntu/scylla-6.0-key.asc | sudo gpg --dearmor -o /etc/apt/keyrings/scylladb.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/scylladb.gpg] https://downloads.scylladb.com/deb/ubuntu/ $(lsb_release -sc) scylla-6.0" | sudo tee /etc/apt/sources.list.d/scylladb.list
sudo apt update
sudo apt install -y scylla openssl
sudo dnf update -y
sudo rpm --import https://downloads.scylladb.com/rpm/scylladb-6.0-key.asc
sudo curl -o /etc/yum.repos.d/scylladb-6.0.repo https://downloads.scylladb.com/rpm/centos/scylladb-6.0.repo
sudo dnf install -y scylla openssl

Create SSL certificate directory structure

Set up directories for SSL certificates with proper ownership and permissions.

sudo mkdir -p /etc/scylla/ssl/ca
sudo mkdir -p /etc/scylla/ssl/server
sudo mkdir -p /etc/scylla/ssl/client
sudo chown -R scylla:scylla /etc/scylla/ssl
sudo chmod -R 750 /etc/scylla/ssl

Generate Certificate Authority (CA)

Create a private CA to sign all ScyllaDB certificates. This CA will be used for both client and server certificates.

cd /etc/scylla/ssl/ca
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=CA/L=San Francisco/O=ScyllaDB/OU=Database/CN=ScyllaDB-CA"
sudo chown scylla:scylla ca-*.pem
sudo chmod 600 ca-key.pem
sudo chmod 644 ca-cert.pem

Generate server certificates

Create SSL certificates for ScyllaDB servers. Replace the IP addresses with your actual server IPs.

cd /etc/scylla/ssl/server
sudo openssl genrsa -out server-key.pem 2048
sudo openssl req -new -key server-key.pem -out server.csr -subj "/C=US/ST=CA/L=San Francisco/O=ScyllaDB/OU=Database/CN=scylla-server"

Create server certificate extensions

sudo tee server-ext.cnf > /dev/null << 'EOF' subjectAltName = @alt_names [alt_names] DNS.1 = localhost DNS.2 = scylla-server IP.1 = 127.0.0.1 IP.2 = 203.0.113.10 IP.3 = 203.0.113.11 IP.4 = 203.0.113.12 EOF sudo openssl x509 -req -in server.csr -CA ../ca/ca-cert.pem -CAkey ../ca/ca-key.pem -out server-cert.pem -days 365 -extensions v3_req -extfile server-ext.cnf sudo chown scylla:scylla server-*.pem sudo chmod 600 server-key.pem sudo chmod 644 server-cert.pem sudo rm server.csr server-ext.cnf

Generate client certificates

Create certificates for client authentication. Each client application should have its own certificate.

cd /etc/scylla/ssl/client
sudo openssl genrsa -out client-key.pem 2048
sudo openssl req -new -key client-key.pem -out client.csr -subj "/C=US/ST=CA/L=San Francisco/O=ScyllaDB/OU=Client/CN=scylla-client"
sudo openssl x509 -req -in client.csr -CA ../ca/ca-cert.pem -CAkey ../ca/ca-key.pem -out client-cert.pem -days 365
sudo chown scylla:scylla client-*.pem
sudo chmod 600 client-key.pem
sudo chmod 644 client-cert.pem
sudo rm client.csr

Configure ScyllaDB SSL encryption

Enable SSL encryption for both client connections and inter-node communication.

# Client-server SSL configuration
client_encryption_options:
    enabled: true
    optional: false
    certificate: /etc/scylla/ssl/server/server-cert.pem
    keyfile: /etc/scylla/ssl/server/server-key.pem
    truststore: /etc/scylla/ssl/ca/ca-cert.pem
    require_client_auth: true
    protocol: TLSv1.2

Inter-node SSL configuration

server_encryption_options: internode_encryption: all certificate: /etc/scylla/ssl/server/server-cert.pem keyfile: /etc/scylla/ssl/server/server-key.pem truststore: /etc/scylla/ssl/ca/ca-cert.pem require_client_auth: true protocol: TLSv1.2

Enable password authentication

Configure ScyllaDB to use password-based authentication for additional security.

# Authentication configuration
authenticator: PasswordAuthenticator
authorizer: CassandraAuthorizer
role_manager: CassandraRoleManager

Increase authentication cache to improve performance

authentication_cache_size_mb: 128 authentication_cache_update_interval_in_ms: 2000 permissions_cache_max_entries: 1000 permissions_validity_in_ms: 10000

Configure network and security settings

Set additional security parameters for production deployment.

# Network configuration
listen_address: 203.0.113.10
rpc_address: 203.0.113.10
broadcast_address: 203.0.113.10
broadcast_rpc_address: 203.0.113.10

Security hardening

enable_user_defined_functions: false enable_scripted_user_defined_functions: false enable_materialized_views: false

Connection limits

native_transport_max_concurrent_connections: 1024 native_transport_max_concurrent_connections_per_ip: 256

Request timeouts

request_timeout_in_ms: 10000 read_request_timeout_in_ms: 5000 write_request_timeout_in_ms: 2000

Start ScyllaDB with SSL

Enable and start ScyllaDB with the new SSL configuration.

sudo systemctl enable scylla-server
sudo systemctl start scylla-server
sudo systemctl status scylla-server

Create administrative user

Connect to ScyllaDB and create a secure administrative user to replace the default cassandra user.

# Connect using default credentials initially
cqlsh 203.0.113.10 9042 -u cassandra -p cassandra --ssl

In the CQL shell, create a new admin user and remove default access:

CREATE ROLE scylladb_admin WITH LOGIN = true AND SUPERUSER = true AND PASSWORD = 'SecureAdminPass123!';
ALTER ROLE cassandra WITH PASSWORD = 'RandomSecurePassword456!' AND SUPERUSER = false;
LIST ROLES;

Configure SSL client connection

Create a client configuration file for SSL connections.

[connection]
hostname = 203.0.113.10
port = 9042
username = scylladb_admin
password = SecureAdminPass123!

[ssl]
certfile = /etc/scylla/ssl/client/client-cert.pem
validate = true
userkey = /etc/scylla/ssl/client/client-key.pem
usercert = /etc/scylla/ssl/client/client-cert.pem
version = TLSv1_2
mkdir -p ~/.cassandra
sudo cp /etc/scylla/ssl/client/client-*.pem ~/.cassandra/
sudo cp /etc/scylla/ssl/ca/ca-cert.pem ~/.cassandra/
sudo chown $USER:$USER ~/.cassandra/*

Create application-specific roles

Set up role-based access control for different applications and users.

cqlsh --ssl
# Create keyspace for application
CREATE KEYSPACE IF NOT EXISTS app_data 
WITH REPLICATION = {'class': 'SimpleStrategy', 'replication_factor': 3};

Create application user with limited permissions

CREATE ROLE app_user WITH LOGIN = true AND PASSWORD = 'AppUserSecure789!'; GRANT SELECT, INSERT, UPDATE, DELETE ON KEYSPACE app_data TO app_user;

Create read-only analytics user

CREATE ROLE analytics_user WITH LOGIN = true AND PASSWORD = 'AnalyticsRead456!'; GRANT SELECT ON KEYSPACE app_data TO analytics_user;

Create backup user

CREATE ROLE backup_user WITH LOGIN = true AND PASSWORD = 'BackupSecure123!'; GRANT SELECT ON ALL KEYSPACES TO backup_user;

Configure audit logging

Enable audit logging for security compliance and monitoring.

# Audit logging configuration
audit_logging_options:
    enabled: true
    logger: BinAuditLogger
    audit_logs_dir: /var/lib/scylla/audit
    included_keyspaces: "system_auth,app_data"
    included_categories: "QUERY,DML,DDL,DCL,AUTH"
    included_users: "scylladb_admin,app_user"
sudo mkdir -p /var/lib/scylla/audit
sudo chown scylla:scylla /var/lib/scylla/audit
sudo chmod 750 /var/lib/scylla/audit
sudo systemctl restart scylla-server

Verify your setup

Test SSL connections and authentication to ensure everything works correctly.

# Test SSL connection with admin user
cqlsh 203.0.113.10 9042 -u scylladb_admin -p 'SecureAdminPass123!' --ssl

Verify SSL encryption is active

netstat -tlnp | grep :9042

Check certificate validity

openssl x509 -in /etc/scylla/ssl/server/server-cert.pem -text -noout | grep -A 2 "Validity"

Test application user permissions

cqlsh 203.0.113.10 9042 -u app_user -p 'AppUserSecure789!' --ssl -e "USE app_data; DESCRIBE KEYSPACE app_data;"

Check audit logs

sudo ls -la /var/lib/scylla/audit/ sudo tail -f /var/lib/scylla/audit/*.log

SSL certificate management

Set up certificate renewal

Create automated certificate renewal to prevent expiration issues.

#!/bin/bash
set -euo pipefail

ScyllaDB SSL Certificate Renewal Script

SSL_DIR="/etc/scylla/ssl" BACKUP_DIR="/var/backups/scylla-ssl-$(date +%Y%m%d)" LOG_FILE="/var/log/scylla-cert-renewal.log" echo "$(date): Starting certificate renewal" >> $LOG_FILE

Create backup

mkdir -p $BACKUP_DIR cp -r $SSL_DIR/* $BACKUP_DIR/

Check certificate expiry (renew if < 30 days)

if openssl x509 -checkend 2592000 -noout -in $SSL_DIR/server/server-cert.pem; then echo "$(date): Certificate valid for 30+ days, skipping renewal" >> $LOG_FILE exit 0 fi echo "$(date): Certificate expires soon, renewing..." >> $LOG_FILE

Generate new server certificate

cd $SSL_DIR/server openssl genrsa -out server-key-new.pem 2048 openssl req -new -key server-key-new.pem -out server-new.csr -subj "/C=US/ST=CA/L=San Francisco/O=ScyllaDB/OU=Database/CN=scylla-server"

Create extensions file

cat > server-ext.cnf << EOF subjectAltName = @alt_names [alt_names] DNS.1 = localhost DNS.2 = scylla-server IP.1 = 127.0.0.1 IP.2 = 203.0.113.10 IP.3 = 203.0.113.11 IP.4 = 203.0.113.12 EOF openssl x509 -req -in server-new.csr -CA ../ca/ca-cert.pem -CAkey ../ca/ca-key.pem -out server-cert-new.pem -days 365 -extensions v3_req -extfile server-ext.cnf

Replace old certificates

mv server-key.pem server-key-old.pem mv server-cert.pem server-cert-old.pem mv server-key-new.pem server-key.pem mv server-cert-new.pem server-cert.pem chown scylla:scylla server-*.pem chmod 600 server-key.pem chmod 644 server-cert.pem

Clean up

rm server-new.csr server-ext.cnf echo "$(date): Certificate renewal completed" >> $LOG_FILE echo "$(date): Restarting ScyllaDB..." >> $LOG_FILE

Restart ScyllaDB

systemctl restart scylla-server if systemctl is-active --quiet scylla-server; then echo "$(date): ScyllaDB restarted successfully" >> $LOG_FILE else echo "$(date): ERROR - ScyllaDB failed to restart" >> $LOG_FILE # Rollback certificates mv server-key.pem server-key-failed.pem mv server-cert.pem server-cert-failed.pem mv server-key-old.pem server-key.pem mv server-cert-old.pem server-cert.pem systemctl start scylla-server exit 1 fi
sudo chmod +x /usr/local/bin/scylla-cert-renewal.sh
sudo chown root:root /usr/local/bin/scylla-cert-renewal.sh

Schedule certificate monitoring

Set up automated monitoring and renewal using systemd timers.

[Unit]
Description=ScyllaDB SSL Certificate Check
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/scylla-cert-renewal.sh
User=root
Group=root
[Unit]
Description=Run ScyllaDB certificate check weekly
Requires=scylla-cert-check.service

[Timer]
OnCalendar=weekly
Persistent=true

[Install]
WantedBy=timers.target
sudo systemctl daemon-reload
sudo systemctl enable scylla-cert-check.timer
sudo systemctl start scylla-cert-check.timer
sudo systemctl list-timers scylla-cert-check.timer

Security hardening

Configure firewall rules

Restrict network access to only necessary ports and IP addresses.

# Allow ScyllaDB ports for specific IP ranges
sudo ufw allow from 203.0.113.0/24 to any port 9042 comment 'ScyllaDB CQL SSL'
sudo ufw allow from 203.0.113.0/24 to any port 7001 comment 'ScyllaDB Inter-node SSL'
sudo ufw allow from 203.0.113.0/24 to any port 7199 comment 'ScyllaDB JMX'

Allow monitoring from management network

sudo ufw allow from 203.0.113.100/32 to any port 9180 comment 'ScyllaDB Prometheus'

Enable firewall

sudo ufw --force enable sudo ufw status numbered
# Create ScyllaDB service for firewalld
sudo firewall-cmd --permanent --new-service=scylladb-ssl
sudo firewall-cmd --permanent --service=scylladb-ssl --add-port=9042/tcp
sudo firewall-cmd --permanent --service=scylladb-ssl --add-port=7001/tcp
sudo firewall-cmd --permanent --service=scylladb-ssl --add-port=7199/tcp
sudo firewall-cmd --permanent --service=scylladb-ssl --add-port=9180/tcp

Apply rules to trusted zone with specific sources

sudo firewall-cmd --permanent --zone=trusted --add-source=203.0.113.0/24 sudo firewall-cmd --permanent --zone=trusted --add-service=scylladb-ssl

Reload firewall

sudo firewall-cmd --reload sudo firewall-cmd --list-all-zones

Enable system audit logging

Configure system-level auditing for ScyllaDB processes and files.

# Monitor ScyllaDB configuration changes
-w /etc/scylla/scylla.yaml -p wa -k scylladb_config
-w /etc/scylla/ssl/ -p wa -k scylladb_ssl

Monitor ScyllaDB data directory

-w /var/lib/scylla/ -p wa -k scylladb_data

Monitor ScyllaDB process execution

-w /usr/bin/scylla -p x -k scylladb_exec

Monitor authentication attempts

-w /var/lib/scylla/audit/ -p wa -k scylladb_auth
sudo systemctl enable auditd
sudo systemctl restart auditd
sudo auditctl -l

Set up log monitoring

Configure centralized logging for security events and SSL certificate monitoring.

# ScyllaDB logging
if $programname == 'scylla' then {
    /var/log/scylladb/scylla.log
    stop
}

SSL certificate events

if $msg contains 'SSL' or $msg contains 'certificate' then { /var/log/scylladb/ssl.log stop }

Authentication events

if $msg contains 'authentication' or $msg contains 'login' then { /var/log/scylladb/auth.log stop }
sudo mkdir -p /var/log/scylladb
sudo chown scylla:scylla /var/log/scylladb
sudo systemctl restart rsyslog
sudo logrotate -d /etc/logrotate.conf

Common issues

SymptomCauseFix
SSL handshake failureCertificate hostname mismatchAdd server IP/hostname to certificate SAN field
Client authentication failedClient certificate not trustedVerify client cert is signed by same CA: openssl verify -CAfile /etc/scylla/ssl/ca/ca-cert.pem /etc/scylla/ssl/client/client-cert.pem
Inter-node SSL errorsClock skew between nodesSync time with NTP: sudo systemctl enable --now ntp
Certificate expiredCertificate past validity periodCheck expiry: openssl x509 -enddate -noout -in cert.pem and renew
Permission denied on key filesIncorrect file ownershipsudo chown scylla:scylla /etc/scylla/ssl/server/server-key.pem && sudo chmod 600
Connection timeout with SSLFirewall blocking encrypted portOpen port 9042 for CQL SSL and 7001 for inter-node SSL
High SSL CPU usageWeak cipher suitesUse stronger ciphers in scylla.yaml: cipher_suites: [TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384]
Authentication cache missesCache too small for user loadIncrease authentication_cache_size_mb in config

Next steps

Running this in production?

Want this handled for you? Running this at scale adds a second layer of work: capacity planning, failover drills, cost control, and on-call. See how we run infrastructure like this for European teams.

Automated install script

Run this to automate the entire setup

Need help?

Don't want to manage this yourself?

We handle high availability infrastructure for businesses that depend on uptime. From initial setup to ongoing operations.