networking25 min

Reverse Proxies

Intermediary servers that handle requests on behalf of backend services

0/9Not Started

Why This Matters

When a client sends a request to your web application, it rarely talks to your application server directly. Instead, a reverse proxy sits between the client and your backend servers. It receives the request, decides where to forward it, and returns the response to the client. The client never knows which backend server actually handled the request.

Reverse proxies are the Swiss Army knife of web infrastructure. They handle SSL termination so your backend does not need to manage certificates. They cache responses, compress data, rate-limit abusive clients, and route requests to different services based on URL paths. Nearly every production web application sits behind a reverse proxy like Nginx, Caddy, or a cloud-managed API gateway.

Define Terms

Visual Model

ClientBrowser
Reverse ProxyTLS + Routing
API Server/api
Web App/
Static Files/assets
HTTPS
/api/*
/*
/assets/*

The full process at a glance. Click Start tour to walk through each step.

A reverse proxy terminates TLS, routes requests by URL path, and forwards them to different backend services.

Code Example

Code
// Simulating reverse proxy header handling
// When a reverse proxy forwards a request, it adds headers
// so the backend knows the original client details.

function addProxyHeaders(originalRequest, backendRequest) {
  // Preserve the original client IP
  backendRequest.headers["X-Forwarded-For"] = originalRequest.clientIp;

  // Preserve the original protocol (https)
  backendRequest.headers["X-Forwarded-Proto"] = originalRequest.protocol;

  // Preserve the original host
  backendRequest.headers["X-Forwarded-Host"] = originalRequest.host;

  return backendRequest;
}

// Simple path-based routing
function routeRequest(path) {
  if (path.startsWith("/api")) {
    return "http://api-service:3000";
  } else if (path.startsWith("/assets")) {
    return "http://static-service:8080";
  } else {
    return "http://web-app:4000";
  }
}

console.log(routeRequest("/api/users"));
// http://api-service:3000
console.log(routeRequest("/assets/logo.png"));
// http://static-service:8080
console.log(routeRequest("/dashboard"));
// http://web-app:4000

// Extracting real client IP from proxy headers
function getClientIp(request) {
  // X-Forwarded-For may contain multiple IPs if there are chained proxies
  const forwarded = request.headers["x-forwarded-for"];
  if (forwarded) {
    // First IP is the original client
    return forwarded.split(",")[0].trim();
  }
  return request.connection.remoteAddress;
}

const mockReq = {
  headers: { "x-forwarded-for": "203.0.113.50, 70.41.3.18" },
  connection: { remoteAddress: "10.0.0.1" }
};
console.log(getClientIp(mockReq)); // 203.0.113.50

Interactive Experiment

Try these exercises:

  • Extend the routeRequest function to handle additional paths like /auth and /ws (WebSocket).
  • Implement a simple response caching layer: if the same URL is requested twice, return the cached response.
  • What happens if the X-Forwarded-For header has three IPs? Which one is the real client? Which are proxies?
  • How would you add rate limiting to the reverse proxy? Sketch out the logic (track request counts per IP per time window).

Quick Quiz

Coding Challenge

Path-Based Request Router

Write a function called `createRouter` that takes a routing table (an object mapping path prefixes to backend URLs) and returns a function. The returned function accepts a request path and returns the matching backend URL. It should match the longest matching prefix. If no prefix matches, return 'http://default-service:80'.

Loading editor...

Real-World Usage

Reverse proxies are a fundamental building block of web infrastructure:

  • Nginx: The most popular reverse proxy, used by over 30% of all websites. Handles SSL termination, static file serving, caching, and load balancing.
  • API gateways: Kong, AWS API Gateway, and Traefik act as reverse proxies that add authentication, rate limiting, and request transformation for microservices.
  • CDNs: Cloudflare and AWS CloudFront are globally distributed reverse proxies that cache content close to users for faster delivery.
  • Service meshes: In Kubernetes, sidecar proxies (Envoy, Istio) act as reverse proxies for each microservice, handling mutual TLS, retries, and observability.
  • SSL certificates: Let's Encrypt certificates are typically configured on the reverse proxy, not on individual application servers.

Connections