Configuration: security and TLS
This page documents the TLS crypto directives available inside a tls { ... } block. These settings are optional. Ferron uses safe defaults when you omit a setting. The TLS crypto configuration applies to all TLS providers: manual, acme, and local.
Directives#
Certificate and private key#
cert <path: string>- This directive specifies the path to the server certificate file. The file must be PEM format and include the leaf certificate and any intermediate certificates your CA requires.
key <path: string>- This directive specifies the path to the server private key file. The file must be PEM format.
These directives are required for the manual provider. Make sure Ferron can read both files. The certificate and private key must match. If they do not match, TLS handshakes fail. You can use environment variable interpolation for the paths.
Configuration example:
example.com {
tls {
provider manual
cert "/path/cert.pem"
key "/path/key.pem"
}
}Cipher suites#
cipher_suite <suite: string>- This directive specifies a cipher suite to add to the allowed list. Repeatable. Each occurrence adds one suite. When you omit it, rustls defaults apply. Default: rustls defaults.
Configuration example:
example.com {
tls {
provider manual
cert "/path/cert.pem"
key "/path/key.pem"
cipher_suite TLS_AES_128_GCM_SHA256
cipher_suite TLS_AES_256_GCM_SHA384
}
}Supported cipher suites#
| Suite | Protocol | Key exchange | Notes |
|---|---|---|---|
TLS_AES_128_GCM_SHA256 | TLS 1.3 | Any | Default in most deployments |
TLS_AES_256_GCM_SHA384 | TLS 1.3 | Any | Stronger encryption |
TLS_CHACHA20_POLY1305_SHA256 | TLS 1.3 | Any | Software-optimized, good for mobile |
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 | TLS 1.2 | ECDHE + ECDSA | ECDSA certificate required |
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 | TLS 1.2 | ECDHE + ECDSA | ECDSA certificate required |
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 | TLS 1.2 | ECDHE + ECDSA | ECDSA certificate required |
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 | TLS 1.2 | ECDHE + RSA | RSA certificate |
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 | TLS 1.2 | ECDHE + RSA | RSA certificate |
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 | TLS 1.2 | ECDHE + RSA | RSA certificate |
TLS 1.2 cipher suites are only effective when min_version allows TLS 1.2.
ECDH curves#
ecdh_curve <curve: string>- This directive specifies an ECDH key exchange group to add to the allowed list, in priority order. Repeatable. Each occurrence adds one curve. When you omit it, rustls defaults apply. Default: rustls defaults.
Supported curves#
| Curve | Type | Notes |
|---|---|---|
x25519 | ECDH | Fast, widely supported, recommended default |
secp256r1 | ECDH | NIST P-256, required for some compliance standards |
secp384r1 | ECDH | NIST P-384, higher security level |
x25519mlkem768 | Hybrid (ECDH + ML-KEM) | Post-quantum hybrid with x25519 |
mlkem768 | ML-KEM | Pure post-quantum KEM |
TLS protocol version#
min_version <version: string>- This directive specifies the minimum allowed TLS version. Supported values:
TLSv1.2,TLSv1.3. Default:min_version TLSv1.2
- This directive specifies the minimum allowed TLS version. Supported values:
max_version <version: string>- This directive specifies the maximum allowed TLS version. Supported values:
TLSv1.2,TLSv1.3. Default:max_version TLSv1.3
- This directive specifies the maximum allowed TLS version. Supported values:
Configuration example: TLS 1.3 only
example.com {
tls {
provider manual
cert "/path/cert.pem"
key "/path/key.pem"
min_version TLSv1.3
max_version TLSv1.3
}
}If you omit both, Ferron uses the safe default range (TLS 1.2 to 1.3). Setting only min_version restricts the lower bound. Setting only max_version restricts the upper bound. Ferron returns an error if max_version is older than min_version.
Client certificate authentication (mTLS)#
client_auth [bool: boolean]- This directive turns client certificate authentication on or off. When
true, clients must present a valid certificate. Default:client_auth false
- This directive turns client certificate authentication on or off. When
client_auth_ca <source: string>- This directive specifies the source of trusted CA certificates for verifying client certificates. Supported values: a file path (
"/path/ca-cert.pem"),system(OS native root store, requiresnative-certsfeature),webpki(Mozilla root bundle). Default:client_auth_ca webpki
- This directive specifies the source of trusted CA certificates for verifying client certificates. Supported values: a file path (
Configuration example: full mTLS
api.example.com {
tls {
provider manual
cert "/etc/ssl/api.example.com/cert.pem"
key "/etc/ssl/api.example.com/key.pem"
min_version TLSv1.3
max_version TLSv1.3
cipher_suite TLS_AES_256_GCM_SHA384
cipher_suite TLS_CHACHA20_POLY1305_SHA256
ecdh_curve x25519
ecdh_curve secp256r1
client_auth
client_auth_ca "/etc/ssl/internal-ca/ca-bundle.pem"
}
}- Client certificate verification uses the same trust model as server-side TLS. The client cert chain must validate against the configured CA roots.
- When
client_auth_capoints to a file with multiple CA certificates (a bundle), Ferron loads all of them into the trust store. - The
systemtrust store includes all OS-trusted root CAs. Use it only when you want to accept client certificates from any publicly trusted CA. This is rarely the right choice for mTLS. - For internal mTLS deployments, use a private CA and set
client_auth_cato the CA bundle file path.
If you see client certificate handshake failures:
- Verify the client certificate chain validates against the CA specified in
client_auth_ca. - Check that the CA certificate file is a valid PEM and has not expired.
- If you use
client_auth_ca system, make sure the OS trusts the issuing CA.
Observability#
Metrics#
| Metric | Type | Attributes | Description |
|---|---|---|---|
ferron.tls.certificate_not_after | Gauge | ferron.host, ferron.tls.provider (http), crypto.certificate.serial_number | Certificate notAfter as Unix epoch seconds |
See also#
Best practices#
ferron doctor reports the following best-practice checks for directives on this page.
max_version TLSv1.2: Disabling TLS 1.3 reduces security and performance. Allow TLS 1.3 unless legacy clients require TLS 1.2 only.client_authwith public trust store: Usingsystemorwebpkiroots for mTLS client authentication trusts any certificate from the public PKI. Use a private CA bundle file for mTLS instead.ocspdisabled: OCSP stapling improves TLS privacy, performance, and revocation behavior. Keep it enabled.ticket_keyswithoutauto_rotate: Session ticket keys should rotate automatically in production to limit the impact of key compromise.ticket_keys.max_keysoutside 2–5: The optimal range keeps enough old keys for rotation without interruption and without excessive retention.ticket_keys.rotation_interval> 24h: Rotate session ticket keys every 12–24 hours in production.