Documentation
¶
Overview ¶
Package hostutil provides pure host-string normalization helpers shared across the proxy (policy matching, category lookups, scan/bypass keys). It is a self-contained seam (stdlib + golang.org/x/net/idna, no Culvert coupling) extracted from package main per ADR-0002 / ADR-0003 to unblock the catdb and scan clusters, which both depend on these helpers.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func MatchFQDN ¶ added in v1.0.19
MatchFQDN reports whether host matches pattern under the proxy's canonical FQDN-glob semantics, normalizing both inputs first. Moved from package main's policy engine (ADR-0002, policy.go decomposition Phase B) — shared by policy rule matching and the SSL-bypass matcher, whose agreement is pinned by main's policy_bypass_security_test.go.
func MatchFQDNNorm ¶ added in v1.0.19
MatchFQDNNorm is MatchFQDN's core, operating on inputs that are ALREADY IDNA-normalized. The policy hot path passes a once-normalized host and a rule's precomputed normalized pattern, avoiding the two per-rule NormalizeHost allocations.
func NormalizeHost ¶
NormalizeHost applies IDNA2008 normalization (RFC 5890) to a hostname, converting Unicode/Punycode domains to their canonical ASCII form. This prevents IDN homograph attacks where visually similar Unicode characters (e.g., Cyrillic 'а' vs Latin 'a') bypass blocklists and policy rules.
Returns the lowercased, IDNA-normalized host. If normalization fails the input is returned lowercased — fail-open, which is acceptable ONLY for canonicalizing admin-entered patterns and store keys (a pattern that fails IDNA simply matches literally, so nothing is admitted that a valid pattern would have blocked). Request-path host validation must use NormalizeHostStrict so a malformed host is REJECTED, not passed through (RISK-013).
func NormalizeHostStrict ¶ added in v1.0.32
NormalizeHostStrict is NormalizeHost's fail-closed core: it reports ok=false when IDNA conversion fails instead of falling back to the raw input. Security gates on the request path (proxy dispatch, SOCKS5) use it to reject hosts that cannot be canonicalized — a host the normalizer cannot map to canonical ASCII would otherwise flow into FQDN/blocklist/ category matching un-normalized, and a fail-open in the canonicalization step is exactly the asymmetry evasion techniques target (RISK-013). Empty input returns ok=true: emptiness is a separate upstream validity concern, and rejecting it here would change unrelated dispatch behavior.
func StripHostPort ¶
StripHostPort removes a trailing :port and IPv6 brackets from a host value, accepting all shapes that reach scan/bypass lookups: "host:port", "[v6]:port", "[v6]", bare "v6", and bare "host". A naive LastIndex(host, ":") cut corrupts bare IPv6 literals (already de-bracketed by net.SplitHostPort upstream) — "2001:db8::1" would become "2001:db8:".
Types ¶
This section is empty.