Files
gh-jezweb-claude-skills-ski…/references/tls-ssl-setup.md
2025-11-30 08:24:16 +08:00

10 KiB

TLS/SSL Setup Guide

Complete guide to configuring SSL/TLS certificates with Hyperdrive.


Overview

Hyperdrive requires TLS/SSL for all database connections.

Supported Configurations:

  1. Basic TLS (require mode) - Default, validates certificates via WebPKI
  2. Server Certificates (verify-ca, verify-full) - Verify server's CA certificate
  3. Client Certificates (mTLS) - Authenticate Hyperdrive to database

SSL Modes

1. require (Default)

What it does:

  • Enforces TLS encryption
  • Validates server certificate using WebPKI (standard browser certificate authorities)
  • No additional certificate configuration needed

When to use:

  • Most cloud databases (AWS RDS, Google Cloud SQL, Azure, Neon, Supabase)
  • Standard SSL/TLS setup
  • Default choice for most applications

Example:

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://user:password@host:5432/database"

# SSL mode is "require" by default

No configuration needed - this is automatic.


2. verify-ca

What it does:

  • Verifies server certificate is signed by expected Certificate Authority (CA)
  • Prevents man-in-the-middle attacks
  • Requires uploading CA certificate to Hyperdrive

When to use:

  • Enhanced security requirements
  • Self-signed certificates
  • Private/internal certificate authorities

Setup:

Step 1: Upload CA certificate:

npx wrangler cert upload certificate-authority \
  --ca-cert /path/to/root-ca.pem \
  --name my-ca-cert

Output:

✅ Uploaded CA Certificate my-ca-cert
ID: ca-12345678-1234-1234-1234-123456789012

Step 2: Create Hyperdrive with CA:

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://user:password@host:5432/database" \
  --ca-certificate-id ca-12345678-1234-1234-1234-123456789012 \
  --sslmode verify-ca

3. verify-full

What it does:

  • Everything from verify-ca, PLUS
  • Verifies database hostname matches Subject Alternative Name (SAN) in certificate

When to use:

  • Maximum security requirements
  • Preventing hostname spoofing
  • Compliance requirements (PCI-DSS, HIPAA)

Setup (same as verify-ca, but use --sslmode verify-full):

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://user:password@host:5432/database" \
  --ca-certificate-id ca-12345678-1234-1234-1234-123456789012 \
  --sslmode verify-full

Certificate Requirements

CA Certificate Format

Must be:

  • PEM format (.pem file)
  • Root CA or Intermediate CA certificate
  • Region-specific (not global bundle with multiple CAs)

Example CA Certificate (root-ca.pem):

-----BEGIN CERTIFICATE-----
MIIDdzCCAl+gAwIBAgIEAgAAuTANBgkqhkiG9w0BAQUFADBaMQswCQYDVQQGEwJJ
...
-----END CERTIFICATE-----

Get CA Certificate:

AWS RDS:

wget https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem
# Use region-specific bundle (NOT global bundle)

Google Cloud SQL:

# Download from Cloud SQL instance details page
# Instance → Connections → Server CA certificate

Azure Database:

wget https://www.digicert.com/CACerts/BaltimoreCyberTrustRoot.crt.pem

Client Certificates (mTLS)

Overview

What is mTLS?

  • Mutual TLS: Both client and server authenticate each other
  • Hyperdrive provides client certificate to database
  • Database verifies certificate before allowing connection

When to use:

  • Database requires client certificate authentication
  • Enhanced security beyond username/password
  • Compliance requirements

Setup

Step 1: Generate Client Certificate (if needed):

# Generate private key
openssl genrsa -out client-key.pem 2048

# Generate certificate signing request (CSR)
openssl req -new -key client-key.pem -out client.csr

# Get certificate from your CA (or self-sign for testing)
openssl x509 -req -in client.csr -CA root-ca.pem -CAkey root-ca-key.pem \
  -CAcreateserial -out client-cert.pem -days 365

Step 2: Upload Client Certificate to Hyperdrive:

npx wrangler cert upload mtls-certificate \
  --cert /path/to/client-cert.pem \
  --key /path/to/client-key.pem \
  --name my-client-cert

Output:

✅ Uploaded client certificate my-client-cert
ID: mtls-87654321-4321-4321-4321-210987654321

Step 3: Create Hyperdrive with Client Certificate:

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://user:password@host:5432/database" \
  --mtls-certificate-id mtls-87654321-4321-4321-4321-210987654321

Optionally combine with server certificates:

npx wrangler hyperdrive create my-db \
  --connection-string="postgres://..." \
  --ca-certificate-id ca-12345678-1234-1234-1234-123456789012 \
  --mtls-certificate-id mtls-87654321-4321-4321-4321-210987654321 \
  --sslmode verify-full

Complete Setup Examples

Example 1: AWS RDS with verify-full

# 1. Download AWS RDS CA certificate (region-specific)
wget https://truststore.pki.rds.amazonaws.com/us-east-1/us-east-1-bundle.pem

# 2. Upload CA certificate
npx wrangler cert upload certificate-authority \
  --ca-cert us-east-1-bundle.pem \
  --name aws-rds-us-east-1-ca

# Output: ID = ca-abc123...

# 3. Create Hyperdrive
npx wrangler hyperdrive create aws-rds-db \
  --connection-string="postgres://admin:password@mydb.abc123.us-east-1.rds.amazonaws.com:5432/postgres" \
  --ca-certificate-id ca-abc123... \
  --sslmode verify-full

Example 2: Self-Hosted with mTLS

# 1. Upload server CA certificate
npx wrangler cert upload certificate-authority \
  --ca-cert /path/to/server-ca.pem \
  --name my-server-ca

# Output: ID = ca-server123...

# 2. Upload client certificate
npx wrangler cert upload mtls-certificate \
  --cert /path/to/client-cert.pem \
  --key /path/to/client-key.pem \
  --name my-client-cert

# Output: ID = mtls-client456...

# 3. Create Hyperdrive with both
npx wrangler hyperdrive create secure-db \
  --connection-string="postgres://user:password@secure-db.example.com:5432/mydb" \
  --ca-certificate-id ca-server123... \
  --mtls-certificate-id mtls-client456... \
  --sslmode verify-full

Example 3: Basic SSL (Default)

# Most cloud databases (AWS, GCP, Azure, Neon, Supabase)
# No certificate configuration needed
npx wrangler hyperdrive create my-db \
  --connection-string="postgres://user:password@host:5432/database"

# SSL mode "require" is automatic

Database Configuration

PostgreSQL SSL Setup

postgresql.conf:

ssl = on
ssl_cert_file = 'server.crt'
ssl_key_file = 'server.key'
ssl_ca_file = 'root.crt'  # For client certificate verification

# Optional: Require SSL
ssl_min_protocol_version = 'TLSv1.2'

pg_hba.conf (require SSL):

# TYPE  DATABASE  USER  ADDRESS    METHOD
hostssl all       all   0.0.0.0/0  md5

# Or require client certificates
hostssl all       all   0.0.0.0/0  cert

Restart PostgreSQL:

sudo systemctl restart postgresql

MySQL SSL Setup

my.cnf or my.ini:

[mysqld]
require_secure_transport = ON
ssl-ca = /path/to/ca-cert.pem
ssl-cert = /path/to/server-cert.pem
ssl-key = /path/to/server-key.pem

Require client certificates (MySQL user):

CREATE USER 'hyperdrive'@'%' IDENTIFIED BY 'password' REQUIRE X509;
GRANT ALL PRIVILEGES ON mydb.* TO 'hyperdrive'@'%';
FLUSH PRIVILEGES;

Restart MySQL:

sudo systemctl restart mysql

Troubleshooting

Error: "TLS not supported by the database"

Cause: Database doesn't have SSL/TLS enabled.

Solution:

  1. Enable SSL in database configuration
  2. Restart database
  3. Verify SSL enabled: SHOW ssl; (MySQL) or SHOW ssl; (PostgreSQL)

PostgreSQL verification:

SHOW ssl;
-- Should return "on"

MySQL verification:

SHOW VARIABLES LIKE 'have_ssl';
-- Should return "YES"

Error: "TLS handshake failed: cert validation failed"

Cause: Server certificate not signed by expected CA.

Solutions:

  1. Verify correct CA certificate uploaded
  2. Check CA certificate is for correct region (AWS RDS)
  3. Ensure CA certificate format is PEM
  4. Verify connection string hostname matches certificate SAN (verify-full mode)

Error: "Server return error and closed connection"

Cause: Database requires client certificate, but none provided.

Solution: Upload client certificate and configure Hyperdrive with mTLS:

npx wrangler cert upload mtls-certificate \
  --cert client-cert.pem \
  --key client-key.pem \
  --name my-cert

npx wrangler hyperdrive create my-db \
  --connection-string="..." \
  --mtls-certificate-id <id>

Error: "Certificate has expired"

Cause: Server certificate or client certificate expired.

Solutions:

  1. Renew certificate from certificate authority
  2. Upload new certificate to Hyperdrive
  3. Update Hyperdrive configuration

Local Development

SSL in Local Development

Option 1: Disable SSL for local database (NOT recommended):

# Local PostgreSQL without SSL
export CLOUDFLARE_HYPERDRIVE_LOCAL_CONNECTION_STRING_HYPERDRIVE="postgres://user:password@localhost:5432/db?sslmode=disable"

Option 2: Use Tunnel for local database (Recommended):

# Use Cloudflare Tunnel to local database (keeps SSL)
cloudflared tunnel create local-db
cloudflared tunnel run local-db

# Hyperdrive connects via tunnel with SSL

Option 3: Self-signed certificates for local dev:

# Generate self-signed cert
openssl req -new -x509 -days 365 -nodes -out server.crt -keyout server.key

# Configure local PostgreSQL to use it
# Then use verify-ca mode with local CA

Best Practices

  1. Use default require mode unless you have specific security requirements
  2. Use verify-full for production if handling sensitive data
  3. Store certificates securely - don't commit to git
  4. Rotate certificates regularly - before expiration
  5. Test certificate setup in staging before production
  6. Use region-specific CA bundles (AWS RDS) not global bundles
  7. Document certificate IDs in project README
  8. Monitor certificate expiration (set calendar reminders)

References