cloudflare/pingora
TLS options
Pingora supports four TLS backends behind the same API. The choice happens at compile time via cargo features. This page covers the practical concerns: which to pick, mTLS, SSLKEYLOGFILE, and connection filtering.
For the per-crate breakdown, see TLS backends.
Picking a backend
| Backend | Cargo feature | When to use |
|---|---|---|
| OpenSSL | openssl |
Default. Mature, broad protocol support. |
| BoringSSL | boringssl |
FIPS compliance, or matching Cloudflare production exactly. Build needs Clang. |
| s2n-tls | s2n |
Aligning with AWS-style infrastructure. |
| rustls | rustls |
Pure-Rust deploys with no native deps. Highly experimental. |
The features are mutually exclusive on the pingora umbrella crate. Setting two of them is a build error.
Configuring TLS for listeners
Listener TLS is configured per endpoint. The accepted shape varies by backend, but the common pattern:
use pingora_core::listeners::tls::TlsSettings;
let mut tls = TlsSettings::intermediate(cert_path, key_path)?;
// backend-specific tweaks via tls.deref_mut()
service.add_tls(addr, tls);TlsSettings::intermediate configures the Mozilla "intermediate" cipher suite list, a sane default. TlsSettings::modern is stricter; TlsSettings::with_callbacks lets you supply backend-native callbacks (cert reload, SNI handling).
Configuring TLS for upstreams (peers)
Per-peer TLS is configured on HttpPeer:
let mut peer = HttpPeer::new(addr, /*use_tls=*/ true, "sni.example.com".to_string());
peer.options.verify_cert = true; // verify upstream cert
peer.options.verify_hostname = true; // hostname must match SNI
peer.options.ca = Some(ca_bundle); // override system CA
peer.options.alternative_cn = Some(...); // SAN/CN allow-listThe verify_cert and verify_hostname options work for rustls as of 0.7.0.
mTLS (mutual TLS)
The 0.7.0 release added HttpProxy::new_mtls which takes a client cert and key:
let proxy = HttpProxy::new_mtls(my_app, conf, client_cert, client_key);This wires the proxy's outbound connector to present the cert to upstreams that ask for one. It also supports verifying the upstream's cert against a custom CA.
SSLKEYLOGFILE
When using pingora-rustls (only), set the SSLKEYLOGFILE environment variable to a file path. The rustls connector will log session keys in the standard NSS format that Wireshark understands. Useful for debugging encrypted traffic.
OpenSSL/BoringSSL/s2n don't expose this from Pingora today; you'd need to wire it through their native APIs.
Connection filtering (connection_filter feature)
Added in 0.7.0. With the connection_filter cargo feature on, you can implement a ConnectionFilter trait that runs before TLS handshake — useful for IP-based allow/deny, rate limiting at the L4 boundary, or stamping per-connection state onto the session.
#[async_trait]
impl ConnectionFilter for MyFilter {
async fn filter(&self, peer_addr: SocketAddr, ctx: &mut FilterCtx) -> bool {
// return false to reject before TLS handshake
}
}Wired in pingora-core/src/listeners/connection_filter.rs.
Default protocols
- TLS 1.2 and TLS 1.3 are accepted by default.
- ALPN advertisement is automatic —
h2first, thenhttp/1.1for HTTP listeners. - Custom ALPNs are supported on the s2n backend (
b370102fixed an s2n issue around ALPN).
Source map
| Concern | File |
|---|---|
| Listener TLS config | pingora-core/src/listeners/tls/ |
| Connector TLS | pingora-core/src/connectors/tls/ |
| Peer TLS settings | pingora-core/src/upstreams/peer.rs |
| Backend dispatch shim | pingora-core/src/tls/ |
| Backend crates | pingora-{openssl,boringssl,rustls,s2n}/src/ |
| Connection filter | pingora-core/src/listeners/connection_filter.rs |
See also
- TLS backends
- Configuration —
s2n_config_cache_size,ca_file
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.