Skip to content
Stand with Ukraine flag

PROXY protocol

The PROXY Protocol safely transports connection metadata — such as the real client IP and port — across proxies and load balancers.

TBMQ supports both PROXY Protocol v1 and v2, enabling it to receive the actual client IP rather than the address of the proxy. This is critical for accurate logging, IP-based access control, rate limiting, and auditing.

  • PROXY Protocol v1 — a human-readable ASCII format that prepends connection metadata (client IP, port) to the TCP stream.
  • PROXY Protocol v2 — a binary format that carries the same information as v1 but with better performance in high-throughput environments.

By supporting PROXY Protocol, TBMQ can log, filter, and apply policies based on the real IP address of clients, which is otherwise masked by the proxy or load balancer.

The proxy sends a PROXY Protocol header at the very start of the TCP stream, before any MQTT or TLS data.

The connection follows this flow:

  1. The proxy accepts the TCP connection from the client.
  2. The proxy immediately sends a PROXY Protocol header containing the client source IP and port, destination IP and port, and protocol type (TCP over IPv4 or IPv6).
  3. TBMQ reads the header, extracts the real client information, then continues:
    • Plain MQTT/WS: processes the MQTT CONNECT packet.
    • TLS-secured MQTT/WS: proceeds with the TLS handshake.

PROXY Protocol v1 header example (ASCII):

PROXY TCP4 192.0.2.1 198.51.100.1 12345 1883\r\n

PROXY Protocol v2 uses a compact binary format suitable for high-performance environments.

This means TBMQ treats the very first bytes of every incoming connection as PROXY Protocol data, before interpreting it as MQTT or TLS.

Enable PROXY Protocol in TBMQ when:

  • TBMQ is deployed behind a load balancer or reverse proxy (e.g., HAProxy, AWS NLB, NGINX) that supports PROXY Protocol.
  • You need the real client IP for logging, IP-based security policies, rate limiting, or auditing.

TBMQ stores the client IP as part of session information and uses it in the Unauthorized Clients feature, where it tracks connection attempts from clients that fail authentication. Having the correct IP address helps identify the source of unauthorized access attempts and improves security monitoring. Without PROXY Protocol, TBMQ sees only the proxy’s IP, making it impossible to distinguish individual clients.

PROXY Protocol applies to all MQTT listeners globally:

listener:
# Enable PROXY Protocol support. Disabled by default. Supports both v1 and v2 when enabled.
proxy_enabled: "${MQTT_PROXY_PROTOCOL_ENABLED:false}"

Set MQTT_PROXY_PROTOCOL_ENABLED to true to enable PROXY Protocol for all listeners.

Since TBMQ v2.3 — per-listener overrides

Section titled “Since TBMQ v2.3 — per-listener overrides”

In addition to the global setting, each listener can be configured independently. Per-listener values default to unset and inherit the global value. If explicitly set, the per-listener value overrides the global one.

listener:
# Global PROXY Protocol setting for all listeners
proxy_enabled: "${MQTT_PROXY_PROTOCOL_ENABLED:false}"
tcp:
# Inherits global value if unset. Overrides global if explicitly set.
proxy_enabled: "${MQTT_TCP_PROXY_PROTOCOL_ENABLED:}"
ssl:
proxy_enabled: "${MQTT_SSL_PROXY_PROTOCOL_ENABLED:}"
ws:
proxy_enabled: "${MQTT_WS_PROXY_PROTOCOL_ENABLED:}"
wss:
proxy_enabled: "${MQTT_WSS_PROXY_PROTOCOL_ENABLED:}"

Example:

MQTT_PROXY_PROTOCOL_ENABLED=true # globally enabled
MQTT_TCP_PROXY_PROTOCOL_ENABLED=false # TCP listener explicitly disabled
MQTT_SSL_PROXY_PROTOCOL_ENABLED= # TLS listener unset → inherits global → enabled

To use PROXY Protocol v1:

server tbmq1 192.168.1.100:1883 send-proxy

send-proxy instructs HAProxy to send PROXY Protocol v1 headers to TBMQ.

To use PROXY Protocol v2:

server tbmq1 192.168.1.100:1883 send-proxy-v2

send-proxy-v2 instructs HAProxy to send PROXY Protocol v2 headers to TBMQ.

Replace 192.168.1.100:1883 with your TBMQ broker’s IP and port. For the full HAProxy guide, see the HAProxy PROXY Protocol documentation.

AWS NLB supports PROXY Protocol v2 only. Ensure your NLB is TCP or TLS type, then enable PROXY Protocol v2 with the AWS CLI:

Terminal window
aws elbv2 modify-target-group-attributes \
--target-group-arn <your-target-group-arn> \
--attributes Key=proxy_protocol_v2.enabled,Value=true

In a Kubernetes environment, add this annotation to your Service:

service.beta.kubernetes.io/aws-load-balancer-proxy-protocol: "*"

The * value enables PROXY Protocol v2 for all source IPs. For details, see the AWS Load Balancer Controller documentation.

Any load balancer that supports PROXY Protocol works with TBMQ — including Google Cloud Load Balancer, Azure Load Balancer, and NGINX. Enable PROXY Protocol on your load balancer according to its documentation, then enable it on the TBMQ side.

  • If PROXY Protocol is enabled in TBMQ but not on the proxy, TBMQ fails to parse the initial bytes and may reject connections.
  • If PROXY Protocol is enabled on the proxy but not in TBMQ, the header is misinterpreted as MQTT or TLS data, causing connection errors.
  • All connections to TBMQ must pass through a properly configured proxy when PROXY Protocol is enabled.
  • PROXY Protocol must only be configured when TBMQ is behind a trusted proxy, as the proxy defines the reported client IP.