[tproxy] tproxy4 future

Balazs Scheidler bazsi at balabit.hu
Tue Sep 18 12:01:29 CEST 2007


As some of you might know, the 5th Netfilter Developer's Workshop took
place last week in Karlsruhe, Germany. Krisztian Kovacs (hidden) and me
attended the workshop and tried to merge the somewhat diverged work on

The fork of the tproxy code was caused by a change of maintenance, thus
some of the latest work of Krisztian was left out from the latest 4.0.x
patches released by Panther. (more exactly the "socket" match and the
mark based diversion code).

On the workshop we merged our efforts again in order to get acceptance
of the Linux net/netfilter maintainers. (DaveM and Patrick McHardy).

This will again change the way tproxy should be used. 

Sorry for breaking compatibility again, and the whole confusion, hopefully 
the results will be a tproxy functionality merged in the Linux kernel. :)

The most important changes relative to the current 4.0.x patches are:
 * the tproxy table is gone, TPROXY targets need to be added to the
mangle table instead
 * the tproxy match is gone, a new "socket" match is introduced
 * instead of using a separate routing trick to divert packets to the
local IP stack inside the TProxy target, we are now using stock routing
decisions, and need a bit in the packet MARK field, and perform
diversion by using an advanced routing rule.
 * instead of IP_FREEBIND we are using a setsockopt named IP_TRANSPARENT
which requires CAP_NET_ADMIN privilege
 * in previous patches the output routing decision was commented out, it
is now correctly decided whether a packet belongs to a tproxied
connection or not.

These are the major changes, now here's a script that demonstrates
TProxy usage:

1) create advanced routing rules

We are using the lowest bit of the packet MARK value to indicate that 
the packet was diverted by the TProxy code. The exact bit value can be 

Commands to set this up:

ip rule add fwmark 1 lookup 100
ip route add local dev lo table 100

2) create TProxy rules in the mangle table

# create a chain named DIVERT
iptables -t mangle -N DIVERT

# everything that matches "-m socket" should go to the local stack
iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT

# connections to be redirected should use the TPROXY target, which sets 
# up redirection, and marks the packet according to its 'tproxy-mark' 
# argument
iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --tproxy-mark 0x1/0x1 --on-port 50080

# DIVERT chain: mark packets and accept
iptables -t mangle -A DIVERT -j MARK --set-mark 1
iptables -t mangle -A DIVERT -j ACCEPT

The ruleset would be much simpler if iptables would support ebtables 
like multiple targets, which it is going to. In that case the rules would become:

iptables -t mangle -A PREROUTING -p tcp -m socket -j MARK --set-mark 1 -j ACCEPT
iptables -t mangle -A PREROUTING -p tcp --dport 80 j MARK --set-mark 1 -j TPROXY --on-port 50080

Hopefully this will also be implemented soon.

I have done some functionality testing on the patchset, and things like 
redirection did work. We'll start some more testing this week, however 
more tests never hurt. We'd appreciate if someone could help us 
with testing.

The latest patchset is available at:


Some documentation and manual pages are still missing, but we are working on that 
issue as well.


More information about the tproxy mailing list