Apache Proxy Protocol
You enable the apache proxy protocol by turning on the remote IP module on your server. Then you configure your upstream load balancer to prepend client headers on each TCP stream. Engineering teams use this setup when load balancers sit in front of web servers. Without it, the web server only sees the internal IP address of the load balancer. Access logs lose the real source address of the visitor. Teams also struggle when server roles or network permissions are too broad. If any internal host
Database Proxy (ProxySQL, PgBouncer) + Model Context Protocol (MCP) Security: the complete guide
Architecture patterns, implementation strategies, and security best practices. Delivered to your inbox.
You enable the apache proxy protocol by turning on the remote IP module on your server. Then you configure your upstream load balancer to prepend client headers on each TCP stream.
Engineering teams use this setup when load balancers sit in front of web servers. Without it, the web server only sees the internal IP address of the load balancer. Access logs lose the real source address of the visitor. Teams also struggle when server roles or network permissions are too broad. If any internal host can send header data, attackers can spoof their origin IP address. You must restrict which upstream hosts your web server trusts before turning this feature on.
How the apache proxy protocol works in practice
Standard network load balancers route traffic at the transport layer. They accept a TCP request from a user and open a connection to Apache. During this step, the load balancer replaces the user source IP with its own IP. HTTP headers like X-Forwarded-For can store the client IP for plain web traffic. Still, transport layer load balancers do not read or change encrypted HTTPS traffic. They cannot inject HTTP headers when they pass raw TLS packets straight to the backend.
The apache proxy protocol fixes this problem at the start of the TCP handshake. Before sending any app data, the load balancer adds a small header to the stream. This header holds the real client IP address, the destination IP, and both port numbers. The protocol supports a human-readable text format and a compact binary format. Both formats deliver the exact same network metadata to the receiving server.
When the packet reaches Apache, the remote IP module reads this header first. It strips the header out so the web app does not break. Then it updates the internal request record with the real client IP address. From that point on, Apache logs and access rules use the true visitor IP. You must also define a trusted list of load balancer IP addresses in Apache. The server will only accept header metadata from network addresses on that trusted list.
What the native setup solves and where it stops
This native setup solves a major logging and network visibility problem for platform teams. Your error logs and access logs now show the real client network address. Rate limiting tools and IP allowlists work again behind a transport layer load balancer. Security teams can trace bad web requests back to an external IP address. It also keeps end-to-end TLS intact between the load balancer and the backend host.
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.
Still, network headers only tell you where a TCP packet came from. They do not tell you which engineer or service is behind an admin session. When engineers manage servers or databases, IP rules only decide which host can connect. Once a user logs in, the protocol cannot inspect or limit what commands run. A valid IP address does not stop someone from running a bad query. It also cannot rewrite sensitive fields like emails, phone numbers, or card numbers in results.
Securing upstream trust and port routing
When you turn on this protocol on a port, every connection must send the header. If a health check or internal user connects directly without the header, Apache drops it. Teams handle this by running a separate listener port for direct internal traffic. You can also exclude specific internal subnets from requiring the header on that port.
Keep your trusted upstream IP list small and strict in your firewall rules. Never allow public internet traffic to reach the backend port directly without the load balancer. If a user bypasses the load balancer, they can write fake IP headers into the stream. Strict network rules ensure only your load balancer can set the client IP address.
Govern statements and responses across databases and APIs
Good config and scoped roles are needed setup. They do not check single queries in flight or mask sensitive fields in returned rows. Across Postgres, MySQL, SQL Server, MongoDB, ClickHouse, Kubernetes APIs, SSH, and internal HTTP endpoints, hoop.dev runs beside each supported service as an open-source proxy, a sidecar for your database or API.
First, hoop.dev guardrails block banned queries before they run. Then hoop.dev data masking rewrites matched sensitive values in responses in memory. The audit trail records every statement and verdict per resource. Furthermore, hoop.dev holds SOC 2 Type II and is open source on GitHub.
Frequently asked questions
What is the difference between this protocol and X-Forwarded-For?
X-Forwarded-For is an HTTP header that works only when the load balancer reads HTTP traffic. The proxy protocol works at the TCP layer, so it supports encrypted TLS passthrough traffic.
Can normal browsers talk directly to a port using this protocol?
No, standard web browsers do not send the required TCP header when they connect. All traffic to that port must pass through a load balancer that adds the header.
Does the apache proxy protocol encrypt traffic between hosts?
No, the protocol only adds a small metadata header to the start of a connection. You must still use TLS on your listener to encrypt the actual data in transit.
Related guides
In this post