Why do my backend servers see all requests as coming from TR7's IP?
Short answer
TR7 works as a Reverse Proxy in HTTP and L7 TCP vServices: it terminates the client's connection and itself opens a new connection to the Backend Service. When the SNAT field of the Backend Service is left at its default value Default, the source address of this connection is the Interface IP of the interface the traffic to the server leaves from in the Backend Service's Route Table, in the same subnet as the server (or as the gateway, if the server is reached through a gateway); this is why the server sees all requests as coming from TR7. This is not an error but the default behavior; the client IP is forwarded with X-Forwarded-For, Use Client IP, the PROXY protocol or, in a Network vService, with LB Mode (How do I see the real client IP on the backend?).
Background
A TCP connection is defined by four values: source IP, source port, destination IP and destination port. The server always sends the response to the source IP of the request. A Reverse Proxy establishes one connection with the client and a separate connection with the server; the server sees only the second connection, that is, the proxy's address. This is why the client's address is carried to the server only in another way (an HTTP header, the PROXY protocol or preservation of the source address).
How Does It Work?
- The client (e.g.
198.51.100.45) connects to the vService address. - TR7 terminates the connection, processes the request and selects the Backend Service.
- TR7 opens a new connection to the Backend Service. With SNAT = Default, the source address is the Interface IP of the interface the traffic to the server leaves from in the Backend Service's Route table, in the same subnet as the server (if the server is reached through a gateway, the Interface IP in the same subnet as the gateway). In a cluster, each device uses its own Interface IP. If more than one IP has been added to the interface in that subnet, which one will be used cannot be determined from the order on the interface; if a specific address is required, Use Device IP is selected.
- The Backend Service sees the request as coming from TR7 and sends the response to TR7; TR7 forwards the response to the client.
Example: TR7, which has the Interface IP 192.0.2.5/24 in the Route table, connects to the server at 192.0.2.20 with the source 192.0.2.5. If a fixed source address is wanted, one of the IPs in the Route table is selected with Use Device IP (What does "Default" in the SNAT field mean; can I choose a specific SNAT IP?).
TR7's IP address (192.0.2.5)
X-Forwarded-For: 198.51.100.45
Why Is This the Default?
- The return path is correct on its own. The server sends the response to the source IP of the request. When the source is TR7, the response returns to TR7 regardless of the server's routing; no change is required on the servers or in the network.
- Symmetric flow is preserved. If the connection is made with the client's IP, the server sends the response to its own default gateway. If the gateway is not TR7, the response bypasses TR7: TR7 cannot complete the connection, and the client rejects the packet coming from an address it does not expect (the server's IP instead of the vService IP). If there is a stateful firewall in between, it drops the flow of which it sees only one direction.
- It is independent of the network topology. The server does not have to be in the same subnet as TR7; a server in any network reachable from TR7's Route table can be used.
- The cost is the client IP. The server cannot see the client's address from the connection; this is why X-Forwarded-For is used in HTTP, and in other cases the PROXY protocol or Use Client IP, which preserves the source address. Use Client IP requires the responses to return through TR7: the default gateway of the servers becomes TR7, or Spoofing is enabled (What is SNAT, and why is it used by default?).
By vService Type
| vService type | Source seen by the server (default) | Way to forward the client IP |
|---|---|---|
| HTTP | TR7's IP (SNAT Default) | X-Forwarded-For, Use Client IP, PROXY protocol, Add HTTP Header action |
| L7 TCP | TR7's IP (SNAT Default) | Use Client IP, PROXY protocol |
| Network | Depends on the LB mode: the client's IP in Direct Server Return (default) and Route Mode, the selected SNAT IP in SNAT mode | LB Mode; in a Network vService, the SNAT field of the Backend Service is not used |
Impact
- The server's access logs and analyses show all traffic as coming from a single address.
- IP-based restrictions and request limits on the server count all users as a single client.
- The application's security decisions are made with TR7's address, not the client's.
Common Misconceptions
- "TR7 loses the client IP." TR7 knows the client's IP; it uses it in its logs, conditions and security features. It uses its own address only in the connection it opens to the Backend Service.
- "The source address is the IP of the first interface in the route table." The source is not the first interface IP in the route table; it is the Interface IP of the interface the traffic to the server leaves from, in the same subnet as the server (or as the gateway, if the server is reached through a gateway).
- "When X-Forwarded-For is enabled, the server log is corrected on its own." The server must be configured to read the header (How is X-Forwarded-For enabled; what do I need to do on the backend side (Apache / Nginx / IIS logs)?).
- "The IP of the CDN in front of TR7 is the same problem." If TR7 is behind a CDN, TR7 itself also sees the CDN's IP; this is solved with Trusted Proxy (There is a CDN such as Cloudflare / Akamai in front of TR7; how do I get the Real client IP (trusted proxy)?).
How it is done in the documentation
