PROXY Protocol Support
How to configure PROXY protocol v2 support in Radiator Server to preserve original client IP addresses when using load balancers like HAProxy or AWS NLB.
- PROXY Protocol Support
- Overview
- Configuration
- RADIUS TCP
- RADIUS UDP
- TACACS+ (TCP or TLS)
- Connection Flow
- How It Works
- 1. Check the proxy IP against ip-accept
- 2. Read the PROXY header
- 3. Look up the client
- 4. Run the TLS handshake (TLS listeners only)
- Connection setup timeout
- Statistics and Counters
- Logging
- Security Considerations
- HTTP Listeners
- See Also
PROXY Protocol Support
Radiator Server supports the PROXY protocol (version 2) for preserving client IP addresses when connections are proxied through load balancers like HAProxy, AWS Network Load Balancer, or other TCP proxies.
Overview
When a load balancer or proxy sits in front of Radiator, the server sees the proxy IP address, not the real client. The PROXY protocol fixes this. The proxy adds a small header at the start of the connection. The header carries the real client IP address and port.
Radiator supports PROXY protocol v2 only. Version 2 is binary, fast to parse, and supported by all modern load balancers. Version 1 (text format) is not supported.
PROXY protocol works on these listeners:
- RADIUS over TCP
- RADIUS over UDP
- RadSec (RADIUS over TLS)
- TACACS+ over TCP
- TACACS+ over TLS
On TLS listeners, the proxy sends the PROXY header before the TLS handshake. Radiator reads the header first and then starts TLS with the bytes that follow.
Configuration
Add proxy-protocol v2; inside the listen block.
RADIUS TCP
servers {
radius "RADIUS_TCP_1812" {
listen {
protocol tcp;
port 1812;
ip 0.0.0.0;
proxy-protocol v2;
ip-accept "ACCEPT_PROXIES";
}
clients "CLIENTS_RADIUS_ALL";
}
}
RADIUS UDP
servers {
radius "RADIUS_UDP_1812" {
listen {
protocol udp;
port 1812;
ip 0.0.0.0;
proxy-protocol v2;
ip-accept "ACCEPT_PROXIES";
}
clients "CLIENTS_RADIUS_ALL";
}
}
UDP behaviour: Radiator sends UDP replies straight to the real client IP from the PROXY header. Replies do not go back through the proxy. Make sure Radiator has a route to the client network. If you need replies to return through the proxy, use TCP.
TACACS+ (TCP or TLS)
servers {
tacacs-plus "TACACS_PLUS_1049" {
listen {
protocol tcp;
port 49;
ip 0.0.0.0;
proxy-protocol v2;
ip-accept "ACCEPT_PROXIES";
}
clients "CLIENTS_TACACS_ALL";
}
}
For TACACS+ over TLS, change protocol tcp; to protocol tls; and add a tls { ... } block. RadSec uses the same form: protocol tls; plus a tls { ... } block on a RADIUS server.
Connection Flow
The following diagram shows how an incoming RADIUS or TACACS+ connection is processed with PROXY protocol enabled:
How It Works
Radiator processes a new connection in this order.
1. Check the proxy IP against ip-accept
Radiator first checks the IP of the direct peer (the load balancer) against the ip-accept list. If the proxy IP is not allowed, the connection is rejected. This stops untrusted hosts from sending fake PROXY headers.
2. Read the PROXY header
Radiator reads the PROXY v2 header. The header gives:
- Real client IP address and port
- Destination IP address and port
- Transport (TCP or UDP, IPv4 or IPv6)
When proxy-protocol v2; is set, every connection must start with a valid PROXY v2 header. There is no fallback. Connections without a header are rejected.
3. Look up the client
Radiator looks up the client using the real client IP from the PROXY header, not the proxy IP. Client matching, shared secrets, and policies all use the real client address.
4. Run the TLS handshake (TLS listeners only)
On RadSec and TACACS+ TLS listeners, the TLS handshake runs after the PROXY header is parsed. The first byte after the header must be the TLS ClientHello.
Connection setup timeout
Reading the PROXY header and, on TLS listeners, the TLS handshake must finish inside one time limit. Radiator picks the limit in this order:
- The
timeouton the matchingip-acceptentry. - The
timeouton thelistenblock. - A built-in default of 10 seconds.
Increase the listener timeout for slow load balancers. Use an ip-accept timeout to override the limit for one source prefix.
Statistics and Counters
Radiator tracks several counters related to PROXY protocol processing:
| Counter | Description |
|---|---|
IpAcceptDeny | Connections rejected at IP-accept pre-admission check |
ProxyProtocolErrors | Failed to parse or invalid PROXY protocol headers |
ClientsDeny | Client lookup failed for the proxied address |
Requests | Successfully processed requests |
Replies | Successfully sent replies |
Monitor these counters to detect:
- Misconfigured load balancers sending invalid headers
- Unauthorized proxies attempting connections
- Client configuration issues with proxied addresses
Logging
When PROXY protocol is enabled, log entries show both addresses:
peer_addr: the real client address from the PROXY header.proxy_addr: the direct proxy address. Only logged when it differs frompeer_addr.
All request processing uses the real client address.
Example log entry on a RadSec listener:
{
"peer_addr": "203.0.113.1",
"proxy_addr": "10.0.1.5",
"message": "Accepting Radius TLS client connection"
}
TACACS+ TLS listeners use the same fields, with messages such as Accepting TACACS+ TLS client connection.
Security Considerations
-
Always restrict proxies with
ip-accept. Only trusted load balancers should be able to send PROXY headers:ip-accept "TRUSTED_PROXIES" { client "LOAD_BALANCERS" { source { ip 10.0.1.0/24; } } } -
Watch the
ProxyProtocolErrorscounter. A sudden rise often means a misconfigured proxy or an attack. -
Define RADIUS and TACACS+ clients by their real IP addresses, not by proxy addresses.
HTTP Listeners
HTTP listeners do not use PROXY protocol. Use the standard X-Forwarded-For header instead.
See Also
- PROXY Protocol Support
- Overview
- Configuration
- RADIUS TCP
- RADIUS UDP
- TACACS+ (TCP or TLS)
- Connection Flow
- How It Works
- 1. Check the proxy IP against ip-accept
- 2. Read the PROXY header
- 3. Look up the client
- 4. Run the TLS handshake (TLS listeners only)
- Connection setup timeout
- Statistics and Counters
- Logging
- Security Considerations
- HTTP Listeners
- See Also
About Radiator software development security
Architecture Overview
Backend Load Balancing
Basic Installation
Built-in Environment Variables
Comparison Operators
Configuration Editor
Configuration Import and Export
Containers
Data Types
Duration Units
Environment Variables
Execution Context
Execution Pipelines
Filters
Getting a Radiator License
Health check /live and /ready
High Availability and Load Balancing
High availability identifiers
HTTP Basic Authentication
Introduction
Linux systemd support
Local AAA Backends
Log storage and formatting
Management API privilege levels
Namespaces
Password Hashing
Probabilistic Sampling
Prometheus scraping
PROXY Protocol Support
Radiator server health and boot up logic
Radiator sizing
Radiator software releases
Rate Limiting
Rate Limiting Algorithms
Reverse Dynamic Authorization
Service Level Objective
TACACS+ Authentication, Authorization, and Accounting
Template Rendering CLI
Tools radiator-client
TOTP/HOTP Authentication
What is Radiator?
YubiKey Authentication
YubiKey Context Variables
About Radiator software development security
Architecture Overview
Backend Load Balancing
Basic Installation
Built-in Environment Variables
Comparison Operators
Configuration Editor
Configuration Import and Export
Containers
Data Types
Duration Units
Environment Variables
Execution Context
Execution Pipelines
Filters
Getting a Radiator License
Health check /live and /ready
High Availability and Load Balancing
High availability identifiers
HTTP Basic Authentication
Introduction
Linux systemd support
Local AAA Backends
Log storage and formatting
Management API privilege levels
Namespaces
Password Hashing
Probabilistic Sampling
Prometheus scraping
PROXY Protocol Support
Radiator server health and boot up logic
Radiator sizing
Radiator software releases
Rate Limiting
Rate Limiting Algorithms
Reverse Dynamic Authorization
Service Level Objective
TACACS+ Authentication, Authorization, and Accounting
Template Rendering CLI
Tools radiator-client
TOTP/HOTP Authentication
What is Radiator?
YubiKey Authentication
YubiKey Context Variables