Help us shape the future of Go! Take the 2026 Go Developer Survey

clientaddr

package
v0.29.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 29, 2026 License: MIT Imports: 6 Imported by: 0

Documentation

Overview

Package clientaddr finds the address of the client behind a request: the one rule SystemAuth, the BFF, appauth and rate limiting share.

A request's direct peer (http.Request.RemoteAddr) is the only address a client cannot choose. Behind reverse proxies the peer is the proxy, and the client's address is in a header the proxy writes. A Resolver believes that header only when the direct peer is one of the trusted proxy networks; from any other peer the header is ignored, because a client can send it too.

Two kinds of header are supported:

  • X-Forwarded-For (the default): a list each proxy appends the peer it saw to. The Resolver reads it from the right, skipping trusted proxy addresses, and takes the first address no trusted proxy vouched for. A client can write anything at the left of the list, but not past the proxy that appends to it.
  • A single-value header, such as CF-Connecting-IP, True-Client-IP or X-Real-IP, which the trusted proxy sets to one address.

A typical deployment has a CDN or edge proxy, then a reverse proxy on the host that sets X-Forwarded-For to the address it took from the edge, then the application on loopback. There the trusted networks are loopback (see LoopbackProxy) and the header is X-Forwarded-For.

Index

Constants

View Source
const (
	HeaderCFConnectingIP = "CF-Connecting-IP"
	HeaderTrueClientIP   = "True-Client-IP"
	HeaderXRealIP        = "X-Real-IP"
)

Named single-value headers, for Config.Header.

View Source
const HeaderXForwardedFor = "X-Forwarded-For"

HeaderXForwardedFor is the list header read by default.

Variables

View Source
var LoopbackNetworks = []string{"127.0.0.0/8", "::1/128"}

LoopbackNetworks are the IPv4 and IPv6 loopback networks: the addresses a reverse proxy on the same host connects from.

Functions

func ParseNetworks

func ParseNetworks(networks []string) ([]netip.Prefix, error)

ParseNetworks parses networks in CIDR notation or single addresses (taken as /32 or /128). IPv4-mapped IPv6 networks are unmapped.

func PeerAddr

func PeerAddr(req *http.Request) (netip.Addr, bool)

PeerAddr returns the address of the request's direct peer, with the port and any IPv6 zone removed and IPv4-mapped IPv6 addresses unmapped. It reports false when RemoteAddr is not an address.

func PeerIP

func PeerIP(req *http.Request) string

PeerIP returns the direct peer's address as a string, or "" when RemoteAddr is not an address.

Types

type Config

type Config struct {
	// TrustedProxies are the networks, in CIDR notation or as single
	// addresses, of the proxies whose header is believed. A request from
	// any other peer is attributed to the peer.
	TrustedProxies []string `` /* 237-byte string literal not displayed */

	// Header is the header the trusted proxies write the client's address
	// to: X-Forwarded-For (the default), read from the right, or a
	// single-value header such as CF-Connecting-IP or X-Real-IP.
	Header string `` /* 240-byte string literal not displayed */
}

Config says which proxies to believe and which header they write. The zero Config trusts no proxy: every request is attributed to its direct peer.

func LoopbackProxy

func LoopbackProxy() Config

LoopbackProxy is the Config for a reverse proxy on the same host that sets X-Forwarded-For.

func (Config) IsZero

func (c Config) IsZero() bool

IsZero reports whether the Config trusts no proxy.

func (Config) Validate

func (c Config) Validate() error

Validate reports whether the networks and the header are well formed.

type Resolver

type Resolver struct {
	// contains filtered or unexported fields
}

Resolver finds a request's client address. A nil *Resolver, like the zero Config, attributes every request to its direct peer.

func MustNew

func MustNew(cfg Config) *Resolver

MustNew is New for configurations known to be valid, such as literals. It panics on an invalid Config.

func New

func New(cfg Config) (*Resolver, error)

New builds a Resolver from cfg. A Header without TrustedProxies is an error: it would never be read, which is almost always a mistake in the configuration.

func Peer

func Peer() *Resolver

Peer returns a Resolver that trusts no proxy.

func (*Resolver) Addr

func (r *Resolver) Addr(req *http.Request) (netip.Addr, bool)

Addr returns the request's client address. It reports false only when the direct peer's address cannot be parsed.

func (*Resolver) ClientIP

func (r *Resolver) ClientIP(req *http.Request) string

ClientIP returns the request's client address as a string, or "" when the direct peer's address cannot be parsed.

func (*Resolver) FromHeader

func (r *Resolver) FromHeader(req *http.Request) (netip.Addr, bool)

FromHeader returns the client address the trusted proxy's header names, and false when the peer is not trusted or the header names nothing usable, so callers can try other sources before the peer.

func (*Resolver) Header

func (r *Resolver) Header() string

Header is the header the Resolver reads from trusted proxies, in canonical form (http.CanonicalHeaderKey), or "" when it trusts none.

func (*Resolver) Trusted

func (r *Resolver) Trusted(addr netip.Addr) bool

Trusted reports whether addr is in one of the trusted proxy networks.

func (*Resolver) TrustsPeer

func (r *Resolver) TrustsPeer(req *http.Request) bool

TrustsPeer reports whether the request's direct peer is a trusted proxy.

func (*Resolver) TrustsProxies

func (r *Resolver) TrustsProxies() bool

TrustsProxies reports whether any proxy network is trusted.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL