• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..03-May-2022-

.github/workflows/H04-Mar-2021-

tlvparse/H04-Mar-2021-

.gitignoreH A D04-Mar-2021111

LICENSEH A D04-Mar-202111.1 KiB

README.mdH A D04-Mar-20213.6 KiB

addr_proto.goH A D04-Mar-20211.9 KiB

addr_proto_test.goH A D04-Mar-20211.6 KiB

go.modH A D04-Mar-202147

header.goH A D04-Mar-20219 KiB

header_test.goH A D04-Mar-202117.2 KiB

policy.goH A D04-Mar-20214.4 KiB

policy_test.goH A D04-Mar-20214.6 KiB

protocol.goH A D04-Mar-20216.7 KiB

protocol_test.goH A D04-Mar-202121.8 KiB

tlv.goH A D04-Mar-20213.6 KiB

tlv_test.goH A D04-Mar-20214.8 KiB

v1.goH A D04-Mar-20216.8 KiB

v1_test.goH A D04-Mar-20218 KiB

v2.goH A D04-Mar-20217.3 KiB

v2_test.goH A D04-Mar-202114.3 KiB

version_cmd.goH A D04-Mar-20211.5 KiB

version_cmd_test.goH A D04-Mar-2021745

README.md

1# go-proxyproto
2
3[![Actions Status](https://github.com/pires/go-proxyproto/workflows/test/badge.svg)](https://github.com/pires/go-proxyproto/actions)
4[![Coverage Status](https://coveralls.io/repos/github/pires/go-proxyproto/badge.svg?branch=master)](https://coveralls.io/github/pires/go-proxyproto?branch=master)
5[![Go Report Card](https://goreportcard.com/badge/github.com/pires/go-proxyproto)](https://goreportcard.com/report/github.com/pires/go-proxyproto)
6[![](https://godoc.org/github.com/pires/go-proxyproto?status.svg)](https://pkg.go.dev/github.com/pires/go-proxyproto?tab=doc)
7
8
9A Go library implementation of the [PROXY protocol, versions 1 and 2](https://www.haproxy.org/download/2.3/doc/proxy-protocol.txt),
10which provides, as per specification:
11> (...) a convenient way to safely transport connection
12> information such as a client's address across multiple layers of NAT or TCP
13> proxies. It is designed to require little changes to existing components and
14> to limit the performance impact caused by the processing of the transported
15> information.
16
17This library is to be used in one of or both proxy clients and proxy servers that need to support said protocol.
18Both protocol versions, 1 (text-based) and 2 (binary-based) are supported.
19
20## Installation
21
22```shell
23$ go get -u github.com/pires/go-proxyproto
24```
25
26## Usage
27
28### Client
29
30```go
31package main
32
33import (
34	"io"
35	"log"
36	"net"
37
38	proxyproto "github.com/pires/go-proxyproto"
39)
40
41func chkErr(err error) {
42	if err != nil {
43		log.Fatalf("Error: %s", err.Error())
44	}
45}
46
47func main() {
48	// Dial some proxy listener e.g. https://github.com/mailgun/proxyproto
49	target, err := net.ResolveTCPAddr("tcp", "127.0.0.1:2319")
50	chkErr(err)
51
52	conn, err := net.DialTCP("tcp", nil, target)
53	chkErr(err)
54
55	defer conn.Close()
56
57	// Create a proxyprotocol header or use HeaderProxyFromAddrs() if you
58	// have two conn's
59	header := &proxyproto.Header{
60		Version:            1,
61		Command:            proxyproto.PROXY,
62		TransportProtocol:  proxyproto.TCPv4,
63		SourceAddr: &net.TCPAddr{
64			IP:   net.ParseIP("10.1.1.1"),
65			Port: 1000,
66		},
67		DestinationAddr: &net.TCPAddr{
68			IP:   net.ParseIP("20.2.2.2"),
69			Port: 2000,
70		},
71	}
72	// After the connection was created write the proxy headers first
73	_, err = header.WriteTo(conn)
74	chkErr(err)
75	// Then your data... e.g.:
76	_, err = io.WriteString(conn, "HELO")
77	chkErr(err)
78}
79```
80
81### Server
82
83```go
84package main
85
86import (
87	"log"
88	"net"
89
90	proxyproto "github.com/pires/go-proxyproto"
91)
92
93func main() {
94	// Create a listener
95	addr := "localhost:9876"
96	list, err := net.Listen("tcp", addr)
97	if err != nil {
98		log.Fatalf("couldn't listen to %q: %q\n", addr, err.Error())
99	}
100
101	// Wrap listener in a proxyproto listener
102	proxyListener := &proxyproto.Listener{Listener: list}
103	defer proxyListener.Close()
104
105	// Wait for a connection and accept it
106	conn, err := proxyListener.Accept()
107	defer conn.Close()
108
109	// Print connection details
110	if conn.LocalAddr() == nil {
111		log.Fatal("couldn't retrieve local address")
112	}
113	log.Printf("local address: %q", conn.LocalAddr().String())
114
115	if conn.RemoteAddr() == nil {
116		log.Fatal("couldn't retrieve remote address")
117	}
118	log.Printf("remote address: %q", conn.RemoteAddr().String())
119}
120```
121
122## Special notes
123
124### AWS
125
126AWS 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.
127
128By 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.
129
130Just to be clear, you need this fix only if your server is designed to speak first.
131