TLS Overview
NATS Server supports TLS (Transport Layer Security) to encrypt connections and authenticate clients using certificates. TLS is essential for production deployments.
Basic TLS Configuration
Server TLS
Enable TLS for client connections:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
}
Or via command line:
nats-server --tls --tlscert=/path/to/server-cert.pem --tlskey=/path/to/server-key.pem
Full TLS with Client Verification
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
}
Or via command line:
nats-server --tlsverify --tlscert=server.pem --tlskey=key.pem --tlscacert=ca.pem
Certificate Files
NATS accepts PEM-encoded certificates:
server-cert.pem:
-----BEGIN CERTIFICATE-----
MIIDXTCCAkWgAwIBAgIJAKL0UG+mRKu9MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
...
-----END CERTIFICATE-----
server-key.pem:
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDKr5r5YLY+RqZo
...
-----END PRIVATE KEY-----
Generating Self-Signed Certificates
For development/testing:
# Generate CA
openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
-keyout ca-key.pem -out ca.pem \
-subj "/CN=NATS CA"
# Generate server certificate
openssl req -nodes -newkey rsa:2048 \
-keyout server-key.pem -out server.csr \
-subj "/CN=localhost"
# Sign server certificate
openssl x509 -req -days 365 -in server.csr \
-CA ca.pem -CAkey ca-key.pem -CAcreateserial \
-out server-cert.pem
Never use self-signed certificates in production. Obtain certificates from a trusted Certificate Authority.
Client Certificate Verification
Mutual TLS (mTLS)
Require clients to present valid certificates:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
}
Certificate Mapping
Map certificate properties to user accounts:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
map_and_verify: true
}
authorization {
users = [
{
user: "CN=alice,O=Company,C=US"
permissions: {
publish: ["orders.>"]
subscribe: ["results.>"]
}
}
{
user: "CN=bob,O=Company,C=US"
permissions: {
publish: ["events.>"]
subscribe: ["data.>"]
}
}
]
}
Certificate Pinning
Pin specific client certificates:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
verify: true
pinned_certs: [
"/path/to/client1-cert.pem",
"/path/to/client2-cert.pem"
]
}
Cipher Suites
NATS Server supports modern, secure cipher suites.
Default Cipher Suites
From server/ciphersuites.go, NATS uses Go’s tls.CipherSuites() which includes:
- TLS_AES_128_GCM_SHA256 (TLS 1.3)
- TLS_AES_256_GCM_SHA384 (TLS 1.3)
- TLS_CHACHA20_POLY1305_SHA256 (TLS 1.3)
- TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
- TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
- TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
- TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
Custom Cipher Suites
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
cipher_suites: [
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
]
}
Curve Preferences
From server/ciphersuites.go:66-73, default curves (in order):
- X25519MLKEM768 - Post-quantum hybrid
- X25519 - Fast elliptic curve
- CurveP256
- CurveP384
- CurveP521
Custom curve preferences:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
curve_preferences: [
"X25519MLKEM768",
"CurveP256"
]
}
NATS prioritizes post-quantum cryptography with X25519MLKEM768 by default.
FIPS Mode
When FIPS 140 mode is enabled (server/ciphersuites.go:56-65):
- X25519 alone is excluded (not FIPS-approved)
- X25519MLKEM768 is included (FIPS-approved when combined with MLKEM768)
- Only FIPS-compliant cipher suites are available
TLS Versions
Minimum TLS Version
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
min_version: "1.3"
}
Supported values:
1.0 (deprecated, not recommended)
1.1 (deprecated, not recommended)
1.2 (minimum recommended)
1.3 (recommended)
Always use TLS 1.2 or higher. TLS 1.3 provides better performance and security.
TLS Timeout
Configure TLS handshake timeout:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
timeout: 2.0 # seconds
}
TLS for Cluster Routes
Secure cluster communication:
cluster {
name: "production"
listen: "0.0.0.0:6222"
tls {
cert_file: "/path/to/route-cert.pem"
key_file: "/path/to/route-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
}
routes: [
"nats://server2:6222"
"nats://server3:6222"
]
}
TLS for Gateway Connections
Secure super-cluster connections:
gateway {
name: "us-east"
listen: "0.0.0.0:7222"
tls {
cert_file: "/path/to/gateway-cert.pem"
key_file: "/path/to/gateway-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
}
gateways: [
{name: "us-west", urls: ["nats://uswest:7222"]}
{name: "eu-central", urls: ["nats://eu:7222"]}
]
}
TLS for Leaf Nodes
Secure leaf node connections:
leafnodes {
listen: "0.0.0.0:7422"
tls {
cert_file: "/path/to/leaf-cert.pem"
key_file: "/path/to/leaf-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
}
}
TLS for HTTP Monitoring
Secure monitoring endpoints:
https_port: 8443
http {
tls {
cert_file: "/path/to/monitor-cert.pem"
key_file: "/path/to/monitor-key.pem"
}
}
OCSP Stapling
Online Certificate Status Protocol for certificate validation:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
ocsp_peer: true
}
OCSP Peer Verification
Verify client certificates via OCSP:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
ocsp_peer: true
}
Certificate Rotation
Automatic Reload
NATS Server can reload certificates without restart:
# Update certificate files
cp new-cert.pem /path/to/server-cert.pem
cp new-key.pem /path/to/server-key.pem
# Reload server configuration
nats-server --signal reload
Certificate Expiration Monitoring
NATS Server exposes certificate expiration in monitoring endpoints:
{
"tls_cert_not_after": "2026-12-31T23:59:59Z"
}
TLS Best Practices
1. Always Use TLS in Production
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
min_version: "1.3"
}
2. Use Strong Cipher Suites
Avoid weak ciphers:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
cipher_suites: [
"TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384",
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305"
]
}
3. Enable Client Certificate Verification
For maximum security:
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
map_and_verify: true
}
4. Rotate Certificates Regularly
- Set certificate validity to 90 days or less
- Automate renewal (e.g., with Let’s Encrypt)
- Monitor expiration dates
5. Separate Certificates by Component
# Client connections
tls {
cert_file: "/certs/client-cert.pem"
key_file: "/certs/client-key.pem"
}
# Cluster routes
cluster {
tls {
cert_file: "/certs/cluster-cert.pem"
key_file: "/certs/cluster-key.pem"
}
}
# Monitoring
http {
tls {
cert_file: "/certs/monitor-cert.pem"
key_file: "/certs/monitor-key.pem"
}
}
6. Protect Private Keys
# Set restrictive permissions
chmod 600 /path/to/server-key.pem
chown nats:nats /path/to/server-key.pem
7. Enable OCSP
tls {
cert_file: "/path/to/server-cert.pem"
key_file: "/path/to/server-key.pem"
ca_file: "/path/to/ca.pem"
verify: true
ocsp_peer: true
}
Troubleshooting TLS
Test TLS Connection
# Test with openssl
openssl s_client -connect localhost:4222 -CAfile ca.pem
# Test with nats-cli
nats-cli pub test "hello" --tlsca=ca.pem --tlscert=client.pem --tlskey=client-key.pem
Common Errors
“x509: certificate signed by unknown authority”
- Client doesn’t trust server’s CA
- Solution: Provide correct CA file to client
“tls: bad certificate”
- Server rejected client certificate
- Solution: Ensure client cert is signed by trusted CA
“tls: handshake timeout”
- TLS handshake taking too long
- Solution: Increase
tls.timeout value