[tproxy] tproxy4 future
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
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 0.0.0.0/0 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'
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
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