🧭 HAProxy (PROXY protocol)

The PROXY protocol is designed to safely transport connection informationβ€”such as a client’s original IP and portβ€”across one or more layers of TCP proxies or load balancers, without requiring protocol-specific logic in the intermediary.

β€” HAProxy PROXY Protocol Spec

Examples:

  • /examples/haproxy_client_ip.rs: shows how to support, optionally, HaProxy (v1/v2) in a rama web service, supporting load balancers that support the proagation of client IP address.

Description

%3clientclientloadbalancer (HAProxy)loadbalancer (HAProxy)client->loadbalancer (HAProxy)rama serverrama serverloadbalancer (HAProxy)->rama server

The PROXY protocol is commonly used when a reverse proxy (like HAProxy, NGINX, or Envoy) terminates incoming TCP connections but needs to preserve the original connection metadata.

This is critical for:

  • Preserving accurate IP logs,
  • Applying access control policies,
  • Implementing multi-layer proxy chains with full end-to-end source attribution.

Rama supports both version 1 (text-based) and version 2 (binary-based) of the PROXY protocol, enabling it to serve as either an upstream server behind HAProxy or as a proxy that receives and parses these headers.

PROXY protocol v1

πŸ“– rama docs: https://ramaproxy.org/docs/rama/proxy/haproxy/protocol/v1/index.html

The v1 format is human-readable and looks like this:

PROXY TCP4 192.0.2.1 198.51.100.1 56324 443\r\n

It is prepended to the beginning of a TCP stream before any application data. When Rama receives such a connection on a configured HaProxyService, it will extract and provide access to the source/destination metadata via its connection context APIs.


PROXY v1 flow
-------------

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client │──────▢│ HAProxy        │──────▢│ Rama (Proxy Target)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                  β”‚                        β”‚
     β”‚ 1. Connect to HA β”‚                        β”‚
     │─────────────────▢│                        β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 2. HA sends v1   β”‚                        β”‚
     β”‚    PROXY header  │──────────────────────▢ β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 3. Rama extracts β”‚                        β”‚
     β”‚    metadata      β”‚                        β”‚

PROXY protocol v2

The v2 format is a binary header, allowing for more efficient parsing and extensibility (e.g., SSL info, unique ID, namespaces). Rama’s implementation fully supports parsing v2 headers including TLV extensions where needed.

πŸ“– rama docs: https://ramaproxy.org/docs/rama/proxy/haproxy/protocol/v2/index.html

Example header structure:

  • 12-byte signature
  • 1-byte version/command
  • 1-byte address family/protocol
  • 2-byte payload length
  • Variable-length address metadata
  • Optional TLV vectors

PROXY v2 flow
-------------

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”       β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Client │──────▢│ HAProxy        │──────▢│ Rama (Proxy Target)β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜       β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
     β”‚                  β”‚                        β”‚
     β”‚ 1. Connect to HA β”‚                        β”‚
     │─────────────────▢│                        β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 2. HA sends v2   β”‚                        β”‚
     β”‚    binary header │──────────────────────▢ β”‚
     β”‚                  β”‚                        β”‚
     β”‚ 3. Rama extracts β”‚                        β”‚
     β”‚    full context  β”‚                        β”‚

Note: Rama can also optionally support HAProxy by setting peek=true when creating the HaProxy layer/service.