#proxy #protocols #tcp-connection #ha-proxy

proxy-header

A library for parsing and serializing PROXY protocol headers

1 unstable release

0.1.0 Nov 17, 2023

#4 in #ha-proxy

Download history 25/week @ 2024-01-06 42/week @ 2024-01-13 7/week @ 2024-01-20 1/week @ 2024-01-27 59/week @ 2024-02-10 37/week @ 2024-02-17 63/week @ 2024-02-24 17/week @ 2024-03-02 36/week @ 2024-03-09 23/week @ 2024-03-16 18/week @ 2024-03-23 97/week @ 2024-03-30 116/week @ 2024-04-06 53/week @ 2024-04-13 16/week @ 2024-04-20

283 downloads per month
Used in rs-proxy

MIT license

69KB
1.5K SLoC

proxy-header

This crate provides a decoder and encoder for the HAProxy PROXY protocol, which is used to preserve original client connection information when proxying TCP connections for protocols that do not support this higher up in the stack.

The PROXY protocol is supported by many load balancers and proxies, including HAProxy, Amazon ELB, Amazon ALB, and others.

This crate implements the entire specification, except parsing the AF_UNIX address type (the header is validated / parsed, but the address is not decoded or exposed in the API).

Acknowledgements

This crate started as a fork of the proxy-protocol crate, but has since been rewritten from scratch.

License

This crate is licensed under the MIT license. See the LICENSE file for details.


lib.rs:

PROXY protocol decoder and encoder

This crate provides a decoder and encoder for the PROXY protocol, which is used to preserve original client connection information when proxying TCP connections for protocols that do not support this higher up in the stack.

The PROXY protocol is supported by many load balancers and proxies, including HAProxy, Amazon ELB, Amazon ALB, and others.

This crate implements the entire specification, except parsing the AF_UNIX address type (the header is validated / parsed, but the address is not decoded or exposed in the API).

Usage

Decoding

To decode a PROXY protocol header from an existing buffer, use ProxyHeader::parse:

use proxy_header::{ProxyHeader, ParseConfig};

let buf = b"PROXY TCP6 2001:db8:1::1 2001:db8:2::1 52953 25\r\nHELO example.com\r\n";

let (header, len) = ProxyHeader::parse(buf, ParseConfig::default())?;
match header.proxied_address() {
   Some(addr) => {
      println!("Proxied connection from {} to {}", addr.source, addr.destination);
   }
   None => {
      println!("Local connection (e.g. healthcheck)");
  }
}

println!("Client sent: {:?}", &buf[len..]);

In addition to the address information, the PROXY protocol version 2 header can contain additional information in the form of TLV (type-length-value) fields. These can be accessed through the ProxyHeader::tlvs iterator or through convenience accessors such as ProxyHeader::authority.

See [Tlv] for more information on the different types of TLV fields.

use proxy_header::Tlv;

for tlv in header.tlvs() {
    match tlv? {  // TLV can be malformed
        Tlv::UniqueId(v) => {
            println!("Unique connection ID: {:?}", v);
        }
        Tlv::Authority(v) => {
            println!("Authority string (SNI): {:?}", v);
        }
        _ => {}
    }
}

See also [io] module for a stream wrapper that can automatically parse PROXY protocol.

Encoding

To encode a PROXY protocol header, use ProxyHeader::encode_v1 for version 1 headers and ProxyHeader::encode_v2 for version 2 headers.

use proxy_header::{ProxyHeader, ProxiedAddress, Protocol};

let addrs = ProxiedAddress::stream(
   "[2001:db8::1:1]:51234".parse().unwrap(),
   "[2001:db8::2:1]:443".parse().unwrap()
);
let header = ProxyHeader::with_address(addrs);

let mut buf = [0u8; 1024];
let len = header.encode_to_slice_v2(&mut buf).unwrap();

Dependencies

~0–1.2MB
~20K SLoC