Documentation
¶
Overview ¶
Package clientip resolves the client address recorded in the request logs and access logs. It lives here rather than in s3api/utils so the standalone IAM and WebUI servers can use it without importing the S3 side.
Index ¶
- Constants
- func ClientIP(ctx fiber.Ctx) string
- func ClientIPFromHeader(ctx fiber.Ctx, header string, trusted TrustedProxies) string
- func Middleware(header string, trusted TrustedProxies) fiber.Handler
- func NormalizeClientIPHeader(header string) (string, error)
- func Tag(output logger.Buffer, ctx fiber.Ctx, _ *logger.Data, _ string) (int, error)
- type TrustedProxies
Constants ¶
const ( ClientIPHeaderForwardedFor = "X-Forwarded-For" ClientIPHeaderRealIP = "X-Real-Ip" )
Proxy headers the client address can be read from when the operator opts in with the client-ip-header option.
Variables ¶
This section is empty.
Functions ¶
func ClientIP ¶
ClientIP returns the address to record for a request. The client IP middleware stores the address resolved from the configured proxy header; without it this is the socket peer address from ctx.IP().
func ClientIPFromHeader ¶
func ClientIPFromHeader(ctx fiber.Ctx, header string, trusted TrustedProxies) string
ClientIPFromHeader resolves the client address from header. The header is only honoured when the connection peer is one of the configured trusted proxies; from any other peer it is ignored and the socket peer address is returned, so a client cannot choose the address that gets logged.
X-Forwarded-For is a comma-separated chain, oldest hop first. It is walked right to left, skipping the trusted proxies that appended to it; the first address that is not a trusted proxy is the client. A proxy may also add its own header line instead of appending to the existing one, so every line is walked, last line first. Some proxies write "ip:port" entries, which are accepted too. X-Real-Ip carries a single address; when a proxy adds a line rather than replacing the client's, the last line is the proxy's, so the last line is the one read.
When every hop is a trusted proxy — a deployment whose trusted-proxies is the ingress pod CIDR, say — the leftmost hop is returned, as nginx's real_ip_recursive does. The socket peer would otherwise be the nearest proxy, which is never the client. It is no less safe than stopping at an untrusted hop: a trusted peer can already choose the logged address by putting any untrusted address on the left.
Any unusable entry falls back to the socket peer address rather than returning a value from further up the chain.
func Middleware ¶
func Middleware(header string, trusted TrustedProxies) fiber.Handler
Middleware resolves the client address for logging from the given proxy header, honouring it only when the connection peer is a trusted proxy, and stores it in the request context. Requests from an untrusted peer, or with no usable header value, keep the socket peer address.
func NormalizeClientIPHeader ¶
NormalizeClientIPHeader validates a configured client IP header and returns its canonical spelling. An empty value means the option is disabled.
Types ¶
type TrustedProxies ¶
type TrustedProxies struct {
// Prefixes holds the trusted IP addresses and CIDR prefixes.
Prefixes []netip.Prefix
// Unix trusts a peer that connected over a unix domain socket. fasthttp
// reports such a peer as 0.0.0.0, which only a prefix covering 0.0.0.0
// (0.0.0.0/32, 0.0.0.0/0) matches, so without this entry a proxy on a
// unix socket listener is not trusted.
Unix bool
}
TrustedProxies is the set of peers whose forwarding headers are honoured.
func ParseTrustedProxies ¶
func ParseTrustedProxies(list string) (TrustedProxies, error)
ParseTrustedProxies parses a comma-separated list of IP addresses, CIDR prefixes and the literal "unix" into the set of peers whose forwarding headers are trusted. The "unix" entry trusts a peer connected over a unix domain socket; an empty list yields an empty set.
func (TrustedProxies) IsEmpty ¶
func (t TrustedProxies) IsEmpty() bool
IsEmpty reports whether no peer is trusted.