Preserving the Client IP
Why does the backend see the proxy address instead of the real client? An edge proxy ends the connection the client opened and starts one of its own, so the socket names the proxy and the original address survives only if something writes it down. For HTTP that is X-Forwarded-For, which the client can also send, so the header becomes a list to be trusted from its last entry inwards, and for raw TCP the PROXY protocol prepends a preamble the backend must expect.
Play the animation 5 steps, animated, best on a wide screen
Preserving the Client IP, step by step
-
The client opens the connection to the edge, an Ingress or Gateway proxy Pod. Its packets carry the real source address, 198.51.100.9, and they arrive unchanged only because nothing on the way rewrote them. That is the assumption everything below rests on.
Play from step 1 -
The edge does not forward those packets. It ends that connection and opens a new one of its own to the backend, so what the app receives is sourced from the proxy Pod, 10.244.0.9. Compare the two src rows: read from the socket, the client address is gone.
Play from step 2 -
So the edge writes the address into the request instead. Before proxying it adds X-Forwarded-For carrying the client address. The standardized form, the RFC 7239 Forwarded header, writes it as for=198.51.100.9. The socket still reads 10.244.0.9, and the app reads the header.
Play from step 3 -
A header is only data, and the client can send an X-Forwarded-For of its own claiming any address. An edge that keeps what arrived appends what it saw, so the row becomes a list: the forged value first, the address your own edge saw last. Trust that list from its last entry inwards.
Play from step 4 -
Raw TCP and passed-through TLS have no header to write into. The PROXY protocol prepends a short preamble to the first bytes of the stream, carrying the original source address, and the backend must be configured to expect it or it reads the preamble as request bytes.
Play from step 5