Documentation
¶
Overview ¶
Package trustedproxy takes a client's address from the proxy in front of Atlas, and from nobody else (ADR-0448).
Behind a load balancer every connection comes from the balancer. The login throttle then charges every person to one bucket (ADR-0197), and every audit line names the balancer as the client — the one fact about a request an audit trail exists to keep. The balancer knows the real address and can say so, in one of two ways depending on what it is:
- A balancer that speaks HTTP appends it to X-Forwarded-For.
- A balancer that forwards TCP — and so cannot add a header to a TLS stream it does not decrypt — writes a PROXY protocol header in front of the stream.
Both are things a client can also write. What makes either believable is the connection it arrived on, so both are read only on a connection from an address the operator listed, and from the side the nearest proxy controls: the PROXY header must be the very first bytes, and X-Forwarded-For is walked from the right. A connection from anywhere else is left exactly as it was — its first bytes are not even peeked at.
An empty Set, which is what a server started without --trusted-proxies has, changes nothing at all: Listener returns the listener and Handler the handler.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Client ¶
Client is the client address a trusted proxy vouched for, and whether one did. Where none did, the request's own connection is the answer, and the caller reads it there.
func ConnContext ¶
ConnContext is the http.Server hook that lets the handler see through a PROXY header to the balancer that wrote it. It only records the connection — reading the header can wait for a client, and this runs on the server's accept loop, which must not.
Types ¶
type Set ¶
type Set struct {
// contains filtered or unexported fields
}
Set is the proxies whose word about a client's address is taken.
func Parse ¶
Parse reads a list of addresses and CIDR prefixes, separated by commas or spaces. An address is the prefix of its own full length.
A prefix that covers every address is refused: trusting everybody to name the client is trusting the client to name itself, which is the one thing the list exists to rule out. Anything that does not parse is refused too, rather than dropped — a list that silently lost an entry trusts less than its operator believes, and one that silently grew would trust more.
func (Set) Contains ¶
Contains reports whether a is one of the trusted proxies. An IPv4 address carried in IPv6 is the IPv4 address. One with a zone is never trusted: fe80::1 on one interface is not fe80::1 on another, and the list cannot say which interface it meant.
func (Set) Handler ¶
Handler resolves each request's client address before next sees it.
The request's own RemoteAddr is the starting point — after the PROXY listener that is already the client a balancer declared. Where that address is itself a trusted proxy, X-Forwarded-For is walked from the right: each entry a trusted proxy appended is passed over, and the first one that is not a trusted proxy is the client. Everything to its left is what the client wrote about itself and is never read. An entry that cannot be read ends the walk where it stands, because past it there is nothing left that a trusted hop vouched for.
Only X-Forwarded-For is read. RFC 7239's Forwarded carries the same fact in a grammar no balancer in front of Atlas has needed yet; it is an amendment when one does.