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.
Quick Start
Section titled “Quick Start”./bin/tellstone \ --tls-cert /path/to/server.crt \ --tls-key /path/to/server.keyThis enables server-only TLS. Clients must verify the server certificate using the issuing CA.
Mutual TLS (mTLS)
Section titled “Mutual TLS (mTLS)”Add the --tls-ca flag to require clients to present a certificate:
./bin/tellstone \ --tls-cert /path/to/server.crt \ --tls-key /path/to/server.key \ --tls-ca /path/to/ca.crtWhen --tls-ca is set, Tellstone verifies every client certificate against
the provided CA. Connections without a valid client certificate are rejected.
Flag Semantics
Section titled “Flag Semantics”| Flags provided | Behaviour |
|---|---|
| (none) | Plaintext — no encryption |
--tls-cert + --tls-key | Server-only TLS |
--tls-cert + --tls-key + --tls-ca | Mutual 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.
Generating Certificates
Section titled “Generating Certificates”For development and testing, generate a self-signed CA and server certificate:
# Generate CAopenssl req -x509 -newkey rsa:4096 -sha256 -days 3650 \ -keyout ca.key -out ca.crt -nodes \ -subj "/CN=Tellstone Dev CA"
# Generate server key + CSRopenssl req -newkey rsa:2048 -nodes \ -keyout server.key -out server.csr \ -subj "/CN=localhost"
# Sign server certificateopenssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key \ -CAcreateserial -out server.crt -days 3650For mTLS, generate client certificates the same way (replace server with
client in the steps above), then sign them with the same CA.
Protocol Details
Section titled “Protocol Details”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
Connecting with the TLS Example Client
Section titled “Connecting with the TLS Example Client”The repository includes a TLS-capable example client:
go run ./cmd/example/tls \ --addr localhost:9988 \ --tls-cert /path/to/ca.crt \ --tls-server-name localhostThis demonstrates both server-only TLS and mTLS connections.
Performance
Section titled “Performance”TLS adds approximately one extra allocation per operation compared to plaintext. Benchmarks on AMD Ryzen 9 9950X:
| Mode | Allocs/op |
|---|---|
| Plaintext | 2 |
| TLS 1.3 | 3 |
The single extra allocation originates from the TLS encryption layer and cannot be eliminated from the application side.
Security Model
Section titled “Security Model”- 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