How do I pass the real client IP for non-HTTP TCP services?
Short answer
Since an HTTP header cannot be added, there are three ways: on an L7 TCP vService, if the server supports it, the PROXY protocol (Proxy or Proxy v2) is turned on in the Proxy field of the Backend Service; if no setting can be made on the server, Use Client IP is selected in the SNAT field and, for the responses to return through TR7, TR7 is made the default gateway of the servers or Spoofing is turned on; on a Network vService, Route Mode or Direct Server Return is selected as the LB Mode. X-Forwarded-For and the header actions work only on an HTTP vService.
Problem: The SMTP, Database or Custom Protocol Server Cannot See the Client
Servers running e-mail, database, directory or custom TCP protocols use the client IP for security rules (e.g. the sender IP check in SMTP), logging and authorization. On an L7 TCP vService, since TR7 connects to the server with its own address (SNAT Default) and an HTTP header cannot be added to these protocols, the client IP must be carried at the connection level.
Solution: 3 Methods
The methods are alternatives to each other; they are chosen according to the vService type, whether the server supports the PROXY protocol, and the network layout.
| Your situation | Suitable method |
|---|---|
| L7 TCP; the server supports the PROXY protocol (e.g. Postfix, Dovecot, Nginx stream) | Method 1: L7 TCP + PROXY protocol |
| L7 TCP; no setting can be made on the server, TR7 can be made the gateway of the servers or Spoofing can be used | Method 2: L7 TCP + Use Client IP |
| Network vService (TCP - L4 / UDP - L4) | Method 3: LB mode on the Network vService |
Method 1: L7 TCP + PROXY Protocol Recommended
- How it works At the beginning of every connection, TR7 sends the PROXY preliminary information carrying the client's IP and port; the server uses this information as the client address. No change is needed on the network.
- Where it is openedLoad Balancer → Backend Services → Edit → Details → Proxy
- Requirement The server supports the PROXY protocol and is configured to expect it; the health check is of the TCP type or is performed on a separate port
- vService type L7 TCP, HTTP
Step-by-Step Configuration
Acceptance of the PROXY protocol is turned on on the server (e.g. smtpd_upstream_proxy_protocol = haproxy in Postfix, listen … proxy_protocol in Nginx stream); if it is turned on in TR7 before the server is prepared, connections cannot be established.
Health checks do not send the PROXY preliminary information; therefore, a health check of the TCP type is assigned to the Backend Service, or in step 7 a separate health port that does not expect PROXY is checked. If there is no profile of the TCP type, Load Balancer → Profiles → Health Checks → Add is clicked (How to add?); if the profile already exists, steps 2–4 are skipped.
The Name is entered and Check Type = TCP is selected (the default is HTTP; the type cannot be changed after saving).
The Add button in the form is clicked.
On the Load Balancer → Backend Services screen, the Backend Service is right-clicked and Edit is selected.
The Details switch at the bottom of the form is turned on.
In the Proxy field, the version supported by the server is selected: Proxy (v1, text) or Proxy v2 (binary). The default is No Proxy. In the Health Check field, the profile of the TCP type is selected, or in the Use Different IP for Health Check field, Different address is selected and a health address and port that do not expect PROXY are entered.
The Edit button at the bottom of the form is clicked; all the vServices that use the Backend Service inherit this behavior.
Verification
The client address of the connection is seen in the server log (e.g. the connect from line in Postfix).
connect from unknown[198.51.100.45]Method 2: L7 TCP + SNAT → Use Client IP
- How it works TR7 connects to the server with the client's IP; no application setting is needed on the server. Since the server sends the response to the client's address, the response must reach TR7.
- Where it is openedLoad Balancer → Backend Services → Edit → Details → SNAT → Use Client IP
- Requirement The responses return through TR7: the default gateway of the servers is TR7's IP on this network; if the gateway cannot be changed, Spoofing is turned on
- vService type L7 TCP, HTTP
Step-by-Step Configuration
The default gateway of the servers is set to TR7's IP on the same network as the servers (in a cluster, the VIP on this network). This change is made on the server or network side; if it cannot be made, Spoofing is turned on in step 5 (Is it possible to work without SNAT (transparent mode); what are the requirements?).
On the Load Balancer → Backend Services screen, the Backend Service is right-clicked and Edit is selected.
The Details switch at the bottom of the form is turned on.
In the SNAT field, Use Client IP is selected (the default is Default).
If the default gateway of the servers cannot be changed, Spoofing is turned on (visible only while Use Client IP is selected; off by default). If Spoofing IP is left empty, the default gateway of the Route table is targeted; in a cluster, Spoofing IP VIP Condition makes Spoofing work on the device where the VIP is active.
The Edit button at the bottom of the form is clicked.
Verification
The source address of the incoming connections is captured on the server (port 25 in the example).
tcpdump -n 'tcp dst port 25 and tcp[tcpflags] & tcp-syn != 0'IP 198.51.100.45.51234 > 192.0.2.20.25: Flags [S]Method 3: LB Mode on the Network vService
- How it works A Network vService does not terminate the connection; Route Mode and Direct Server Return forward the client IP to the server without changing it. This also applies to UDP services.
- Where it is opened Network vService → LB Mode
- Requirement Route Mode: the default gateway of the servers is TR7 · Direct Server Return: the servers are on the same L2 network as TR7 and are prepared to accept the vService address
- vService type Network (TCP - L4, UDP - L4; Port range off)
Step-by-Step Configuration
On the Load Balancer → Load Balancer vService List screen, the Network vService is selected and opened with Edit.
In the LB Mode field, Route Mode or Direct Server Return (default) is selected. While Protocol is ANY - L3 or Port range is on, the mode is not applied; in this case, if no SNAT IP is selected on the vService, the client IP is preserved and the response must return through TR7.
In Route Mode, TR7 is made the default gateway of the servers (Why does return traffic have to flow through TR7 in Route Mode?); in Direct Server Return, the vService address is defined as a local address on the server and the ARP response for this address is turned off (What is Direct Server Return (DSR); what preparation is needed on the server side?).
The Save button is clicked. On a Network vService, every save restarts the vService; the change is made at a low-traffic time.
Verification
The source address of the incoming connection is checked on the server.
tcpdump -n 'tcp dst port 25'IP 198.51.100.45.xxxxx > …Common Mistakes
- Selecting Use Client IP without preparing the return path. If the default gateway of the servers is not TR7 and Spoofing is off, the responses bypass TR7 and connections cannot be established.
- Looking for X-Forwarded-For on L7 TCP. The header is added only on an HTTP vService.
- Changing the Proxy or SNAT field of the Backend Service on a Network vService. A Network vService does not use these fields; the LB mode is decisive.
- Expecting the PROXY protocol or Use Client IP for UDP. UDP is only on the Network vService; the LB mode is used there.
How it is done in the documentation
