Skip to content

TLS Encryption

Tellstone supports TLS 1.3 transport encryption for both the binary protocol and the optional RESP2 listener. TLS is off by default and activated by providing a certificate and private key.

Terminal window
./bin/tellstone \
--tls-cert /path/to/server.crt \
--tls-key /path/to/server.key

This enables server-only TLS. Clients must verify the server certificate using the issuing CA.

Add the --tls-ca flag to require clients to present a certificate:

Terminal window
./bin/tellstone \
--tls-cert /path/to/server.crt \
--tls-key /path/to/server.key \
--tls-ca /path/to/ca.crt

When --tls-ca is set, Tellstone verifies every client certificate against the provided CA. Connections without a valid client certificate are rejected.

Flags providedBehaviour
(none)Plaintext — no encryption
--tls-cert + --tls-keyServer-only TLS
--tls-cert + --tls-key + --tls-caMutual TLS (mTLS)

Environment variables follow the same pattern: TELLSTONE_TLS_CERT, TELLSTONE_TLS_KEY, and TELLSTONE_TLS_CA. Flags take precedence when both are set.

For development and testing, generate a self-signed CA and server certificate:

Terminal window
# Generate CA
openssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \
-keyout ca.key -out ca.crt -nodes \
-subj "/CN=Tellstone Dev CA"
# Generate server key + CSR
openssl req -newkey rsa:2048 -nodes \
-keyout server.key -out server.csr \
-subj "/CN=localhost"
# Sign server certificate
openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \
-CAcreateserial -out server.crt -days 3650

For mTLS, generate client certificates the same way (replace server with client in the steps above), then sign them with the same CA.

Tellstone uses a forked TLS 1.3 implementation optimised for gnet’s epoll-based event-loop:

  • TLS 1.3 only — no support for TLS 1.0, 1.1, or 1.2
  • Cipher suites — AES-128-GCM-SHA256, AES-256-GCM-SHA384, ChaCha20-Poly1305-SHA256
  • Zero-allocation fast path — pre-allocated read buffer avoids per-record allocations
  • Single binary — no external OpenSSL dependency; TLS is compiled in

The repository includes a TLS-capable example client:

Terminal window
go run ./cmd/example/tls \
--addr localhost:9988 \
--tls-cert /path/to/ca.crt \
--tls-server-name localhost

This demonstrates both server-only TLS and mTLS connections.

TLS adds approximately one extra allocation per operation compared to plaintext. Benchmarks on AMD Ryzen 9 9950X:

ModeAllocs/op
Plaintext2
TLS 1.33

The single extra allocation originates from the TLS encryption layer and cannot be eliminated from the application side.

  • Default cipher suites are not marked insecure
  • No legacy protocol versions or cipher suites are compiled in
  • Renegotiation and downgrade attacks are structurally impossible
  • Server-only TLS protects against passive eavesdropping
  • mTLS additionally protects against unauthorised clients