Compile HAProxy With TPROXY Support

After having compiled the kernel & iptables with tproxy last week, it’s time to stretch that config to HAproxy. If you haven’t compiled both your running kernel and iptables with tproxy, do that first – otherwise, this won’t work.

HAProxy is a marvelous load balancing tool, which by default has only 1 drawback: all the servers where HAProxy is load balancing for, will have the IP address of the load balancer in the logs, as all traffic is routed through it.

This can make it more annoying to debug, and could possibly break some applications that require a unique source IP from the client. To solve it, we’ll compile HAProxy with TPROXY support.

First up, download the latest version of HAProxy . Back in 2010 that was 1.4.8; today the current stable release is 3.4.x, so grab whatever is newest.

wget https://www.haproxy.org/download/3.4/src/haproxy-3.4.0.tar.gz

tar xzf haproxy-3.4.0.tar.gz

cd haproxy-3.4.0

And compile it. On a modern HAProxy the linux26/CPU=i386 targets are long gone, and TPROXY support is now built in by default for the linux-glibc target, so there’s no USE_LINUX_TPROXY=1 flag to pass anymore.

make TARGET=linux-glibc

make install TARGET=linux-glibc

The TARGET= line picks the build profile for a modern glibc-based Linux; transparent proxying (USE_TPROXY / USE_LINUX_TPROXY) is enabled automatically as part of that target. If you’re on a 2.6.28-era kernel, use TARGET=linux-glibc-legacy instead.

Let’s populate our iptable-rules.

vim /usr/bin/iptables_for_haproxy.sh

in the new file, copy/paste the following.

#!/bin/bash

iptables -t mangle -N DIVERT

iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT

iptables -t mangle -A DIVERT -j MARK –set-mark 111

iptables -t mangle -A DIVERT -j ACCEPT

ip rule add fwmark 111 lookup 100

ip route add local 0.0.0.0/0 dev lo table 100

Make it executable.

chmod +x /usr/bin/iptables_for_haproxy.sh

And if you prefer, you can add it to your /etc/rc.local for auto startup as well, so it’s executed whenever you reboot.

Now, this does require one more tricky bit.