Expand description
The client-IP extraction from the forwarded chain: the reference
_utils/ip_extraction.py’s depth-limited X-Forwarded-For walk, driven
by the trusted_proxies / trusted_proxy_depth knobs.
Semantics, mirroring _resolve_client_ip_from_forwarded_chain exactly:
no header: the connecting peer is the client
chain shorter than the depth: the connecting peer (warn once)
right side holds unlisted peers: walk right to left, skip trusted
entries, first untrusted wins (warn)
otherwise: the entry `depth` from the right,
port-stripped and canonicalizedA selected entry that is itself on the trusted list surfaces the
over-declared-depth warning as data (ChainWarnings) - the engine
has no logger, so the once-only warnings ride the result for the
caller to log. Unparseable entries and metacharacter candidates
(*?[]\) resolve back to the connecting peer, never to a spoof.
§Example
use guard_core_engine::ip_extraction::{extract_client_ip, ClientIpSource};
// A trusted proxy's claim is honored one hop deep.
let extraction = extract_client_ip(
Some("10.0.0.1"),
Some("203.0.113.7"),
&["10.0.0.0/8".to_owned()],
1,
);
assert_eq!(extraction.client_ip, "203.0.113.7");
assert_eq!(extraction.source, ClientIpSource::ForwardedChain);
// An untrusted peer's header is ignored (the spoof signal rides along).
let extraction = extract_client_ip(
Some("192.0.2.9"),
Some("203.0.113.7"),
&["10.0.0.0/8".to_owned()],
1,
);
assert_eq!(extraction.client_ip, "192.0.2.9");
assert!(extraction.untrusted_forwarded_header);
// No trusted proxies at all: the header never decides.
let extraction = extract_client_ip(Some("192.0.2.9"), Some("203.0.113.7"), &[], 1);
assert_eq!(extraction.client_ip, "192.0.2.9");
assert_eq!(extraction.source, ClientIpSource::Connecting);Structs§
- Chain
Warnings - The once-only warnings the reference logs, surfaced as data (the engine has no logger; the caller logs and de-duplicates).
- Client
IpExtraction - One extraction: the identity plus where it came from and what the caller should log.
- Client
Resolution - One request’s client resolution: the identity the pipeline runs under
and whether
fail_securerejects the request outright.
Enums§
- Client
IpSource - Where the extracted client identity came from (the reference
extract_client_ip’s arms).
Constants§
- UNKNOWN_
CLIENT_ IDENTITY - The reference
UNKNOWN_CLIENT_IDENTITY: the identity a request with no connecting peer carries. - UNRESOLVABLE_
CLIENT_ ADDRESS_ CHECK_ NAME - The check name the rejection reports to the
on_blockhook (UNRESOLVABLE_CLIENT_ADDRESS_CHECK_NAME). - UNRESOLVABLE_
CLIENT_ ADDRESS_ MESSAGE - The body of the missing-client-address rejection.
- UNRESOLVABLE_
CLIENT_ ADDRESS_ STATUS - The status of the missing-client-address rejection (the reference
BypassHandler.handle_passthrough403).
Functions§
- candidate_
has_ metachar _forwarded_header_candidate_has_metachar.- canonical_
ip_ text _canonical_ip_text.- canonicalize_
ip _canonicalize_ip: canonical text for a parseable address (an IPv4-mapped IPv6 collapses to its IPv4 text), the raw value otherwise.- extract_
client_ ip extract_client_ip: the reference entry point.client_hostis the connecting peer (Nonefor a socket connection);forwarded_forthe rawX-Forwarded-Forheader.- forwarded_
header_ ips _forwarded_header_ips: the entries, comma-split, port-stripped.- is_
trusted_ proxy _proxy_matches/_is_trusted_proxy.- resolve_
client - The reference client resolution an adapter runs per request.
- resolve_
client_ ip_ from_ forwarded_ chain _resolve_client_ip_from_forwarded_chain: the depth-limited walk with the warnings as data. Failures and short chains degrade to the connecting identity, never to a header claim.- strip_
forwarded_ entry_ port _strip_forwarded_entry_port:[v6]:portandhost:portlose the port; anything else passes through untouched.