logo of Akmatori
28.01.2024

Understanding Proxy Protocol: A Guide to Version 1 and Version 2

head-image

In the digital landscape where efficiency and security are paramount, understanding networking protocols is crucial for developers and system administrators. The Proxy Protocol is an essential tool designed to carry connection information from the source requesting a connection to the destination server. This post will explore the differences and applications of Proxy Protocol Version 1 and Version 2, and introduce how Akmatori, a Globally Distributed TCP/UDP Balancer, can significantly improve your infrastructure's performance and security.

What is the Proxy Protocol?

The Proxy Protocol was created to solve a problem faced by servers operating behind load balancers or reverse proxies. Typically, these configurations lose the original client’s connection information such as a client's IP address, a crucial detail for both logging purposes and security. The Proxy Protocol preserves this information, enabling the destination server to understand who made the request, thus enhancing both transparency and security. Proxy protocol was initially developed by HAProxy and you can find full protocol specification here

Proxy Protocol Version 1

The version 1 of the protocol is text based.

Main Features:
Text-based: Easy to implement and debug because of its human-readable format.
Compatibility: Works seamlessly with existing protocols and systems that read headers.

Use Cases:
Ideal for setups where simple deployments are needed, and readability of headers is required for troubleshooting and logging.

An example of PROXY Protocol header for IPv4 incoming address:

PROXY TCP4 1.2.3.4 166.1.130.1 44765 80\r\n

Format:

Signature INET_Protocol Source_Address Destination_Address Source_Port Destination_Port

Where:

Signature
Constant 5 bytes identifying the first line of a request as being a version 1 PROXY protocol line.
Position: 0
Value:

PROXY ->\x50 \x52 \x4F \x58 \x59  

INET_Protocol
Proxied protocol and family. Only TCP and TCP6 allowed.

Source_Address
IPv4 for TCP or IPv6 for TCP6.

Destination_Address
IPv4 for TCP or IPv6 for TCP6.

Source Port
Number between 0..65535

Destination Port
Number between 0..65535

Proxy Protocol Version 2

Proxy Protocol version 2 is binary based.

Main Features

  • Binary format: More efficient, less error-prone, and faster to parse than text-based formats.
  • Enhanced security: Includes additional features like TLV (Type-Length-Value) that can carry extra information such as SSL information, network namespace, etc.
    Scalability: Designed for modern, high-load environments.

Use Cases

  • Best for high-performance applications where efficiency is critical.
  • Suitable for environments where advanced security and detailed connection logging are necessary.

An example of PROXY Protocol binary header for a IPv4 incoming address:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                  Proxy Protocol v2 Signature                  |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|Command|   AF  | Proto.|         Address Length        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                      IPv4 Source Address                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    IPv4 Destination Address                   |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |        Destination Port       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

An example of PROXY Protocol binary header for a IPv6 incoming address:

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                  Proxy Protocol v2 Signature                  |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Version|Command|   AF  | Proto.|         Address Length        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                      IPv6 Source Address                      +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                                                               |
+                                                               +
|                                                               |
+                    IPv6 Destination Address                   +
|                                                               |
+                                                               +
|                                                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |        Destination Port       |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Where:

Signature
Constant 12 bytes allow an proxy to identify that the request starts with a PROXY protocol header.
Length: 3 * 32 bits = 12 bytes
Position: bytes 0 to 11
Value:

\x0D \x0A \x0D \x0A \x00 \x0D \x0A \x51 \x55 \x49 \x54 \x0A  

Version
Constant 4 bits that must always be equal to \x2 version 2. Only uses the 4 highest bits of the 13th byte. The other 4 bits are used by the command field.
Length: 4 bits.
Position: Highest 4 bits of the 13th byte.
Value:

\x2 (binary: 0010)  

Command
Indicates whether the request was proxied or not. It is useful to know if the addresses should be ignored or not.
Length: 4 bits.
Position: Lowest 4 bits of the 13th byte.
Value:

\x0 (binary: 0000): LOCAL: request is not from a proxy.  
\x1 (binary: 0001): PROXY: request is from a proxy.  

Address Family Original Address Family of the socket used to connect to the proxy.
Length: 4 bits.
Position: Highest 4 bits of the 14th byte.
Value:

\x0 (binary: 0000): AF_UNSET: Used for the LOCAL command.  
\x1 (binary: 0001): AF_INET: IPv4  
\x2 (binary: 0010): AF_INET6: IPv6  
\x3 (binary: 0011): AF_UNIX: UNIX  

Transport Protocol The protocol used to connect to the proxy. With the Address Family, we can infer the addresses types and length.
AF_INET + STREAM: TCP over IPv4
AF_INET + DGRAM: UDP over IPv4
AF_INET6 + STREAM: UDP over IPv4
AF_INET6 + DGRAM: UDP over IPv6
AF_UNIX + STREAM: UNIX stream
AF_UNIX + DGRAM: UNIX datagram
Length: 4 bits.
Position: Lowest 4 bits of the 14th byte.
Value:

\x0 (binary: 0000): AF_UNSET: Used for the LOCAL command.  
\x1 (binary: 0001): STREAM: TCP  
\x2 (binary: 0010): DGRAM: Datagram (UDP or SOCK_DGRAM)  

Address Length The length of the address fields (source, destination) addresses and port. In Network Order (Big Endian), which means the most significant byte is at the lowest address. The length of the address + the number of bytes before the address is the total length of the header.
Length: 2 * 8 bits = 2 bytes.
Position: 15th and 16th bytes.

Source Address
The source address of the request. Each byte represent an integer from 0 to 255.
Length: 4 bytes (IPv4)
Position: 17th to 20th bytes (IPv4)

Destination Address
The destination address of the request. Each byte represent an integer from 0 to 255.
Length: 4 bytes (IPv4)
Position: 21th to 24th bytes (IPv4)

Source Port
The source port of the request. The bytes are in Network Order (Big Endian). Which means the most significant byte is at the lowest address.
Length: 2 bytes (IPv4)
Position: 25th and 26th bytes (IPv4)

Destination Port
The destination port of the request. The bytes are in Network Order (Big Endian). Which means the most significant byte is at the lowest address.
Length: 2 bytes (IPv4)
Position: 27th and 28th bytes (IPv4)

Benefits of Proxy Protocol in Modern Infrastructure

  • Enhanced Security: Provides accurate client IP data, critical for security audits and real-time intrusion detection.
  • Improved Logging: Ensures detailed logs with the original client IP for accurate analytics and troubleshooting.
  • Scalability and Efficiency: Especially with Version 2, supports high-traffic networks by reducing processing overhead and improving data transmission efficiency.

Integrating Proxy Protocol with Akmatori

Akmatori leverages the Proxy Protocol v1 to enhance its capabilities as a Globally Distributed TCP/UDP Balancer. By using Akmatori, you can ensure that critical connection information is preserved across your load-balanced networks, improving security and performance across global data centers.

Conclusion

Understanding and implementing the right version of the Proxy Protocol can greatly enhance your network's security, efficiency, and transparency. With the added support of tools like Akmatori, managing your infrastructure at scale becomes not only feasible but also efficient.

Maximize your website or application's performance and reliability!