Skip to content

feat(tls): expose PROXY-recovered client addr to cert callback via SSL ex_data#25

Merged
pigri merged 4 commits into
mainfrom
feat/ssl-client-ex-data
Jun 14, 2026
Merged

feat(tls): expose PROXY-recovered client addr to cert callback via SSL ex_data#25
pigri merged 4 commits into
mainfrom
feat/ssl-client-ex-data

Conversation

@pigri

@pigri pigri commented Jun 14, 2026

Copy link
Copy Markdown

Stash the PROXY-protocol-recovered client address on the TLS SSL object (via an
ex_data index) just before the server handshake invokes the certificate callback,
and expose a small client_addr_ex::{set,get} helper to read it back.

This lets a consumer's certificate_callback see the real client IP even for
HTTP/2, where the SslStream isn't reachable on the request path. peer_addr()
returns the recovered address once maybe_consume_proxy_header has patched the
SocketDigest.

  • pingora-core/src/protocols/tls/mod.rs: client_addr_ex ex_data index + set/get.
  • pingora-core/src/protocols/tls/boringssl_openssl/server.rs: set it before the
    cert callback.
  • pingora-openssl/src/lib.rs: re-export ex_data.

3 files, +42. openssl_derived only.

pigri added 4 commits June 14, 2026 13:14
…L ex_data

Branched off the commit synapse pins (ae2ef10, which has the proxy-protocol
feature) — NOT the regressed main, which lacks proxy_protocol.rs entirely.

The server TLS handshake (handshake_with_callback) now stashes the
PROXY-protocol-recovered client SocketAddr onto the SSL object via a typed
ex_data index, immediately before invoking the certificate_callback. This is
the only handshake hook a consumer can read for HTTP/2 connections (the
SslStream isn't reachable on the h2 request path), so it lets synapse-proxy
correlate the SSL* pointer (== the agent uprobe's ssl_ptr) with the real
external client IP and stamp it on decrypted-HTTP IDS alerts.

- pingora-openssl: re-export ssl_lib::ex_data so Index is nameable downstream.
- pingora-core: new openssl-gated `protocols::tls::client_addr_ex` {set,get}
  sharing one OnceLock ex_data index.
- server.rs: read peer_addr() (recovered) from the socket digest, set it on the
  SSL before the cert callback. No-op when proxy-proto is off / not inet.
client_addr_ex (gated on openssl_derived) uses crate::tls::ex_data, but only
pingora-openssl re-exported it. Mirror the export in pingora-boringssl so the
boringssl backend compiles (cargo check --workspace).
alloc-stdlib 0.2.3 pulls alloc-no-stdlib 3.0.0, which coexists with
brotli/brotli-decompressors 2.0.x as two incompatible Allocator traits and
breaks the build with "StandardAlloc: Allocator not satisfied" on the CI
toolchains (cargo check --workspace). Pin alloc-stdlib 0.2.2 (uses 2.0.4) so a
single alloc-no-stdlib resolves. Verified with rustc 1.91.1.
cargo-machete flags the alloc-stdlib resolver pin as an unused dependency.
It is intentional (constrains alloc-no-stdlib to one version), so add it to
[package.metadata.cargo-machete].ignored.
@pigri pigri merged commit 43d67ec into main Jun 14, 2026
5 checks passed
@pigri pigri deleted the feat/ssl-client-ex-data branch June 14, 2026 17:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant