What is the difference between the "Real IP from" options in the Trusted Proxy profile (X-Forwarded-For (last / most trusted), X-Forwarded-For (first), Custom Header)?
Short answer
In the Trusted Proxy profile, X-Forwarded-For (last / most trusted) (default) takes the rightmost address in the header chain: this is the value added by the trusted proxy as the address connecting to it, and it is the most secure option. X-Forwarded-For (first) takes the leftmost address in the chain; since the client can write this value itself, it can be spoofed even if the connection comes from the trusted network. Custom Header reads the CDN's single-value custom header, such as CF-Connecting-IP or True-Client-IP, written in the Header Name field. In all three options, the header is used only if the connection comes from an address in the Trusted Networks list (Real IP from).
Comparison
| Option | Value read | Reliability | Suitable situation |
|---|---|---|---|
| X-Forwarded-For (last / most trusted) | The rightmost address in the chain | High | A single proxy layer in front of TR7 |
| X-Forwarded-For (first) | The leftmost address in the chain | Low; the client can write it | Only closed environments where the start of the chain is trusted |
| Custom Header | The value of the specified header (Header Name) | High (the CDN overwrites the header) | Cloudflare (CF-Connecting-IP), Akamai (True-Client-IP) |
How Does It Work?
- TR7 first checks whether the address the connection comes from is in the Trusted Networks list; if not, the header is not taken into account (it is not deleted, it goes to the Backend Service as it is).
- If the address is in a trusted network, the address in the header is read with the selected method and used as the client address.
- TR7 does not walk back the X-Forwarded-For chain step by step: the intermediate addresses in the chain are not compared with the trusted networks; the single selected position (the last or the first value) is read. If there is more than one X-Forwarded-For line, the values are counted as a single chain.
- If there is more than one source (Sources) in the profile, the sources are evaluated in order; the first source that finds the connection in its trusted network is applied.
Chain Example
For client (198.51.100.45) → CDN (198.51.100.7) → TR7, the CDN adds the following header:
X-Forwarded-For: 198.51.100.45last and first give the same value here. If the client itself sends X-Forwarded-For: 198.51.100.66, the CDN appends the address it sees to the end (198.51.100.66, 198.51.100.45): last reads the correct address (198.51.100.45), and first reads the fake address written by the client (198.51.100.66).
When there are two proxy layers (client → CDN → corporate proxy → TR7), last gives the CDN address added by the corporate proxy; in this case, the CDN's custom header (Custom Header) is used, or the corporate proxy adds a separate header carrying the client address.
In TR7
- Location: Load Balancer → Profiles → Trusted Proxies → profile → Sources → Real IP from; the profile is selected in the Details → Trusted Proxy field of the HTTP vService (There is a CDN such as Cloudflare / Akamai in front of TR7; how do I get the Real client IP (trusted proxy)?).
- Previous address: The connection source before resolution (the address of the proxy in front) can be used in logs, reports and conditions with the
%PROXY_SRCSmart Variable (The components that use the resolved address).
Common Misconceptions
- "first is the real client, so it is more accurate." The first value can be written by the client.
- "Custom header reads any header." The header name can consist only of letters, digits, hyphens and underscores (at most 64 characters); the value in the header must be an IP address.
- "If the header comes from an untrusted source, it is deleted." The header is not taken into account, but it goes to the Backend Service as it is.
How it is done in the documentation
Related questions
