Skip to content

pires/go-proxyproto

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

269 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

go-proxyproto

Actions Status Coverage Status Go Report Card

A Go library implementation of the PROXY protocol, versions 1 and 2, which provides, as per specification:

(...) a convenient way to safely transport connection information such as a client's address across multiple layers of NAT or TCP proxies. It is designed to require little changes to existing components and to limit the performance impact caused by the processing of the transported information.

This library is to be used in one of or both proxy clients and proxy servers that need to support said protocol. Both protocol versions, 1 (text-based) and 2 (binary-based) are supported.

Installation

$ go get -u github.com/pires/go-proxyproto

Examples

The fastest way to get started is the runnable programs under examples/ and the API examples on pkg.go.dev:

Goal Where to look
Minimal client examples/client
Minimal server examples/server
HTTP server examples/httpserver
Server + client over TLS (PROXY header before TLS) examples/tlsserver, examples/tlsclient
Listener options: timeout, buffer size, policy, validation ExampleListener_*
NewConn options ExampleNewConn_*
PROXY over TLS, both wrapping orders ExampleListener_tls, ExampleListener_tlsHeaderInsideTLS

Usage

Use the full runnable examples above for complete programs. The core API shape is small:

Client side

header := proxyproto.HeaderProxyFromAddrs(1, sourceAddr, destinationAddr)
_, err := header.WriteTo(conn) // write the PROXY header before application data

See examples/client for a complete TCP client.

Server side

proxyListener := &proxyproto.Listener{Listener: ln}
conn, err := proxyListener.Accept()
// conn.RemoteAddr() now reports the client address from the PROXY header, when present.

See examples/server for a complete TCP server. For HTTP/1 and HTTP/2, see examples/httpserver, which uses helper/http2 so one server can accept proxied HTTP/1 and HTTP/2 connections.

TLS

When combining the PROXY protocol with TLS, choose the wrapping order based on where the upstream puts the PROXY header relative to the TLS handshake:

  • Header in cleartext, before the handshake: proxyproto reads the header first, so it goes inside the TLS listener: tls.NewListener(&proxyproto.Listener{Listener: l}, tlsConfig).
  • Header inside the TLS session, after the handshake: TLS decrypts first, so proxyproto wraps the TLS listener: &proxyproto.Listener{Listener: tls.NewListener(l, tlsConfig)}.

In both cases conn.RemoteAddr() reports the client carried by the PROXY header. Runnable code lives in examples/tlsserver and examples/tlsclient; the API examples ExampleListener_tls and ExampleListener_tlsHeaderInsideTLS show both orderings.

Special notes

AWS

AWS Network Load Balancer (NLB) does not push the PPV2 header until the client starts sending the data. This is a problem if your server speaks first. e.g. SMTP, FTP, SSH etc.

By default, NLB target group attribute proxy_protocol_v2.client_to_server.header_placement has the value on_first_ack_with_payload. You need to contact AWS support to change it to on_first_ack, instead.

Just to be clear, you need this fix only if your server is designed to speak first.

About

A Go library implementation of the PROXY protocol, versions 1 and 2.

Topics

Resources

License

Stars

612 stars

Watchers

9 watching

Forks

Sponsor this project

 

Packages

 
 
 

Contributors

Languages