Skip to content

Tls

Chapter 34: TLS/SSL Security Configuration

Section titled “Chapter 34: TLS/SSL Security Configuration”

TLS (Transport Layer Security) encryption is essential for protecting blockchain node communications. This chapter covers comprehensive TLS configuration for securing RPC endpoints, APIs, and inter-node communications.


┌─────────────────────────────────────────────────────────────────────────────┐
│ TLS SECURITY IMPORTANCE │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ WITHOUT TLS: WITH TLS: │
│ ━━━━━━━━━━ ━━━━━━━ │
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ Client │────── Data ──────▶│ Node │ │
│ └─────────┘ (UNENCRYPTED) └─────────┘ │
│ │
│ Vulnerable to: Protected by: │
│ - Eavesdropping - Encryption │
│ - Data tampering - Authentication │
│ - MITM attacks - Integrity verification │
│ - Credential theft - Certificate validation │
│ │
│ │
│ Common Attacks: │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ MITM Attack: │ │
│ │ Attacker intercepts communication between │ │
│ │ client and node, potentially modifying transactions │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
BenefitDescription
EncryptionData is unreadable to eavesdroppers
AuthenticationVerifies the server’s identity
IntegrityDetects data tampering
ComplianceRequired for many security standards

Terminal window
# Generate self-signed certificate with RSA key
openssl req -x509 -newkey rsa:4096 \
-keyout server-key.pem \
-out server-cert.pem \
-days 365 -nodes \
-subj "/C=US/ST=CA/L=SanFrancisco/O=Blockchain/CN=localhost"
# Verify the certificate
openssl x509 -in server-cert.pem -text -noout
Terminal window
# Install Certbot
sudo apt update
sudo apt install certbot python3-certbot-nginx
# Generate certificate
sudo certbot --nginx -d rpc.yourdomain.com
# Auto-renewal
sudo certbot renew --dry-run
# Add to crontab
0 0 * * * certbot renew --quiet
Terminal window
# Generate certificate with intermediate CA
openssl req -x509 -newkey rsa:4096 \
-keyout server-key.pem \
-out server-cert.pem \
-days 365 -nodes \
-CAcreateserial
# For client certificate authentication
openssl genrsa -out client-key.pem 2048
openssl req -new -key client-key.pem -out client.csr
openssl x509 -req -in client.csr -CA server-cert.pem \
-CAkey server-key.pem -CAcreateserial \
-out client-cert.pem -days 365

/etc/nginx/sites-available/blockchain-rpc
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name rpc.yourdomain.com;
# SSL Configuration
ssl_certificate /etc/letsencrypt/live/rpc.yourdomain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/rpc.yourdomain.com/privkey.pem;
# SSL Security Settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256';
ssl_prefer_server_ciphers off;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
# HSTS (optional but recommended)
add_header Strict-Transport-Security "max-age=63072000" always;
location / {
proxy_pass http://127.0.0.1:8545;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
# Headers
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts
proxy_connect_timeout 60s;
proxy_send_timeout 60s;
proxy_read_timeout 60s;
}
}
# Redirect HTTP to HTTPS
server {
listen 80;
server_name rpc.yourdomain.com;
return 301 https://$server_name$request_uri;
}
# Advanced SSL configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384';
ssl_prefer_server_ciphers off;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Terminal window
# Geth doesn't support TLS directly, use nginx or reverse proxy
# But you can enable metrics over TLS using SSH tunnel
# Create SSH tunnel for metrics
ssh -L 6060:localhost:6060 -N user@your-node-server
# For internal use only, bind RPC to localhost
geth \
--http \
--http.addr "127.0.0.1" \
--http.port 8545 \
--http.api "eth,net,web3" \
--http.corsdomain ""
Terminal window
# Erigon supports TLS for gRPC
erigon \
--grpc \
--grpc.addr "0.0.0.0" \
--grpc.port 9090 \
--tls \
--tls.cert "/path/to/server-cert.pem" \
--tls.key "/path/to/server-key.pem"

Mutual TLS provides two-way authentication - both client and server verify each other’s certificates.

┌─────────────────────────────────────────────────────────────────┐
│ MUTUAL TLS (MTLS) FLOW │
├─────────────────────────────────────────────────────────────────┤
│ │
│ │
│ ┌──────────┐ ┌──────────┐ │
│ │ Client │ │ Node │ │
│ └────┬─────┘ └────┬─────┘ │
│ │ │ │
│ │────────── TLS Handshake Request ────────▶│ │
│ │ (Client Certificate) │ │
│ │◀────────── Server Certificate ────────────│ │
│ │ │ │
│ │────────── Verify Server Cert ────────────▶│ │
│ │◀────────── Verify Client Cert ────────────│ │
│ │ │ │
│ │════════ Encrypted Connection ═════════════│ │
│ │
│ Both sides verify each other's certificates │
│ │
└─────────────────────────────────────────────────────────────────┘
server {
listen 443 ssl http2;
server_name rpc.yourdomain.com;
# Server certificate
ssl_certificate /path/to/server-cert.pem;
ssl_certificate_key /path/to/server-key.pem;
# Client CA (to verify client certificates)
ssl_client_certificate /path/to/client-ca.pem;
ssl_verify_client on;
ssl_verify_depth 2;
location / {
proxy_pass http://127.0.0.1:8545;
}
}

34.6 Certificate Management Best Practices

Section titled “34.6 Certificate Management Best Practices”
rotate-certs.sh
#!/bin/bash
# Backup old certificates
cp /path/to/server-cert.pem /path/to/server-cert.pem.bak
cp /path/to/server-key.pem /path/to/server-key.pem.bak
# Install new certificates
cp new-cert.pem /path/to/server-cert.pem
cp new-key.pem /path/to/server-key.pem
# Reload Nginx
nginx -s reload
# Or restart your node if using direct TLS
systemctl restart geth
Terminal window
# Check certificate expiration
openssl x509 -in /path/to/server-cert.pem -noout -dates
# Add to monitoring
# In your monitoring system, check:
# ssl_cert_not_after (epoch timestamp)

QuestionAnswer
Why is TLS important for blockchain nodes?Encrypts data in transit, prevents MITM attacks
What’s the difference between TLS and mTLS?TLS only verifies server, mTLS verifies both sides
How do you get production certificates?Let’s Encrypt, DigiCert, or internal CA
What is OCSP stapling?Server provides certificate revocation status directly
How often should certificates be rotated?Every 90 days or per organization policy

  • Always use TLS for production RPC endpoints
  • Use Nginx or similar proxy for TLS termination
  • Implement mTLS for high-security requirements
  • Regularly rotate certificates
  • Monitor certificate expiration

In Chapter 35: Validator Slashing Protection, we’ll explore validator security.


Last Updated: 2026-02-20