Skip to main content
Version: 4.x

Preserve the client IP with PROXY protocol

When a Phoenix AI cluster is placed behind a Layer-4 (TCP) load balancer, the Coordinator Nodes (FEs) may see the load balancer's IP address as the source of every connection instead of the real client. This causes two problems:

  • IP-restricted accounts (for example, 'user'@'203.0.113.10') cannot be matched correctly, because the connection appears to come from the load balancer.
  • Audit logs and the PROCESSLIST record the load balancer's IP instead of the actual client IP.

Whether you hit this depends on your load balancer:

  • AWS Network Load Balancer (NLB) with client IP preservation, same region: When the NLB has client IP preservation enabled and the client is in the same region as the cluster, the NLB transparently preserves the real client IP at the network layer. In this case the FE already sees the real client IP, and you do not need PROXY protocol.
  • Other cases — for example HAProxy, cross-region NLB traffic, or any proxy where client IP preservation is unavailable — the FE sees the load balancer's IP. Use PROXY protocol to recover the real client address.

Starting from kernel version 4.1.2, Phoenix supports the HAProxy PROXY protocol v1 on the MySQL port (9030). When PROXY protocol is enabled, a trusted load balancer prepends a small text header to each connection that carries the real client IP and port. Phoenix parses this header and uses the real client address for authentication, the PROCESSLIST, and audit logging.

note

Only PROXY protocol v1 (the human-readable text format) is supported. Both TCP4 (IPv4) and TCP6 (IPv6) source addresses are accepted.

Configuration parameters

PROXY protocol support is controlled by the following Coordinator Node (FE) parameters. Both parameters are dynamic.

ParameterDefaultDescription
mysql_proxy_protocol_networks"" (empty)Controls which upstream peers are trusted to supply a PROXY protocol v1 header on port 9030.
  • "" (empty, the default): PROXY protocol is disabled. All connections use the TCP peer address.
  • *: Accept PROXY headers from any peer. Not recommended in production.
  • A semicolon-separated list of IPv4/IPv6 CIDR ranges (for example, 10.0.0.0/8;192.168.1.0/24): Only connections from these ranges are expected to carry a PROXY header. Connections from other peers are served directly without PROXY parsing.
mysql_proxy_protocol_header_timeout_ms1000Timeout, in milliseconds, for reading a PROXY protocol v1 header from a trusted peer. Applies only when the peer address matches mysql_proxy_protocol_networks. If the header is not fully received within this window, the connection is closed with an error. Set to 0 to wait indefinitely (not recommended).

If a trusted peer is expected to send a PROXY header but sends a missing or malformed one (or none within the timeout), the connection is rejected and a warning similar to the following is logged on the Coordinator Node:

PROXY protocol header required but not received: <reason>
warning

A peer that can supply a PROXY protocol header can spoof any client IP, including IPs used by privileged accounts. Only add the IP ranges of your trusted load balancers to mysql_proxy_protocol_networks. Never set it to * in a production environment that is reachable by untrusted clients.

How it works

  1. The load balancer is configured to send a PROXY protocol v1 header at the start of each TCP connection to port 9030.
  2. Phoenix checks whether the connecting peer (the load balancer) is in the trusted networks defined by mysql_proxy_protocol_networks.
    • If the peer is trusted, Phoenix reads and parses the PROXY header, then replaces the connection's source address with the real client IP and port from the header.
    • If the peer is not trusted, the connection is served directly using the TCP peer address, and no PROXY header is expected.
  3. Health-check connections that use the UNKNOWN family (for example, PROXY UNKNOWN\r\n) are accepted and fall back to the TCP peer address.

Enable PROXY protocol

Follow these steps to enable PROXY protocol for a cluster:

  1. Configure your load balancer to send a PROXY protocol v1 header on the listener that forwards to Phoenix port 9030. For example, configure HAProxy with send-proxy on the corresponding server line.

    note

    Only the v1 (text) header is supported; the binary v2 header is not. The AWS Network Load Balancer's native PROXY protocol support emits the v2 header and is therefore not compatible with this feature. If you are using an NLB and your clients are in the same region as the cluster, prefer the NLB's client IP preservation instead — it requires no PROXY protocol configuration. Use PROXY protocol with a proxy such as HAProxy that emits the v1 header.

  2. In the Phoenix Cloud console, set the Coordinator Node parameters mysql_proxy_protocol_networks and mysql_proxy_protocol_header_timeout_ms to the trusted load balancer ranges and your preferred timeout. For instructions on configuring Coordinator Node parameters from the console, see Configure Static Parameters.

    For example, to trust load balancers in 10.0.0.0/8:

    mysql_proxy_protocol_networks = 10.0.0.0/8
    mysql_proxy_protocol_header_timeout_ms = 1000
  3. Verify that connections through the load balancer report the real client IP, for example by inspecting the audit log or running SHOW PROCESSLIST and confirming the Host column shows the client address rather than the load balancer address.