Proxy applications

Preserve client identity safely

Use Caddy’s forwarded headers and trusted proxy settings without accepting forged client addresses.

10 minute lesson

~~~

Put a proxy in front of an app and the app stops seeing real client addresses. Every connection now comes from Caddy, so the app logs 127.0.0.1 for everyone. Rate limiting, audit logs, anything keyed on client IP — all broken.

The fix is a convention: forwarded headers. Caddy sets X-Forwarded-For with the client’s address, X-Forwarded-Proto with the original scheme, and X-Forwarded-Host on every proxied request. Your application reads those instead of the socket address. No configuration needed — reverse_proxy does it by default.

Now the security problem. Headers are just text, and any client can send one. Try forging an address through your proxy from the last lesson:

curl -H "X-Forwarded-For: 203.0.113.9" http://127.0.0.1:8080/

Log the headers in your application and look at what arrived. The forged value is gone: Caddy replaced it with the address it saw on the socket. That’s because the request didn’t come from a trusted proxy, so Caddy refuses to believe its identity claims. Forgery defeated by default.

But sometimes there is a legitimate proxy in front of Caddy — a load balancer or a CDN. Then the socket address Caddy sees belongs to the CDN, and the real client address is in the header the CDN sends. You tell Caddy which peers to believe with the global trusted_proxies option:

{
  servers {
    trusted_proxies static 10.0.0.0/8
  }
}

Now, when a connection arrives from an address in 10.0.0.0/8, Caddy trusts its forwarded headers and passes the real client identity to your upstream. Connections from anywhere else still get the socket address.

The mistake to avoid is trusting too widely. Set trusted_proxies to ranges you control, never to the whole Internet. If everyone is a trusted proxy, anyone can claim any address, and every downstream system that keys off client IP — bans, throttles, audit trails — believes the lie.

When your logs show impossible client addresses, or every visitor appears to come from one CDN IP, this setting is the first place to look.

Lesson completed

Take this course offline

Get every free book and course as PDF and EPUB files.

Get the download library →