Permalink
Browse files

Add README from balabit.com - it's nice doc about TPROXY.

  • Loading branch information...
darkk committed Dec 4, 2012
1 parent 0a491b0 commit 778340243e09c53e73573e5e08268b9b75abfce0
Showing with 235 additions and 0 deletions.
  1. +235 −0 doc/balabit-TPROXY-README.txt
@@ -0,0 +1,235 @@
+
+These are the Transparent Proxying patches for Linux kernel 2.6.
+
+The latest version can always be found at
+
+ http://www.balabit.com/download/files/tproxy/
+
+
+What does the term 'proxy' mean?
+--------------------------------
+
+ A proxy is a server-like program, receiving requests from clients,
+ forwarding those requests to the real server on behalf of users,
+ and returning the response as it arrives.
+
+ Proxies read and parse the application protocol, and reject invalid
+ traffic. As most attacks violate the application protocol, disallowing
+ protocol violations usually protects against attacks.
+
+What is transparent proxying?
+-----------------------------
+
+ To simplify management tasks of clients sitting behind proxy
+ firewalls, the technique 'transparent proxying' was invented.
+ Transparent proxying means that the presence of the proxy is invisible
+ to the user. Transparent proxying however requires kernel support.
+
+We have a 'REDIRECT' target, isn't that enough?
+----------------------------------------------
+
+ Real transparent proxying requires the following three features from
+ the IP stack of the computer it is running on:
+ 1. Redirect sessions destined to the outer network to a local process
+ using a packet filter rule.
+ 2. Make it possible for a process to listen to connections on a
+ foreign address.
+ 3. Make it possible for a process to initiate a connection with a
+ foreign address as a source.
+
+ Item #1 is usually provided by packet filtering packages like
+ Netfilter/IPTables, IPFilter. (yes, this is the REDIRECT target)
+
+ All three were provided in Linux kernels 2.2.x, but support for this
+ was removed.
+
+How to install it?
+------------------
+
+ Download the latest tproxy-kernel-<kernelversion>*.tar.bz2 tarball
+ for your kernel (from v2.6.24), with the tproxy-iptables-*.patch file.
+
+ Patch your kernel using:
+
+ cd /usr/src/linux
+ cat <path_to_tproxy>/00*.patch | patch -p1
+
+ then enable tproxy support, `socket' and `TPROXY' modules
+ (with optional conntrack support if you need SNAT), compile your kernel
+ and modules.
+
+ The required modules are automatically loaded if the iptables commands
+ are used.
+
+ The IPtables patches:
+
+ cd /usr/src/iptables-1.4.X
+ cat <path_to_tproxy>/tproxy-iptables*.patch | patch -p1
+
+ then compile it on the usual way:
+
+ ./autogen.sh
+ ./configure && make && make install
+
+ Squid-3 has official support of TProxy v4.1:
+
+ checkout the source code of squid-3 as in
+
+ http://wiki.squid-cache.org/Squid3VCS
+
+
+ then compile it:
+
+ cd ~/source/squid
+ ./bootstrap.sh
+ ./configure --enable-linux-netfilter && make && make install
+
+ Of course you might need to change the path in the examples above.
+
+How to start using it?
+----------------------
+
+ This implementation of transparent proxying works by marking packets and
+ changing the route based on packet mark. The foreign address bind and tproxy
+ redirection is enabled via a new socket option, IP_TRANSPARENT, without it
+ neither the bind nor the tproxy target works.
+
+ Now let's see what happens when a proxy tries to use the required tproxy
+ features I outlined earlier.
+
+ 1. Redirection
+
+ This is easy, as this was already supported by iptables. Redirection is
+ equivalent with the following nat rule:
+
+ iptables -t nat -A PREROUTING -j DNAT --to-dest <localip> --to-port <proxyport>
+
+ <localip> is one the IP address of the interface where the packet
+ entered the IP stack
+ <proxyport> is the port where the proxy was bound to
+
+ To indicate that this is not simple NAT rule, a separate target, 'TPROXY'
+ was created:
+
+ iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY --on-port <proxyport> \
+ --tproxy-mark 0x1/0x1
+
+ The local IP address is determined automatically, but can be overridden
+ by the --on-ip parameter.
+
+ The marked sockets has to be routed locally:
+
+ ip rule add fwmark 1 lookup 100
+ ip route add local 0.0.0.0/0 dev lo table 100
+
+
+ 2. Listening for connections on a foreign address
+
+ There are protocols which use more than a single TCP channel for
+ communication. The best example is FTP which uses a command channel for
+ sending commands, and a data channel to transfer the body of files. The
+ secondary channel can be established in both active and passive mode,
+ active meaning the server connects back to the client, passive meaning
+ the client connects to the server on another port.
+
+ Let's see the passive case, when the client establishes a connection to
+ the address returned in the response of the PASV FTP command.
+
+ As the presence of the proxy is transparent to the client, the target
+ IP address of the secondary channel (e.g. the address in the PASV
+ response) is the server (and not the firewall) and this connection must
+ also be handled by the proxy.
+
+ The first solution that comes to mind is to add a a TPROXY rule
+ automatically (e.g. to redirect a connection destined to a given server
+ on a given port to a local process), however it is not feasible, adding
+ rules on the fly should not be required as it would mess the
+ administrator's own rules, the NAT translation should be done
+ implicitly without touching the user rulebase.
+
+ To do this on a Linux 2.2 kernel it was enough to call bind() on a
+ socket with a foreign IP address, and if a new connection to the given
+ foreign IP was routed through the firewall the connection was
+ intercepted. This solution however distracted the core network kernel
+ hackers and removed this feature. This implementation is similar to
+ the old behaviour although it works a bit differently:
+
+ * the proxy sets the IP_TRANSPARENT socket option on the listening
+ socket
+ * the proxy then binds to the foreign address
+ * the proxy accepts incoming connections
+
+ It requires additional iptables rules with the socket module of the
+ tproxy patches:
+
+ iptables -t mangle -N DIVERT
+ iptables -t mangle -A PREROUTING -p tcpo -m socket -j DIVERT
+ iptables -t mangle -A DIVERT -j MARK --set-xmark 0x1/0xffffffff
+ iptables -t mangle -A DIVERT -j ACCEPT
+
+ the best if the second rule is before using the TPROXY target.
+
+ 3. Initiating connections with a foreign address as a source
+
+ Similarly to the case outlined above, it is sometimes necessary to be
+ able to initiate a connection with a foreign IP address as a source.
+ Imagine the active FTP case when the FTP client listens for connections
+ with source address equal to the server. Another example: a webserver
+ in your DMZ which does access control based on client IP address. If
+ the proxy could not initiate connections with foreign IP address, the
+ webserver would see the inner IP address of the firewall itself.
+
+ In Linux 2.2 this was accomplished by bind()-ing to a foreign address
+ prior calling connect(), and it worked. In this tproxy patch it is done
+ somewhat similar to the case 2 outlined above.
+
+ * the proxy calls setsockopt with IP_TRANSPARENT
+
+ * the proxy bind to a foreign address
+
+ * the tproxy calls connect()
+
+ The iptables rules with the socket match are also required here.
+
+How to use it?
+--------------
+
+ The following use-case assumes a transparent proxy listening on port
+ 50080 and any ip address (0.0.0.0).
+
+ First, set up the routing rules with iproute2:
+
+ ip rule add fwmark 1 lookup 100
+ ip route add local 0.0.0.0/0 dev lo table 100
+
+ Or, if you want to use packet marking for anything else, the least
+ significant bit is enough for transparent proxying.
+
+ ip rule add fwmark 0x1/0x1 lookup 100
+ ip route add local 0.0.0.0/0 dev lo table 100
+
+ Note that this latter example is only working with newer versions of
+ iproute2.
+
+ For supporting foreign address bind, the socket match is required with
+ packet marking:
+
+ iptables -t mangle -N DIVERT
+ iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
+
+ # DIVERT chain: mark packets and accept
+ iptables -t mangle -A DIVERT -j MARK --set-mark 1
+ iptables -t mangle -A DIVERT -j ACCEPT
+
+ The last rule is for diverting traffic to the proxy:
+
+ iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
+ --tproxy-mark 0x1/0x1 --on-port 50080
+
+ If it is a Squid-3 proxy, in /etc/squid/squid.conf the following
+ rule is necessary for transparent proxying:
+
+ http_port 50080 tproxy transparent
+
+ Then set up the ACL rules according to your local policy.
+

0 comments on commit 7783402

Please sign in to comment.