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
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 RADIUS connections (TCP or UDP) pass through a load balancer or proxy, the server sees the proxy's IP address instead of the original client's IP address. The PROXY protocol solves this by prepending connection metadata that includes the original client's IP address and port.
Radiator implements PROXY protocol v2, which provides:
- Binary format for efficient parsing
- Support for IPv4 and IPv6 addresses
- Minimal overhead on connection establishment
Note: PROXY protocol v1 is not supported. Version 1 uses a text-based format which is less efficient to parse and more error-prone than the binary v2 format. All modern load balancers and proxies support v2.
Configuration
Enable PROXY protocol in your server listen configuration by adding proxy-protocol v2 in the listen block:
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";
}
}
For 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";
}
}
Important UDP Behavior: With UDP and PROXY protocol, response packets are sent directly back to the original client IP (extracted from the PROXY header), not back through the proxy. This requires that the Radiator server has a direct route to the client network. For scenarios where responses must flow back through the proxy, use TCP instead.
Connection Flow
The following diagram shows how an incoming RADIUS connection is processed with PROXY protocol enabled:
Note: For TLS connections (RadSec), the TLS handshake occurs after IP-Accept but before PROXY protocol parsing, as the PROXY header is transmitted inside the TLS tunnel.
How It Works
1. IP-Accept Pre-admission Check
Before processing the PROXY protocol header, Radiator checks the direct peer address (the load balancer's IP) against the ip-accept list. This provides an additional security layer ensuring only trusted proxies can connect.
If the proxy's IP is not in the ip-accept list, the connection is rejected immediately.
2. PROXY Protocol Header Parsing
If ip-accept passes, Radiator reads and parses the PROXY protocol v2 header. The header contains:
- Original client IP address and port
- Destination IP address and port
- Protocol information (TCP/UDP, IPv4/IPv6)
If the header is malformed or uses an unsupported version, the connection is rejected.
3. Client Lookup
After successful PROXY protocol parsing, client lookup uses the original client IP address (from the PROXY header), not the proxy's address.
This ensures that RADIUS client matching, shared secrets, and access policies apply to the actual client, not the intermediate proxy.
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, logs include both addresses:
peer_addr: The direct connection source (load balancer IP)proxy_addr: Logged when different from peer_addr, showing the proxy- Context uses the original client address for all processing
Example log entry:
{
"peer_addr": "203.63.154.1",
"proxy_addr": "10.0.1.5",
"message": "Processing RADIUS request"
}
Security Considerations
-
Always use
ip-accept: Restrict which proxies can connect to prevent IP spoofingip-accept "TRUSTED_PROXIES" { client "LOAD_BALANCERS" { source { ip 10.0.1.0/24; } } } -
Monitor
ProxyProtocolErrors: Spike indicates misconfiguration or attack attempts -
Validate client configuration: Ensure RADIUS clients are defined using their real IP addresses, not proxy addresses
Protocol Support
PROXY protocol is supported on:
- RADIUS TCP (including RadSec/TLS)
- RADIUS UDP
- TACACS+ TCP (with or without TLS)
For HTTP use X-Forwarded-For headers instead.
Performance Impact
PROXY protocol adds minimal overhead:
- Header size: 16 bytes (IPv4) or 28 bytes (IPv6) for v2
- Parsing: Single parse operation at connection establishment
- Memory: No additional per-request allocations
For UDP, the header is included with each datagram. For TCP, it's sent once per connection.
See Also
Architecture Overview
Backend Load Balancing
Basic Installation
Comparison Operators
Configuration Editor
Configuration Import and Export
Data Types
Duration Units
Execution Context
Execution Pipelines
Filters
Health check /live and /ready
High Availability and Load Balancing
High availability identifiers
HTTP Basic Authentication
Introduction
Local AAA Backends
Log storage and formatting
Management API privilege levels
Namespaces
Password Hashing
Pipeline Directives
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
Template Rendering CLI
Tools radiator-client
TOTP/HOTP Authentication
What is Radiator?