Okay, imagine Traefik is the bouncer at a club (your web application). Usually, when someone comes to the door, the bouncer sees their face directly and knows who they are (their IP address).
Now, imagine there's a friendly assistant (another load balancer or proxy) standing before the bouncer. Instead of people going directly to the bouncer, they first talk to the assistant. The assistant checks their ID and then escorts them to the club.
The problem is, when the VIP (the web request) finally reaches the bouncer (Traefik), the bouncer only sees the assistant's face (the load balancer's IP address), not the actual VIP's face (the original user's IP address).
Proxy Protocol is like the assistant handing the bouncer a special note along with the VIP. This note says, "Hey, this person's real IP address is [original IP address], and they came in using [original port]."
You're telling Traefik: "Hey, only listen to these special notes (Proxy Protocol headers) if they come from these specific IP addresses (127.0.0.1/32 which is just your own machine, and 192.168.1.7). If a note comes from anyone else, ignore it because it might be someone trying to trick you!"
The user's browser makes a request to the load balancer. The load balancer then forwards that request to Traefik. From Traefik's perspective, the request looks like it's coming directly from the load balancer. The headers Traefik sees might look something like this:
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
Accept: text/html,application/xhtml+xml,...
# ... other standard HTTP headers ...
Notice that Traefik only sees the load balancer's IP address (192.168.1.7) as the source of the connection. The original user's IP address (203.0.113.45) is lost.
When Proxy Protocol is enabled and correctly configured on both the load balancer and Traefik (with trustedIPs including the load balancer's IP), the load balancer will prepend a special "Proxy Protocol header" to the original HTTP request when forwarding it to Traefik.
The entire stream of data that Traefik receives will look something like this:
PROXY TCP4 203.0.113.45 50000 192.168.1.7 80\r\n
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
Accept: text/html,application/xhtml+xml,...
# ... other standard HTTP headers ...
Let's break down the Proxy Protocol header:
When Traefik receives this, and if the connection came from a trusted IP (like 192.168.1.7 in our example), it will:
Your backend application, behind Traefik, might then see headers like:
GET / HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) ...
Accept: text/html,application/xhtml+xml,...
X-Forwarded-For: 203.0.113.45
X-Forwarded-Proto: http # Or https, depending on the original request to the LB
# ... other standard HTTP headers ...
Here, Traefik has used the information from the Proxy Protocol header to populate the X-Forwarded-For header with the original client's IP address.
In summary, a proxied request with Proxy Protocol includes a special initial line containing information about the original connection before the actual HTTP request headers. This allows Traefik (and other intermediaries that understand the protocol) to know the true source of the request.
If you liked this content I’d appreciate an upvote or a comment. That helps me improve the quality of my posts as well as getting to know more about you, my dear reader.
Muchas gracias!
Follow me for more content like this.
X | PeakD | Rumble | YouTube | Linked In | GitHub | PayPal.me | Medium
Down below you can find other ways to tip my work.
BankTransfer: "710969000019398639", // CLABE
BAT: "0x33CD7770d3235F97e5A8a96D5F21766DbB08c875",
ETH: "0x33CD7770d3235F97e5A8a96D5F21766DbB08c875",
BTC: "33xxUWU5kjcPk1Kr9ucn9tQXd2DbQ1b9tE",
ADA: "addr1q9l3y73e82hhwfr49eu0fkjw34w9s406wnln7rk9m4ky5fag8akgnwf3y4r2uzqf00rw0pvsucql0pqkzag5n450facq8vwr5e",
DOT: "1rRDzfMLPi88RixTeVc2beA5h2Q3z1K1Uk3kqqyej7nWPNf",
DOGE: "DRph8GEwGccvBWCe4wEQsWsTvQvsEH4QKH",
DAI: "0x33CD7770d3235F97e5A8a96D5F21766DbB08c875"