pub struct TrustedProxies { /* private fields */ }Expand description
Allowlist of reverse-proxy peer addresses whose X-Forwarded-Client-Cert
headers the audit middleware will trust.
§Threat model
XFCC is a header an upstream Envoy / Istio sidecar sets after performing
mTLS termination on behalf of the gateway. Because it is a plain HTTP
header, anything that can open a TCP connection to the gateway can also
claim a Subject=... value. If the gateway forwards that claim into
the audit log unchecked, an attacker on the same L3 segment (or with
access to a misconfigured ingress) can write arbitrary identities into
the audit stream — defeating non-repudiation, poisoning downstream SIEM
tooling, and providing cover for malicious activity attributed to a
fabricated certificate Subject.
The mitigation is layered: only consult XFCC when the immediate TCP
peer (the L4 source IP axum’s listener observed via ConnectInfo) is
in an operator-curated allowlist of proxies known to terminate mTLS.
Everything else has its XFCC header silently dropped. The allowlist is
empty by default so a fresh deployment cannot accidentally trust an
attacker.
§Configuration
Operators populate the allowlist via ENV_TRUSTED_XFCC_PROXIES: a
comma-separated list of IPv4 / IPv6 addresses (127.0.0.1, ::1) or
CIDR ranges (10.0.0.0/8, fd00::/8). Parse failures on individual
entries are logged at warn and the entry is dropped; a fully empty
list (the default) means no peer is trusted.
§Sharing
Clone is intentionally cheap: the inner CIDR list is small and the
per-peer warn-dedup DashSet is wrapped in Arc, so cloning into each
request’s extensions does not duplicate state.
Implementations§
Source§impl TrustedProxies
impl TrustedProxies
Sourcepub fn from_env() -> Self
pub fn from_env() -> Self
Load from ENV_TRUSTED_XFCC_PROXIES.
Unset / empty → empty allowlist (no peer is trusted, every inbound
X-Forwarded-Client-Cert header is dropped). Malformed individual
entries are skipped with a startup tracing::warn! so a typo in
one entry does not poison the whole allowlist.
Sourcepub fn parse(s: &str) -> Self
pub fn parse(s: &str) -> Self
Parse a comma-separated list of IPs / CIDR ranges into an allowlist.
Bare IPs (127.0.0.1, ::1) are normalised into /32 (IPv4) or
/128 (IPv6) host routes so the membership test is uniform across
shapes. Whitespace around individual entries is tolerated.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
true when no peer is trusted (the safe default). When this is
true, Self::contains returns false for every input.
Sourcepub fn contains(&self, ip: IpAddr) -> bool
pub fn contains(&self, ip: IpAddr) -> bool
Membership test: is ip in any of the configured ranges?
Sourcepub fn warn_once_untrusted(&self, peer: IpAddr) -> bool
pub fn warn_once_untrusted(&self, peer: IpAddr) -> bool
Record a warn-level diagnostic exactly once per unique peer that
tried to send X-Forwarded-Client-Cert from outside the allowlist.
Subsequent requests from the same peer are silent. Returns true
if the warn was emitted (the peer was previously unseen).
Trait Implementations§
Source§impl Clone for TrustedProxies
impl Clone for TrustedProxies
Source§fn clone(&self) -> TrustedProxies
fn clone(&self) -> TrustedProxies
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for TrustedProxies
impl Debug for TrustedProxies
Source§impl Default for TrustedProxies
impl Default for TrustedProxies
Source§fn default() -> TrustedProxies
fn default() -> TrustedProxies
Auto Trait Implementations§
impl !RefUnwindSafe for TrustedProxies
impl !UnwindSafe for TrustedProxies
impl Freeze for TrustedProxies
impl Send for TrustedProxies
impl Sync for TrustedProxies
impl Unpin for TrustedProxies
impl UnsafeUnpin for TrustedProxies
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> FutureExt for T
impl<T> FutureExt for T
Source§fn with_context(self, otel_cx: Context) -> WithContext<Self>
fn with_context(self, otel_cx: Context) -> WithContext<Self>
Source§fn with_current_context(self) -> WithContext<Self>
fn with_current_context(self) -> WithContext<Self>
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more