Open-Source Wikis

/

Pingora

/

Features

/

TLS options

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-list

The 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 — h2 first, then http/1.1 for HTTP listeners.
  • Custom ALPNs are supported on the s2n backend (b370102 fixed 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

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

TLS options – Pingora wiki | Factory