Skip to content

/glossary/nginx/reverse-proxy

What is a reverse proxy?

verified onenvironmentlocal · windows 10.0.26200 arm64 · GNU bash 5.3.15 (Git Bash) · nginx version: nginx/1.30.6updated 2026-10-20
tool
nginx
versions
nginx 1.x
os
any

A reverse proxy sits in front of one or more backend servers. Clients connect to the proxy as if it were the site; the proxy forwards each request to a backend and relays the response. Typical jobs: terminating TLS, routing paths or hostnames to different services, load balancing, caching, compression, and limiting request sizes. nginx, Caddy, HAProxy and Traefik are common reverse proxies.

A forward proxy is the opposite: it acts for clients (for example a corporate proxy) instead of for servers.

What the backend sees

Because the TCP connection now comes from the proxy, the backend sees the proxy's address. The proxy passes the original client details in headers:

bash
mkdir -p logs temp
cat > app.js <<'EOF'
const s = require("http").createServer((req, res) => {
  const h = (k) => req.headers[k] ?? "-";
  res.end(`socket ${req.socket.remoteAddress} | host ${h("host")} | x-forwarded-for ${h("x-forwarded-for")} | x-forwarded-proto ${h("x-forwarded-proto")}\n`);
});
s.listen(3921, "127.0.0.1");
setTimeout(() => process.exit(0), 4000);
EOF
cat > nginx.conf <<'EOF'
pid logs/nginx.pid;
events {}
http {
  access_log off;
  server {
    listen 127.0.0.1:3922;
    location / {
      proxy_pass http://127.0.0.1:3921;
      proxy_set_header Host $host;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
    }
  }
}
EOF
node app.js &
nginx -p . -c nginx.conf -e logs/error.log &
sleep 1
echo "direct:  $(curl -s -H 'Host: shop.example' http://127.0.0.1:3921/)"
echo "proxied: $(curl -s -H 'Host: shop.example' http://127.0.0.1:3922/)"
nginx -p . -c nginx.conf -e logs/error.log -s stop

Output

direct:  socket 127.0.0.1 | host shop.example | x-forwarded-for - | x-forwarded-proto -
proxied: socket 127.0.0.1 | host shop.example | x-forwarded-for 127.0.0.1 | x-forwarded-proto http

The application should read the client IP from X-Forwarded-For (or the standard Forwarded header) only when the request comes from a trusted proxy; otherwise clients can forge it. Frameworks have a setting for this, such as Express trust proxy or Django SECURE_PROXY_SSL_HEADER.

Sources