Skip to main content
Encryption in transit protects data as it moves across the network between YugabyteDB nodes and between clients and the database. YugabyteDB uses TLS (Transport Layer Security) to encrypt all network communication.

TLS Architecture

YugabyteDB supports two types of TLS encryption:
  1. Node-to-Node Encryption: Secures communication between YugabyteDB cluster nodes (masters and tablet servers)
  2. Client-to-Server Encryption: Secures communication between clients and the database cluster
Both can be enabled independently or together for complete network security.

Certificate Requirements

Before enabling TLS, you need to generate certificates for your cluster:
  • CA Certificate (ca.crt): Root certificate authority that signs all node certificates
  • CA Private Key (ca.key): Private key for the CA (keep secure, never deploy to nodes)
  • Node Certificates (node.<hostname>.crt): Individual certificates for each node
  • Node Private Keys (node.<hostname>.key): Private keys for each node certificate

Generate Certificates

Step 1: Create Certificate Directory

mkdir -p secure-data
cd secure-data

Step 2: Create CA Configuration

Create ca.conf:
cat > ca.conf <<'EOF'
[ ca ]
default_ca = my_ca

[ my_ca ]
default_days = 3650
serial = serial.txt
database = index.txt
default_md = sha256
policy = my_policy

[ my_policy ]
organizationName = supplied
commonName = supplied

[ req ]
prompt = no
distinguished_name = my_distinguished_name
x509_extensions = my_extensions

[ my_distinguished_name ]
organizationName = YugabyteDB
commonName = CA for YugabyteDB

[ my_extensions ]
keyUsage = critical,digitalSignature,nonRepudiation,keyEncipherment,keyCertSign
basicConstraints = critical,CA:true,pathlen:1
EOF

Step 3: Initialize Certificate Database

touch index.txt
echo '01' > serial.txt

Step 4: Generate CA Certificate

# Generate CA private key
openssl genrsa -out ca.key 2048
chmod 400 ca.key

# Generate CA certificate
openssl req -new -x509 -days 3650 \
  -config ca.conf \
  -key ca.key \
  -out ca.crt

# Verify CA certificate
openssl x509 -in ca.crt -text -noout

Step 5: Generate Node Certificates

For each node in your cluster:
# Set node IP or hostname
NODE_IP="10.0.1.10"

# Create node configuration
cat > node.${NODE_IP}.conf <<EOF
[ req ]
prompt = no
distinguished_name = my_distinguished_name

[ my_distinguished_name ]
organizationName = YugabyteDB
commonName = ${NODE_IP}

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
IP.1 = ${NODE_IP}
IP.2 = 127.0.0.1
DNS.1 = localhost
DNS.2 = *.example.com
EOF

# Generate node private key
openssl genrsa -out node.${NODE_IP}.key 2048
chmod 400 node.${NODE_IP}.key

# Generate certificate signing request (CSR)
openssl req -new \
  -config node.${NODE_IP}.conf \
  -key node.${NODE_IP}.key \
  -out node.${NODE_IP}.csr

# Sign the certificate with CA
openssl ca -config ca.conf \
  -keyfile ca.key \
  -cert ca.crt \
  -policy my_policy \
  -out node.${NODE_IP}.crt \
  -outdir . \
  -in node.${NODE_IP}.csr \
  -days 3650 \
  -batch \
  -extfile node.${NODE_IP}.conf \
  -extensions req_ext

# Verify node certificate
openssl verify -CAfile ca.crt node.${NODE_IP}.crt

Step 6: Generate Client Certificates

For client authentication:
# Generate client private key
openssl genrsa -out client.key 2048
chmod 400 client.key

# Create client CSR
openssl req -new \
  -key client.key \
  -out client.csr \
  -subj "/O=YugabyteDB/CN=yugabyte"

# Sign client certificate
openssl ca -config ca.conf \
  -keyfile ca.key \
  -cert ca.crt \
  -policy my_policy \
  -out client.crt \
  -outdir . \
  -in client.csr \
  -days 3650 \
  -batch

Deploy Certificates to Nodes

Step 1: Create Certificate Directories on Nodes

# On each node, create cert directory
ssh user@node-ip "mkdir -p ~/certs"

Step 2: Copy Certificates

# For each node, copy the required files
NODE_IP="10.0.1.10"

scp ca.crt user@${NODE_IP}:~/certs/
scp node.${NODE_IP}.crt user@${NODE_IP}:~/certs/
scp node.${NODE_IP}.key user@${NODE_IP}:~/certs/

# Set permissions
ssh user@${NODE_IP} "chmod 400 ~/certs/node.${NODE_IP}.key"
Never copy the CA private key (ca.key) to cluster nodes. Only the CA certificate (ca.crt) should be deployed to nodes.

Enable Node-to-Node Encryption

Start YB-Master and YB-TServer processes with TLS enabled.

YB-Master Configuration

yb-master \
  --fs_data_dirs=/mnt/disk0 \
  --master_addresses=10.0.1.10:7100,10.0.1.11:7100,10.0.1.12:7100 \
  --rpc_bind_addresses=10.0.1.10:7100 \
  --certs_dir=/home/yugabyte/certs \
  --use_node_to_node_encryption=true \
  --allow_insecure_connections=false

YB-TServer Configuration

yb-tserver \
  --fs_data_dirs=/mnt/disk0 \
  --tserver_master_addrs=10.0.1.10:7100,10.0.1.11:7100,10.0.1.12:7100 \
  --rpc_bind_addresses=10.0.1.10:9100 \
  --certs_dir=/home/yugabyte/certs \
  --use_node_to_node_encryption=true \
  --allow_insecure_connections=false

Configuration Flags

FlagDescriptionDefault
--use_node_to_node_encryptionEnable encryption between nodesfalse
--use_client_to_server_encryptionEnable encryption for client connectionsfalse
--allow_insecure_connectionsAllow unencrypted connectionstrue
--certs_dirDirectory containing certificates<data_dir>/yb-data/{master|tserver}/data/certs
--certs_for_client_dirSeparate directory for client certsSame as certs_dir

Enable Client-to-Server Encryption

Server Configuration

Enable client-to-server TLS on YB-TServers:
yb-tserver \
  --fs_data_dirs=/mnt/disk0 \
  --tserver_master_addrs=10.0.1.10:7100,10.0.1.11:7100,10.0.1.12:7100 \
  --rpc_bind_addresses=10.0.1.10:9100 \
  --certs_for_client_dir=/home/yugabyte/certs \
  --use_client_to_server_encryption=true \
  --use_node_to_node_encryption=true \
  --allow_insecure_connections=false

Client Configuration

Connect using ysqlsh with TLS:
# Connect with SSL enabled (default sslmode=prefer)
ysqlsh -h 10.0.1.10

# Require SSL connection
ysqlsh -h 10.0.1.10 "sslmode=require"

# Verify server certificate
ysqlsh -h 10.0.1.10 \
  "sslmode=verify-full sslrootcert=/path/to/ca.crt"

# Use client certificate authentication
ysqlsh -h 10.0.1.10 \
  "sslmode=require \
   sslcert=/path/to/client.crt \
   sslkey=/path/to/client.key \
   sslrootcert=/path/to/ca.crt"

SSL Modes for Clients

ModeDescription
disableNo SSL connection
allowTry non-SSL first, then SSL
preferTry SSL first, then non-SSL (default)
requireRequire SSL, but don’t verify certificate
verify-caRequire SSL and verify CA signature
verify-fullRequire SSL, verify CA and hostname

TLS with Authentication

Combine TLS encryption with various authentication methods.

TLS with Password Authentication

# Start with TLS and SCRAM-SHA-256 auth
yb-tserver \
  --use_client_to_server_encryption=true \
  --certs_for_client_dir=/home/yugabyte/certs \
  --ysql_enable_auth=true \
  --ysql_pg_conf_csv="password_encryption=scram-sha-256" \
  --ysql_hba_conf_csv='hostssl all all 0.0.0.0/0 scram-sha-256'
Connect:
ysqlsh -h 10.0.1.10 -U myuser "sslmode=require"
# Will prompt for password

TLS with Certificate Authentication

# Require client certificates
yb-tserver \
  --use_client_to_server_encryption=true \
  --certs_for_client_dir=/home/yugabyte/certs \
  --ysql_hba_conf_csv='hostssl all all all cert'
Connect:
ysqlsh -h 10.0.1.10 \
  "sslmode=require \
   sslcert=/path/to/client.crt \
   sslkey=/path/to/client.key \
   sslrootcert=/path/to/ca.crt"

TLS with Both Password and Certificate

# Require both certificate and password
yb-tserver \
  --use_client_to_server_encryption=true \
  --certs_for_client_dir=/home/yugabyte/certs \
  --ysql_hba_conf_csv='hostssl all all all scram-sha-256 clientcert=verify-full'
The clientcert=verify-full option requires clients to present a valid certificate AND provide a correct password. This provides the strongest authentication.

Quick Setup with yugabyted

For testing and development, use yugabyted to generate certificates automatically:
# Generate certificates for localhost
yugabyted cert generate_server_certs --hostnames=127.0.0.1

# Certificates created in ~/var/generated_certs/127.0.0.1/
# - ca.crt
# - node.127.0.0.1.crt
# - node.127.0.0.1.key

# Start with TLS enabled
export CERTS_DIR=~/var/generated_certs/127.0.0.1

yugabyted start \
  --tserver_flags="use_client_to_server_encryption=true,certs_for_client_dir=$CERTS_DIR"

# Connect with TLS
ysqlsh "sslmode=require"

Verify TLS Configuration

Check that TLS is properly configured:
# Check node-to-node encryption status via master UI
curl -k https://10.0.1.10:7000/tablet-servers

# Check client SSL status in ysqlsh
ysqlsh -h 10.0.1.10 -c "\conninfo"

# Should show: SSL connection (protocol: TLSv1.3, cipher: ...)
Query SSL connection info:
-- Check current connection SSL status
SELECT ssl_is_used();

-- View SSL version
SHOW ssl_version;

-- Check SSL cipher
SHOW ssl_cipher;

Certificate Rotation

Rotate certificates before they expire without downtime.

Step 1: Generate New Certificates

# Create new CA and node certificates
# Follow the certificate generation steps above

Step 2: Deploy New Certificates

# Copy new certificates to nodes
for node in 10.0.1.10 10.0.1.11 10.0.1.12; do
  scp ca.crt user@${node}:~/certs/ca_new.crt
  scp node.${node}.crt user@${node}:~/certs/node_new.crt
  scp node.${node}.key user@${node}:~/certs/node_new.key
done

Step 3: Rolling Restart

Restart nodes one at a time:
# On each node:
# 1. Stop the process
systemctl stop yb-tserver

# 2. Replace certificates
cd ~/certs
mv node.*.crt node.old.crt
mv node.*.key node.old.key
mv ca.crt ca.old.crt
mv node_new.crt node.$(hostname -i).crt
mv node_new.key node.$(hostname -i).key
mv ca_new.crt ca.crt

# 3. Restart
systemctl start yb-tserver

# 4. Wait for node to be healthy before proceeding to next node

Performance Considerations

TLS encryption adds minimal overhead:
  • Connection overhead: 10-50ms for TLS handshake (one-time per connection)
  • Throughput overhead: 2-5% with modern CPUs supporting AES-NI
  • Latency overhead: less than 1ms per request

Optimization Tips

  1. Use hardware with AES-NI support
  2. Enable TLS session resumption
  3. Use connection pooling to amortize handshake costs
  4. Choose modern cipher suites (TLS 1.3)

Security Best Practices

  1. Use Strong Ciphers: Configure TLS 1.2+ with strong cipher suites
  2. Verify Certificates: Use verify-full SSL mode for production clients
  3. Rotate Certificates: Rotate certificates before expiration (recommend 90 days before)
  4. Secure Private Keys: Store private keys with 400 permissions, never share
  5. Separate CAs: Consider separate CAs for node and client certificates
  6. Monitor Expiration: Set up alerts for certificate expiration
  7. Disable Weak Protocols: Disable TLS 1.0 and 1.1
  8. Use HSM: Store CA private key in Hardware Security Module (HSM)

Troubleshooting

TLS handshake failures:
# Check certificate validity
openssl x509 -in node.crt -noout -dates

# Verify certificate chain
openssl verify -CAfile ca.crt node.crt

# Check TLS configuration in logs
tail -f /mnt/disk0/yb-data/tserver/logs/yb-tserver.INFO | grep -i tls
Certificate verification fails:
# Check CN and SAN match hostname
openssl x509 -in node.crt -noout -subject -ext subjectAltName

# Verify CA certificate is correct
diff ca.crt /path/to/deployed/ca.crt
Connection refused after enabling TLS:
  • Ensure --allow_insecure_connections=false is only set after all nodes have TLS enabled
  • Check firewall rules allow TLS ports
  • Verify certificates are in correct directory specified by --certs_dir
Client cannot connect with SSL:
# Test SSL connection
openssl s_client -connect 10.0.1.10:5433 -CAfile ca.crt

# Check server SSL configuration
ysqlsh -h 10.0.1.10 -c "SHOW ssl"

Build docs developers (and LLMs) love