Caddy Proxy Protocol

Published
Length
3 min read

Luis Felipe Dias

All posts

You set up the caddy proxy protocol by adding a listener wrapper in your server rules. This wrapper reads the real client IP address from an upstream load balancer before TLS starts. Teams use this setup when a cloud load balancer sits in front of their web servers. Without it, every log entry shows the internal IP of the load balancer. If teams leave trusted IP ranges too broad, attackers can send fake headers and spoof their origin address. How the caddy proxy protocol works in your network

Database Proxy (ProxySQL, PgBouncer) + Model Context Protocol (MCP) Security: the complete guide

Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.

Free white paper. No spam. Unsubscribe anytime.

You set up the caddy proxy protocol by adding a listener wrapper in your server rules. This wrapper reads the real client IP address from an upstream load balancer before TLS starts. Teams use this setup when a cloud load balancer sits in front of their web servers. Without it, every log entry shows the internal IP of the load balancer. If teams leave trusted IP ranges too broad, attackers can send fake headers and spoof their origin address.

How the caddy proxy protocol works in your network

Standard HTTP traffic uses text headers to pass client details down the line. Still, layer four load balancers forward raw TCP packets without reading HTTP headers. The proxy protocol solves this gap by adding a small header at the start of the TCP stream. This header holds the original source IP, the destination IP, and both port numbers.

When a packet arrives, the web server must read this metadata before doing anything else. In your server settings, you place the protocol wrapper ahead of the TLS handshake handler. This order matters because the server cannot decrypt TLS until it strips off the raw TCP prefix. Once the server reads the prefix, it swaps the load balancer IP with the true client IP. Downstream apps and access logs then see the real visitor address.

To keep this safe, you must define a strict list of trusted upstream CIDR ranges. The server checks the direct peer address against this allowlist on every new connection. If the peer IP matches a trusted load balancer, the server accepts the attached client IP. You can also set a short timeout so slow or broken connections drop right away.

Managing upstream trust and network policies

Admins also have to pick a policy for traffic that arrives without a header. If all traffic flows through one load balancer, the server should reject raw connections right away. If some internal services talk to the web server directly, the policy might allow empty headers from trusted subnets. Getting this rule wrong breaks traffic or opens a big security hole.

Version one of the spec uses plain text, while version two uses a binary format. Most modern cloud load balancers support both formats without extra work. The web server detects the version on its own when the TCP handshake finishes. Teams just need to make sure the upstream load balancer turns the feature on first. If only one side turns it on, every request will fail with a broken stream error.

Database Proxy (ProxySQL, PgBouncer) + Model Context Protocol (MCP) Security: architecture patterns and best practices

Continue reading? Get the full guide.

Free. No spam. Unsubscribe anytime.

What the native setup solves and where gaps remain

Turning on the caddy proxy protocol fixes blind spots in your web server logs and IP rate limiters. Your security tools can block bad actors by their true public IP instead of blocking your own load balancer. It also lets geo-blocking rules work as expected at the edge of your network.

Still, network headers only tell you where a packet came from on the internet. This setup does not control what an engineer or service does once a session starts. A valid source IP does not prove who is at the keyboard or check the commands they run. Network rules decide which hosts can talk, not what actions happen inside the session. Teams that manage databases and internal servers need deeper controls that work at the command level.

Add runtime guardrails and masking beside your databases and APIs

Login rules, role grants, and CI checks govern who connects to your stack. Yet any allowed script, engineer, or AI agent still runs commands with the full scope of its role. For workloads on Postgres, MySQL, SQL Server, MongoDB, ClickHouse, Kubernetes, SSH, or internal HTTP services, hoop.dev sits inline in the protocol beside the service as an open-source proxy, a sidecar for your database or API. On every production query an agent or human runs, hoop.dev decides whether to pass, mask, block, or escalate it for review.

Before a query runs, hoop.dev guardrails check the statement against your rules, an AI Analyzer you configure can score intent or hold risky calls for human approval, and hoop.dev data masking rewrites sensitive fields in responses in memory. Explore the MIT-licensed project on GitHub.

Frequently asked questions

Why do my TLS connections fail after turning on the protocol?

TLS fails if the listener order is wrong or the upstream load balancer does not send the header. Make sure the wrapper runs before TLS termination and verify your load balancer settings.

How do I stop attackers from spoofing their IP address?

You must set a strict allowlist of trusted IP ranges that belong only to your load balancers. Never trust all IP addresses, or any client can send a fake header from the public web.

What is the difference between HTTP forwarded headers and this protocol?

HTTP forwarded headers work at layer seven and require the load balancer to read and rewrite web traffic. This protocol works at layer four on raw TCP streams, so it supports encrypted passthrough traffic.

Save the open-source gateway.

hoop is MIT-licensed infrastructure for controlling how AI agents reach production data. Star hoophq/hoop so you can inspect it, deploy it, or share it when your team starts governing agent access.