Networking Tutorial · Routing and Network Services · Lesson 20 of 28

Proxies and CDNs

Forward and reverse proxies, CDNs and edge caching, and the headers that carry the real client IP.

Create a free account to save this page, take notes and track your progress. Sign in

Forward and reverse proxies

  • A forward proxy acts for clients: a company proxy that all outbound web traffic goes through.
  • A reverse proxy acts for servers: NGINX, Envoy, a load balancer or a CDN that receives requests and forwards them to your app. It can terminate TLS, compress, cache, rate limit and route.

CDNs

A CDN (content delivery network) such as Amazon CloudFront, Azure Front Door, Google Cloud CDN or Cloudflare runs reverse proxies in hundreds of locations. Users connect to a nearby edge, which serves cached content or forwards the request to your origin over a fast, warm connection. Cache behaviour is controlled by Cache-Control headers from your app.

The real client IP

Behind a proxy, your app sees the proxy's IP as the connection's source. Proxies add the original address to a header, usually X-Forwarded-For (a comma-separated list, one entry per proxy) or the standard Forwarded header. Clients can send fake values, so trust only the entries added by your own proxies:

Find the real client IP safelyTry it yourself
import ipaddress

TRUSTED_PROXIES = [ipaddress.ip_network("10.0.0.0/16")]     # our load balancers

def client_ip(peer, x_forwarded_for):
    chain = [p.strip() for p in x_forwarded_for.split(",")] + [peer]
    for hop in reversed(chain):                             # walk back from the closest hop
        if not any(ipaddress.ip_address(hop) in net for net in TRUSTED_PROXIES):
            return hop
    return chain[0]

# A client tries to spoof 1.2.3.4; our load balancer (10.0.0.12) appended the real address.
print(client_ip("10.0.0.12", "1.2.3.4, 203.0.113.50"))
print(client_ip("10.0.0.12", "198.51.100.8"))

Output

203.0.113.50
198.51.100.8

Test yourself

Why shouldn't you use the first entry of X-Forwarded-For as the client IP?

  1. Clients can put any value there; only entries added by your own proxies can be trusted
  2. It is always the load balancer's IP
  3. It contains ports, not IPs
  4. It is encrypted
Show answer

Answer: Clients can put any value there; only entries added by your own proxies can be trusted

Each proxy appends to the header. Walk from the right, skipping your own proxies, to find the first address you didn't add.

Was this page helpful?