go-proxyproto

A Go library that implements the HAProxy PROXY protocol (v1 and v2) for TCP, Unix, and UDP listeners.

Library
Go
vv0.15.0
620stars
Apache License 2.0

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
81/100Excellent
Development Activity92
Maintenance72
Community72
Maturity60
Momentum28

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture85
Code Quality88
Innovation68
Learning Curve80

go-proxyproto is a Go implementation of the HAProxy PROXY protocol specification, covering both the text-based version 1 and the binary version 2 formats. It preserves the original client connection information (source and destination address, port, and transport) as traffic crosses NAT gateways, load balancers, and other proxy layers that would otherwise present every connection as coming from the proxy itself.

The library wraps a standard net.Listener with proxyproto.Listener so accepted connections report the real client address transparently to existing code, and it exposes lower-level Header, Read, and ParseUDPDatagram APIs for writing headers, parsing them out of band, or handling UDP datagrams where each packet must carry its own header. Trust is explicit: policies (REQUIRE, USE, IGNORE, REJECT, SKIP) and CIDR-based trusted-source helpers decide which upstreams are allowed to supply proxy information, since anyone permitted to send a header can spoof the address it carries.

What You Get

  • A drop-in net.Listener wrapper (proxyproto.Listener) that transparently unwraps PROXY headers so conn.RemoteAddr() returns the real client address
  • Support for both PROXY protocol v1 (text) and v2 (binary), including TLVs and vendor-specific extensions (AWS, Azure, GCP, SSL/TLS TLVs) via the tlvparse subpackage
  • Configurable trust policies (REQUIRE, USE, IGNORE, REJECT, SKIP) plus CIDR-range helpers like TrustProxyHeaderFromRanges to restrict which upstreams may supply proxy headers
  • Dedicated UDP helpers (ParseUDPDatagram, Header.FormatUDPDatagram) since PROXY protocol over UDP requires the header to be parsed independently from every datagram
  • An HTTP/1 and HTTP/2 helper package (helper/http2) that lets a single server accept both PROXY-wrapped protocols behind the same listener
  • Runnable example programs for client, server, HTTP server, TLS client/server, and UDP client/server usage under examples/

Common Use Cases

  • Recovering the real client IP at a Go TCP or HTTP server sitting behind AWS/GCP/Azure load balancers or HAProxy/Envoy proxies
  • Chaining PROXY protocol with TLS termination, in either order, so client address information survives alongside encryption
  • Building multi-protocol edge servers that must accept both PROXY-wrapped HTTP/1 and HTTP/2 traffic on one listener
  • Implementing UDP-based services (e.g. DNS, syslog relays) that need per-datagram client address recovery under PROXY protocol v2
  • Restricting which upstream proxies are trusted to supply client addresses, to prevent IP spoofing on internet-facing listeners

Under The Hood

Architecture go-proxyproto is organized as a flat, single-purpose package (proxyproto) built around three layers: header parsing/writing (header.go, v1.go, v2.go) implements the wire format for both protocol versions; policy.go defines the trust model (PolicyFunc/ConnPolicyFunc, the USE/IGNORE/REJECT/REQUIRE/SKIP enum, and CIDR-based TrustProxyHeaderFromRanges helpers) that decides whether an upstream’s header is honored; and protocol.go ties them together in Listener and Conn, which wrap a net.Listener/net.Conn so RemoteAddr() transparently reflects the client address once the header is read. UDP is deliberately kept out of the stream-oriented Listener/Conn types (udp.go exposes ParseUDPDatagram and Header.FormatUDPDatagram instead) because the spec requires a header in every datagram rather than once per connection, and a subpackage (tlvparse) isolates vendor-specific TLV decoding (AWS, Azure, GCP, SSL) from the core header logic. A separate helper/http2 subpackage layers HTTP/1 and HTTP/2 support on top via an internal pipeListener, keeping HTTP-specific concerns out of the core protocol implementation. Read/write paths are timeout-bound (ReadHeaderTimeout, default 10s) so a single slow or malicious connection cannot indefinitely hold a goroutine during header detection.

Tech Stack The library targets Go 1.25 and depends on only golang.org/x/net (for HTTP/2 support in the helper package) plus its indirect golang.org/x/text dependency — the core protocol implementation itself uses only the Go standard library (net, bufio, sync/atomic, time). It has no runtime framework dependency; it is designed to wrap the standard net.Listener/net.Conn interfaces directly so it drops into any existing TCP, Unix-socket, or HTTP server. CI runs against Go 1.25 and 1.26 via GitHub Actions, and releases are tagged directly against the module’s semantic version.

Code Quality The project has extensive test coverage: dedicated _test.go files for every wire-format and policy source file (header, v1, v2, policy, udp, tlv, addr_proto), package-level example tests (example_conn_test.go, example_listener_test.go, example_tls_test.go, example_udp_test.go) that double as documentation, and a fuzz_test.go exercising the parser against malformed input. Errors are explicit sentinel values (errors.New, wrapped with ErrInvalidUpstream) rather than panics, except for one intentional panic guarding a caller-configuration mistake (setting both Policy and ConnPolicy). Linting is enforced via golangci-lint with an above-default linter set (gosec, bodyclose, revive, misspell, unconvert, and more) run in CI on every push and pull request, alongside go vet and go fmt checks.

What Makes It Unique Unlike libraries that only parse a PROXY header once per connection, go-proxyproto explicitly separates connection-oriented and datagram-oriented handling — UDP support is a distinct API (ParseUDPDatagram/FormatUDPDatagram) rather than an awkward fit forced into the same Listener abstraction, reflecting a close reading of where the specification’s per-datagram requirement diverges from typical stream semantics. Its trust model is unusually explicit for a networking library: rather than assuming a header should always be honored, it documents the spoofing risk directly in the API (REQUIRE still honors headers from any peer) and ships CIDR-based helpers so operators can restrict trust to known proxy ranges without writing custom policy functions. Bundled TLV parsers for AWS, Azure, and GCP vendor extensions, plus a dedicated AWS Network Load Balancer caveat documented directly in the README (the on_first_ack_with_payload timing issue for server-first protocols), show the maintainers tracking real deployment friction beyond the base spec.

Used by 7 apps in this directory

Python
55%
Other

authentik

Authentication · Security

25,245

The self-hosted Identity Provider that replaces Okta, Auth0, and Entra ID with a unified SSO platform supporting SAML, OAuth2/OIDC, LDAP, RADIUS, and WebAuthn.

View details
92
Repo Health
81
Technical
67
Dependency
Built with
Python55%
TypeScript34%
Updated today
Go
98%
Apache 2.0

Caddy

Devops · Security

75,334

The only web server that obtains and renews TLS certificates automatically, with HTTP/1-2-3 support and zero dependency on external runtimes.

View details
92
Repo Health
86
Technical
76
Dependency
Built with
Go98%
Updated 2 days ago
Go
83%
Apache 2.0

frp

Networking

109,098

A fast reverse proxy that exposes local servers behind NAT or firewalls to the public internet with multi-protocol support.

View details
95
Repo Health
82
Technical
71
Dependency
Built with
Go83%
Vue12%
Updated yesterday
Go
94%
Other

NetBird

Security

28,735

Replace your VPN with a zero-trust WireGuard overlay network that auto-connects devices, enforces SSO and posture checks, and deploys in under 5 minutes.

View details
92
Repo Health
82
Technical
66
Dependency
Built with
Go94%
Updated today
Go
63%
GPL 3.0

Stormkit

Devops · Hosting Control Panel

255

Self-hostable platform for deploying and hosting modern web apps with automated CI/CD, custom domains, and a built-in serverless runtime — a true open-source alternative to Vercel and Netlify.

View details
78
Repo Health
79
Technical
68
Dependency
Built with
Go63%
TypeScript34%
Updated 2 days ago
Go
93%
MIT

Traefik

Devops · Automation · Security

64,662

A cloud-native reverse proxy and load balancer that auto-configures itself from Docker, Kubernetes, and other orchestrators — zero manual routing required.

View details
93
Repo Health
85
Technical
65
Dependency
Built with
Go93%
Updated today
Go
98%
Other

Tyk API Gateway

Developer Tools · Devops

10,810

Cloud-native, high-performance open-source API gateway for REST, GraphQL, gRPC, and TCP — built in Go since 2014 with no feature lockout.

View details
96
Repo Health
78
Technical
66
Dependency
Built with
Go98%
Updated 2 days ago

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search