Documentation ¶
Overview ¶
Package proxyproto implements Proxy Protocol (v1 and v2) parser and writer, as per specification: https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt
Index ¶
- Variables
- func JoinTLVs(tlvs []TLV) ([]byte, error)
- func SetReadHeaderTimeout(t time.Duration) func(*Conn)
- func ValidateHeader(v Validator) func(*Conn)
- func WithPolicy(p Policy) func(*Conn)
- type AddressFamilyAndProtocol
- func (ap AddressFamilyAndProtocol) IsDatagram() bool
- func (ap AddressFamilyAndProtocol) IsIPv4() bool
- func (ap AddressFamilyAndProtocol) IsIPv6() bool
- func (ap AddressFamilyAndProtocol) IsStream() bool
- func (ap AddressFamilyAndProtocol) IsUnix() bool
- func (ap AddressFamilyAndProtocol) IsUnspec() bool
- type Conn
- func (p *Conn) Close() error
- func (p *Conn) LocalAddr() net.Addr
- func (p *Conn) ProxyHeader() *Header
- func (p *Conn) Raw() net.Conn
- func (p *Conn) Read(b []byte) (int, error)
- func (p *Conn) ReadFrom(r io.Reader) (int64, error)
- func (p *Conn) RemoteAddr() net.Addr
- func (p *Conn) SetDeadline(t time.Time) error
- func (p *Conn) SetReadDeadline(t time.Time) error
- func (p *Conn) SetWriteDeadline(t time.Time) error
- func (p *Conn) TCPConn() (conn *net.TCPConn, ok bool)
- func (p *Conn) UDPConn() (conn *net.UDPConn, ok bool)
- func (p *Conn) UnixConn() (conn *net.UnixConn, ok bool)
- func (p *Conn) Write(b []byte) (int, error)
- func (p *Conn) WriteTo(w io.Writer) (int64, error)
- type ConnPolicyFunc
- type ConnPolicyOptions
- type Header
- func (header *Header) EqualTo(otherHeader *Header) bool
- func (header *Header) EqualsTo(otherHeader *Header) bool
- func (header *Header) Format() ([]byte, error)
- func (header *Header) IPs() (sourceIP, destIP net.IP, ok bool)
- func (header *Header) Ports() (sourcePort, destPort int, ok bool)
- func (header *Header) SetTLVs(tlvs []TLV) error
- func (header *Header) TCPAddrs() (sourceAddr, destAddr *net.TCPAddr, ok bool)
- func (header *Header) TLVs() ([]TLV, error)
- func (header *Header) UDPAddrs() (sourceAddr, destAddr *net.UDPAddr, ok bool)
- func (header *Header) UnixAddrs() (sourceAddr, destAddr *net.UnixAddr, ok bool)
- func (header *Header) WriteTo(w io.Writer) (int64, error)
- type Listener
- type PP2Type
- type Policy
- type PolicyFunc
- func LaxWhiteListPolicy(allowed []string) (PolicyFunc, error)
- func MustLaxWhiteListPolicy(allowed []string) PolicyFunc
- func MustStrictWhiteListPolicy(allowed []string) PolicyFunc
- func SkipProxyHeaderForCIDR(skipHeaderCIDR *net.IPNet, def Policy) PolicyFunc
- func StrictWhiteListPolicy(allowed []string) (PolicyFunc, error)
- type ProtocolVersionAndCommand
- type TLV
- type Validator
Constants ¶
This section is empty.
Variables ¶
var ( // Protocol SIGV1 = []byte{'\x50', '\x52', '\x4F', '\x58', '\x59'} SIGV2 = []byte{'\x0D', '\x0A', '\x0D', '\x0A', '\x00', '\x0D', '\x0A', '\x51', '\x55', '\x49', '\x54', '\x0A'} ErrCantReadVersion1Header = errors.New("proxyproto: can't read version 1 header") ErrVersion1HeaderTooLong = errors.New("proxyproto: version 1 header must be 107 bytes or less") ErrLineMustEndWithCrlf = errors.New("proxyproto: version 1 header is invalid, must end with \\r\\n") ErrCantReadProtocolVersionAndCommand = errors.New("proxyproto: can't read proxy protocol version and command") ErrCantReadAddressFamilyAndProtocol = errors.New("proxyproto: can't read address family or protocol") ErrCantReadLength = errors.New("proxyproto: can't read length") ErrCantResolveSourceUnixAddress = errors.New("proxyproto: can't resolve source Unix address") ErrCantResolveDestinationUnixAddress = errors.New("proxyproto: can't resolve destination Unix address") ErrNoProxyProtocol = errors.New("proxyproto: proxy protocol signature not present") ErrUnknownProxyProtocolVersion = errors.New("proxyproto: unknown proxy protocol version") ErrUnsupportedProtocolVersionAndCommand = errors.New("proxyproto: unsupported proxy protocol version and command") ErrUnsupportedAddressFamilyAndProtocol = errors.New("proxyproto: unsupported address family and protocol") ErrInvalidLength = errors.New("proxyproto: invalid length") ErrInvalidAddress = errors.New("proxyproto: invalid address") ErrInvalidPortNumber = errors.New("proxyproto: invalid port number") ErrSuperfluousProxyHeader = errors.New("proxyproto: upstream connection sent PROXY header but isn't allowed to send one") )
var ( // DefaultReadHeaderTimeout is how long header processing waits for header to // be read from the wire, if Listener.ReaderHeaderTimeout is not set. // It's kept as a global variable so to make it easier to find and override, // e.g. go build -ldflags -X "github.com/pires/go-proxyproto.DefaultReadHeaderTimeout=1s" DefaultReadHeaderTimeout = 10 * time.Second // ErrInvalidUpstream should be returned when an upstream connection address // is not trusted, and therefore is invalid. ErrInvalidUpstream = fmt.Errorf("proxyproto: upstream connection address not trusted for PROXY information") )
Functions ¶
func SetReadHeaderTimeout ¶ added in v0.8.0
SetReadHeaderTimeout sets the readHeaderTimeout for a connection when passed as option to NewConn()
func ValidateHeader ¶
ValidateHeader adds given validator for proxy headers to a connection when passed as option to NewConn()
func WithPolicy ¶
WithPolicy adds given policy to a connection when passed as option to NewConn()
Types ¶
type AddressFamilyAndProtocol ¶
type AddressFamilyAndProtocol byte
AddressFamilyAndProtocol represents address family and transport protocol.
const ( UNSPEC AddressFamilyAndProtocol = '\x00' TCPv4 AddressFamilyAndProtocol = '\x11' UDPv4 AddressFamilyAndProtocol = '\x12' TCPv6 AddressFamilyAndProtocol = '\x21' UDPv6 AddressFamilyAndProtocol = '\x22' UnixStream AddressFamilyAndProtocol = '\x31' UnixDatagram AddressFamilyAndProtocol = '\x32' )
func (AddressFamilyAndProtocol) IsDatagram ¶
func (ap AddressFamilyAndProtocol) IsDatagram() bool
IsDatagram returns true if the transport protocol is UDP or DGRAM (SOCK_DGRAM), false otherwise.
func (AddressFamilyAndProtocol) IsIPv4 ¶
func (ap AddressFamilyAndProtocol) IsIPv4() bool
IsIPv4 returns true if the address family is IPv4 (AF_INET4), false otherwise.
func (AddressFamilyAndProtocol) IsIPv6 ¶
func (ap AddressFamilyAndProtocol) IsIPv6() bool
IsIPv6 returns true if the address family is IPv6 (AF_INET6), false otherwise.
func (AddressFamilyAndProtocol) IsStream ¶
func (ap AddressFamilyAndProtocol) IsStream() bool
IsStream returns true if the transport protocol is TCP or STREAM (SOCK_STREAM), false otherwise.
func (AddressFamilyAndProtocol) IsUnix ¶
func (ap AddressFamilyAndProtocol) IsUnix() bool
IsUnix returns true if the address family is UNIX (AF_UNIX), false otherwise.
func (AddressFamilyAndProtocol) IsUnspec ¶
func (ap AddressFamilyAndProtocol) IsUnspec() bool
IsUnspec returns true if the transport protocol or address family is unspecified, false otherwise.
type Conn ¶
type Conn struct { ProxyHeaderPolicy Policy Validate Validator // contains filtered or unexported fields }
Conn is used to wrap and underlying connection which may be speaking the Proxy Protocol. If it is, the RemoteAddr() will return the address of the client instead of the proxy address. Each connection will have its own readHeaderTimeout and readDeadline set by the Accept() call.
func NewConn ¶
NewConn is used to wrap a net.Conn that may be speaking the proxy protocol into a proxyproto.Conn
func (*Conn) LocalAddr ¶
LocalAddr returns the address of the server if the proxy protocol is being used, otherwise just returns the address of the socket server. In case an error happens on reading the proxy header the original LocalAddr is returned, not the one from the proxy header even if the proxy header itself is syntactically correct.
func (*Conn) ProxyHeader ¶ added in v0.3.2
ProxyHeader returns the proxy protocol header, if any. If an error occurs while reading the proxy header, nil is returned.
func (*Conn) Raw ¶ added in v0.3.3
Raw returns the underlying connection which can be casted to a concrete type, allowing access to specialized functions.
Use this ONLY if you know exactly what you are doing.
func (*Conn) Read ¶
Read is check for the proxy protocol header when doing the initial scan. If there is an error parsing the header, it is returned and the socket is closed.
func (*Conn) RemoteAddr ¶
RemoteAddr returns the address of the client if the proxy protocol is being used, otherwise just returns the address of the socket peer. In case an error happens on reading the proxy header the original RemoteAddr is returned, not the one from the proxy header even if the proxy header itself is syntactically correct.
func (*Conn) SetDeadline ¶
SetDeadline wraps original conn.SetDeadline
func (*Conn) SetReadDeadline ¶
SetReadDeadline wraps original conn.SetReadDeadline
func (*Conn) SetWriteDeadline ¶
SetWriteDeadline wraps original conn.SetWriteDeadline
func (*Conn) TCPConn ¶ added in v0.3.1
TCPConn returns the underlying TCP connection, allowing access to specialized functions.
Use this ONLY if you know exactly what you are doing.
func (*Conn) UDPConn ¶ added in v0.3.1
UDPConn returns the underlying UDP connection, allowing access to specialized functions.
Use this ONLY if you know exactly what you are doing.
type ConnPolicyFunc ¶ added in v0.8.0
type ConnPolicyFunc func(connPolicyOptions ConnPolicyOptions) (Policy, error)
ConnPolicyFunc can be used to decide whether to trust the PROXY info based on connection policy options. If set, the connecting addresses (remote and local) are passed in as argument.
See below for the different policies.
In case an error is returned the connection is denied.
func IgnoreProxyHeaderNotOnInterface ¶ added in v0.8.0
func IgnoreProxyHeaderNotOnInterface(allowedIP net.IP) ConnPolicyFunc
IgnoreProxyHeaderNotOnInterface retuns a ConnPolicyFunc which can be used to decide whether to use or ignore PROXY headers depending on the connection being made on a specific interface. This policy can be used when the server is bound to multiple interfaces but wants to allow on only one interface.
type ConnPolicyOptions ¶ added in v0.8.0
ConnPolicyOptions contains the remote and local addresses of a connection.
type Header ¶
type Header struct { Version byte Command ProtocolVersionAndCommand TransportProtocol AddressFamilyAndProtocol SourceAddr net.Addr DestinationAddr net.Addr // contains filtered or unexported fields }
Header is the placeholder for proxy protocol header.
func HeaderProxyFromAddrs ¶ added in v0.2.0
HeaderProxyFromAddrs creates a new PROXY header from a source and a destination address. If version is zero, the latest protocol version is used.
The header is filled on a best-effort basis: if hints cannot be inferred from the provided addresses, the header will be left unspecified.
func Read ¶
Read identifies the proxy protocol version and reads the remaining of the header, accordingly.
If proxy protocol header signature is not present, the reader buffer remains untouched and is safe for reading outside of this code.
If proxy protocol header signature is present but an error is raised while processing the remaining header, assume the reader buffer to be in a corrupt state. Also, this operation will block until enough bytes are available for peeking.
func ReadTimeout ¶
ReadTimeout acts as Read but takes a timeout. If that timeout is reached, it's assumed there's no proxy protocol header.
func (*Header) EqualTo ¶
EqualTo returns true if headers are equivalent, false otherwise. Deprecated: use EqualsTo instead. This method will eventually be removed.
func (*Header) SetTLVs ¶ added in v0.2.0
SetTLVs sets the TLVs stored in this header. This method replaces any previous TLV.
func (*Header) TLVs ¶
TLVs returns the TLVs stored into this header, if they exist. TLVs are optional for v2 of the protocol.
type Listener ¶
type Listener struct { Listener net.Listener // Deprecated: use ConnPolicyFunc instead. This will be removed in future release. Policy PolicyFunc ConnPolicy ConnPolicyFunc ValidateHeader Validator ReadHeaderTimeout time.Duration }
Listener is used to wrap an underlying listener, whose connections may be using the HAProxy Proxy Protocol. If the connection is using the protocol, the RemoteAddr() will return the correct client address. ReadHeaderTimeout will be applied to all connections in order to prevent blocking operations. If no ReadHeaderTimeout is set, a default of 200ms will be used. This can be disabled by setting the timeout to < 0.
Only one of Policy or ConnPolicy should be provided. If both are provided then a panic would occur during accept.
type PP2Type ¶
type PP2Type byte
PP2Type is the proxy protocol v2 type
const ( // Section 2.2 PP2_TYPE_ALPN PP2Type = 0x01 PP2_TYPE_AUTHORITY PP2Type = 0x02 PP2_TYPE_CRC32C PP2Type = 0x03 PP2_TYPE_NOOP PP2Type = 0x04 PP2_TYPE_UNIQUE_ID PP2Type = 0x05 PP2_TYPE_SSL PP2Type = 0x20 PP2_SUBTYPE_SSL_VERSION PP2Type = 0x21 PP2_SUBTYPE_SSL_CN PP2Type = 0x22 PP2_SUBTYPE_SSL_CIPHER PP2Type = 0x23 PP2_SUBTYPE_SSL_SIG_ALG PP2Type = 0x24 PP2_SUBTYPE_SSL_KEY_ALG PP2Type = 0x25 PP2_TYPE_NETNS PP2Type = 0x30 // Section 2.2.7, reserved types PP2_TYPE_MIN_CUSTOM PP2Type = 0xE0 PP2_TYPE_MAX_CUSTOM PP2Type = 0xEF PP2_TYPE_MIN_EXPERIMENT PP2Type = 0xF0 PP2_TYPE_MAX_EXPERIMENT PP2Type = 0xF7 PP2_TYPE_MIN_FUTURE PP2Type = 0xF8 PP2_TYPE_MAX_FUTURE PP2Type = 0xFF )
func (PP2Type) App ¶
App is true if the type is reserved for application specific data, see section 2.2.7
func (PP2Type) Experiment ¶
Experiment is true if the type is reserved for temporary experimental use by application developers, see section 2.2.7
func (PP2Type) Registered ¶
Registered is true if the type is registered in the spec, see section 2.2
type Policy ¶
type Policy int
Policy defines how a connection with a PROXY header address is treated.
const ( // USE address from PROXY header USE Policy = iota // IGNORE address from PROXY header, but accept connection IGNORE // REJECT connection when PROXY header is sent // Note: even though the first read on the connection returns an error if // a PROXY header is present, subsequent reads do not. It is the task of // the code using the connection to handle that case properly. REJECT // REQUIRE connection to send PROXY header, reject if not present // Note: even though the first read on the connection returns an error if // a PROXY header is not present, subsequent reads do not. It is the task // of the code using the connection to handle that case properly. REQUIRE // SKIP accepts a connection without requiring the PROXY header // Note: an example usage can be found in the SkipProxyHeaderForCIDR // function. SKIP )
type PolicyFunc ¶
PolicyFunc can be used to decide whether to trust the PROXY info from upstream. If set, the connecting address is passed in as an argument.
See below for the different policies.
In case an error is returned the connection is denied.
func LaxWhiteListPolicy ¶
func LaxWhiteListPolicy(allowed []string) (PolicyFunc, error)
LaxWhiteListPolicy returns a PolicyFunc which decides whether the upstream ip is allowed to send a proxy header based on a list of allowed IP addresses and IP ranges. In case upstream IP is not in list the proxy header will be ignored. If one of the provided IP addresses or IP ranges is invalid it will return an error instead of a PolicyFunc.
func MustLaxWhiteListPolicy ¶
func MustLaxWhiteListPolicy(allowed []string) PolicyFunc
MustLaxWhiteListPolicy returns a LaxWhiteListPolicy but will panic if one of the provided IP addresses or IP ranges is invalid.
func MustStrictWhiteListPolicy ¶
func MustStrictWhiteListPolicy(allowed []string) PolicyFunc
MustStrictWhiteListPolicy returns a StrictWhiteListPolicy but will panic if one of the provided IP addresses or IP ranges is invalid.
func SkipProxyHeaderForCIDR ¶ added in v0.7.0
func SkipProxyHeaderForCIDR(skipHeaderCIDR *net.IPNet, def Policy) PolicyFunc
SkipProxyHeaderForCIDR returns a PolicyFunc which can be used to accept a connection from a skipHeaderCIDR without requiring a PROXY header, e.g. Kubernetes pods local traffic. The def is a policy to use when an upstream address doesn't match the skipHeaderCIDR.
func StrictWhiteListPolicy ¶
func StrictWhiteListPolicy(allowed []string) (PolicyFunc, error)
StrictWhiteListPolicy returns a PolicyFunc which decides whether the upstream ip is allowed to send a proxy header based on a list of allowed IP addresses and IP ranges. In case upstream IP is not in list reading on the connection will be refused on the first read. Please note: subsequent reads do not error. It is the task of the code using the connection to handle that case properly. If one of the provided IP addresses or IP ranges is invalid it will return an error instead of a PolicyFunc.
type ProtocolVersionAndCommand ¶
type ProtocolVersionAndCommand byte
ProtocolVersionAndCommand represents the command in proxy protocol v2. Command doesn't exist in v1 but it should be set since other parts of this library may rely on it for determining connection details.
const ( // LOCAL represents the LOCAL command in v2 or UNKNOWN transport in v1, // in which case no address information is expected. LOCAL ProtocolVersionAndCommand = '\x20' // PROXY represents the PROXY command in v2 or transport is not UNKNOWN in v1, // in which case valid local/remote address and port information is expected. PROXY ProtocolVersionAndCommand = '\x21' )
func (ProtocolVersionAndCommand) IsLocal ¶
func (pvc ProtocolVersionAndCommand) IsLocal() bool
IsLocal returns true if the command in v2 is LOCAL or the transport in v1 is UNKNOWN, i.e. when no address information is expected, false otherwise.
func (ProtocolVersionAndCommand) IsProxy ¶
func (pvc ProtocolVersionAndCommand) IsProxy() bool
IsProxy returns true if the command in v2 is PROXY or the transport in v1 is not UNKNOWN, i.e. when valid local/remote address and port information is expected, false otherwise.
func (ProtocolVersionAndCommand) IsUnspec ¶
func (pvc ProtocolVersionAndCommand) IsUnspec() bool
IsUnspec returns true if the command is unspecified, false otherwise.