Skip to main content

Overview

TLS (Transport Layer Security) options enable encrypted connections between NATS clients and servers, ensuring secure communication and optional client authentication through certificates.

Command Line Flags

--tls
boolean
default:"false"
Enable TLS without client certificate verification.
nats-server --tls --tlscert ./certs/server-cert.pem --tlskey ./certs/server-key.pem
--tlscert
string
Path to server certificate file (PEM format).
nats-server --tlscert ./certs/server-cert.pem
--tlskey
string
Path to server private key file (PEM format).
nats-server --tlskey ./certs/server-key.pem
--tlsverify
boolean
default:"false"
Enable TLS and verify client certificates.
nats-server --tlsverify --tlscert ./certs/server-cert.pem --tlskey ./certs/server-key.pem --tlscacert ./certs/ca.pem
--tlscacert
string
Path to certificate authority (CA) file for verifying client certificates.
nats-server --tlscacert ./certs/ca.pem

Configuration File Options

Basic TLS Configuration

tls.cert_file
string
required
Path to server certificate file.
tls {
  cert_file: "./certs/server-cert.pem"
}
tls.key_file
string
required
Path to server private key file.
tls {
  key_file: "./certs/server-key.pem"
}
tls.ca_file
string
Path to certificate authority file for client verification.
tls {
  ca_file: "./certs/ca.pem"
}

Client Verification

tls.verify
boolean
default:"false"
Verify client certificates. Requires ca_file.
tls {
  cert_file: "./certs/server-cert.pem"
  key_file: "./certs/server-key.pem"
  ca_file: "./certs/ca.pem"
  verify: true
}
tls.verify_and_map
boolean
default:"false"
Verify client certificates and map certificate fields to user authentication.
tls {
  cert_file: "./certs/server-cert.pem"
  key_file: "./certs/server-key.pem"
  ca_file: "./certs/ca.pem"
  verify_and_map: true
}
tls.insecure
boolean
default:"false"
Skip certificate verification (for testing only).
tls {
  insecure: true
}
Never use in production! This disables security.

Cipher and Protocol Configuration

tls.cipher_suites
array
List of allowed cipher suites. Restricts which encryption algorithms can be used.
tls {
  cipher_suites: [
    "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256",
    "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384",
    "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"
  ]
}
tls.curve_preferences
array
Elliptic curves for ECDHE cipher suites.
tls {
  curve_preferences: [
    "CurveP256",
    "CurveP384",
    "CurveP521"
  ]
}
tls.min_version
string
default:"1.2"
Minimum TLS protocol version. Options: 1.0, 1.1, 1.2, 1.3
tls {
  min_version: "1.3"
}

Performance and Timeout

tls.timeout
float
default:"2.0"
TLS handshake timeout in seconds.
tls {
  timeout: 5.0
}
tls.rate_limit
integer
TLS handshake rate limit in bytes per second.
tls {
  rate_limit: 1048576  # 1 MB/s
}
tls.handshake_first
boolean
default:"false"
Perform TLS handshake before sending INFO protocol.
tls {
  handshake_first: true
}
tls.handshake_first_fallback
duration
Fallback timeout when handshake_first is enabled.
tls {
  handshake_first: true
  handshake_first_fallback: "2s"
}

Certificate Pinning

tls.pinned_certs
array
SHA256 fingerprints of pinned certificates.
tls {
  pinned_certs: [
    "<sha256-fingerprint-1>",
    "<sha256-fingerprint-2>"
  ]
}

Configuration Examples

Basic TLS Server

port: 4222
server_name: "nats-tls"

tls {
  cert_file: "./certs/server-cert.pem"
  key_file: "./certs/server-key.pem"
}

TLS with Client Verification

port: 4222
server_name: "nats-tls-verify"

tls {
  cert_file: "./certs/server-cert.pem"
  key_file: "./certs/server-key.pem"
  ca_file: "./certs/ca.pem"
  verify: true
}

Mutual TLS (mTLS) with Certificate Mapping

port: 4222
server_name: "nats-mtls"

tls {
  cert_file: "./certs/server-cert.pem"
  key_file: "./certs/server-key.pem"
  ca_file: "./certs/ca.pem"
  verify_and_map: true
}

accounts {
  APP: {
    users: [
      # Certificate CN maps to user
      {user: "client1"}
      {user: "client2"}
    ]
  }
}

High Security Configuration

port: 4222
server_name: "nats-secure"

tls {
  cert_file: "./certs/server-cert.pem"
  key_file: "./certs/server-key.pem"
  ca_file: "./certs/ca.pem"
  verify: true
  
  # Require TLS 1.3
  min_version: "1.3"
  
  # Strong cipher suites only
  cipher_suites: [
    "TLS_AES_128_GCM_SHA256",
    "TLS_AES_256_GCM_SHA384",
    "TLS_CHACHA20_POLY1305_SHA256"
  ]
  
  # Modern curves
  curve_preferences: [
    "X25519",
    "CurveP256"
  ]
  
  # Extended timeout for slower clients
  timeout: 10.0
}

Cluster with TLS

port: 4222
server_name: "nats-cluster-tls"

# Client TLS
tls {
  cert_file: "./certs/server-cert.pem"
  key_file: "./certs/server-key.pem"
  ca_file: "./certs/ca.pem"
  verify: true
}

# Cluster with TLS
cluster {
  name: "secure-cluster"
  listen: "0.0.0.0:6222"
  
  tls {
    cert_file: "./certs/route-cert.pem"
    key_file: "./certs/route-key.pem"
    ca_file: "./certs/ca.pem"
    verify: true
  }
  
  routes: [
    "nats://nats-2:6222",
    "nats://nats-3:6222"
  ]
}

Multiple Certificates

port: 4222
server_name: "nats-multi-cert"

tls {
  # Multiple certificate pairs for different domains
  certificates: [
    {
      cert_file: "./certs/example.com.pem"
      key_file: "./certs/example.com-key.pem"
    },
    {
      cert_file: "./certs/api.example.com.pem"
      key_file: "./certs/api.example.com-key.pem"
    }
  ]
  
  ca_file: "./certs/ca.pem"
  verify: true
}

Generating Test Certificates

For development and testing:
# Generate CA
openssl genrsa -out ca-key.pem 4096
openssl req -new -x509 -days 365 -key ca-key.pem -out ca.pem -subj "/CN=NATS CA"

# Generate server certificate
openssl genrsa -out server-key.pem 4096
openssl req -new -key server-key.pem -out server.csr -subj "/CN=localhost"
openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out server-cert.pem

# Generate client certificate
openssl genrsa -out client-key.pem 4096
openssl req -new -key client-key.pem -out client.csr -subj "/CN=client"
openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem -CAcreateserial -out client-cert.pem

Available Cipher Suites

Modern recommended cipher suites:
  • 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_ECDSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
  • TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305

Monitoring TLS Connections

Check TLS connection status via monitoring:
curl http://localhost:8222/connz
Look for tls_version and tls_cipher_suite fields in connection details.

Best Practices

  1. Protocol Version: Use TLS 1.2 or higher (preferably 1.3)
  2. Strong Ciphers: Configure modern cipher suites, avoid weak algorithms
  3. Certificate Management: Use proper PKI and rotate certificates regularly
  4. Client Verification: Enable verify or verify_and_map in production
  5. Certificate Expiry: Monitor certificate expiration dates
  6. Private Keys: Protect private keys with appropriate file permissions (0600)
  7. CA Trust: Use properly signed certificates from trusted CAs in production
  8. Separate Certificates: Use different certificates for client and cluster connections
  9. Timeout Tuning: Adjust timeout based on network conditions
  10. Testing: Always test TLS configuration before deploying to production

Certificate Mapping

When using verify_and_map: true, NATS maps certificate fields to users:
tls {
  verify_and_map: true
  ca_file: "./certs/ca.pem"
}

accounts {
  APP: {
    users: [
      # User derived from certificate CN
      {user: "alice", permissions: {...}}
      {user: "bob", permissions: {...}}
    ]
  }
}
Client certificate with CN=alice will be authenticated as user alice.

Troubleshooting

Certificate Errors

# Verify certificate validity
openssl x509 -in server-cert.pem -text -noout

# Check certificate chain
openssl verify -CAfile ca.pem server-cert.pem

# Test TLS connection
openssl s_client -connect localhost:4222 -CAfile ca.pem

Common Issues

  • Certificate expired: Check expiration with openssl x509 -enddate
  • Hostname mismatch: Ensure certificate CN/SAN matches server hostname
  • CA not trusted: Verify ca_file contains the correct CA certificate
  • Permission denied: Check file permissions on certificate and key files
  • Handshake timeout: Increase timeout value

Server Options

Core server configuration

Cluster Options

Secure cluster with TLS

JetStream Options

Secure JetStream with TLS

Build docs developers (and LLMs) love