| 1 | |
| 2 |
|
| 3 | =========================
|
| 4 | Transparent proxy support
|
| 5 | =========================
|
| 6 |
|
| 7 | This feature adds Linux 2.2-like transparent proxy support to current kernels.
|
| 8 | To use it, enable the socket match and the TPROXY target in your kernel config.
|
| 9 | You will need policy routing too, so be sure to enable that as well.
|
| 10 |
|
| 11 | From Linux 4.18 transparent proxy support is also available in nf_tables.
|
| 12 |
|
| 13 | 1. Making non-local sockets work
|
| 14 | ================================
|
| 15 |
|
| 16 | The idea is that you identify packets with destination address matching a local
|
| 17 | socket on your box, set the packet mark to a certain value::
|
| 18 |
|
| 19 | # iptables -t mangle -N DIVERT
|
| 20 | # iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j DIVERT
|
| 21 | # iptables -t mangle -A DIVERT -j MARK --set-mark 1
|
| 22 | # iptables -t mangle -A DIVERT -j ACCEPT
|
| 23 |
|
| 24 | Alternatively you can do this in nft with the following commands::
|
| 25 |
|
| 26 | # nft add table filter
|
| 27 | # nft add chain filter divert "{ type filter hook prerouting priority -150; }"
|
| 28 | # nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept
|
| 29 |
|
| 30 | And then match on that value using policy routing to have those packets
|
| 31 | delivered locally::
|
| 32 |
|
| 33 | # ip rule add fwmark 1 lookup 100
|
| 34 | # ip route add local 0.0.0.0/0 dev lo table 100
|
| 35 |
|
| 36 | Because of certain restrictions in the IPv4 routing output code you'll have to
|
| 37 | modify your application to allow it to send datagrams _from_ non-local IP
|
| 38 | addresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
|
| 39 | option before calling bind::
|
| 40 |
|
| 41 | fd = socket(AF_INET, SOCK_STREAM, 0);
|
| 42 | /* - 8< -*/
|
| 43 | int value = 1;
|
| 44 | setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
|
| 45 | /* - 8< -*/
|
| 46 | name.sin_family = AF_INET;
|
| 47 | name.sin_port = htons(0xCAFE);
|
| 48 | name.sin_addr.s_addr = htonl(0xDEADBEEF);
|
| 49 | bind(fd, &name, sizeof(name));
|
| 50 |
|
| 51 | A trivial patch for netcat is available here:
|
| 52 | http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
|
| 53 |
|
| 54 |
|
| 55 | 2. Redirecting traffic
|
| 56 | ======================
|
| 57 |
|
| 58 | Transparent proxying often involves "intercepting" traffic on a router. This is
|
| 59 | usually done with the iptables REDIRECT target; however, there are serious
|
| 60 | limitations of that method. One of the major issues is that it actually
|
| 61 | modifies the packets to change the destination address -- which might not be
|
| 62 | acceptable in certain situations. (Think of proxying UDP for example: you won't
|
| 63 | be able to find out the original destination address. Even in case of TCP
|
| 64 | getting the original destination address is racy.)
|
| 65 |
|
| 66 | The 'TPROXY' target provides similar functionality without relying on NAT. Simply
|
| 67 | add rules like this to the iptables ruleset above::
|
| 68 |
|
| 69 | # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
|
| 70 | --tproxy-mark 0x1/0x1 --on-port 50080
|
| 71 |
|
| 72 | Or the following rule to nft::
|
| 73 |
|
| 74 | # nft add rule filter divert tcp dport 80 tproxy to :50080 meta mark set 1 accept
|
| 75 |
|
| 76 | Note that for this to work you'll have to modify the proxy to enable (SOL_IP,
|
| 77 | IP_TRANSPARENT) for the listening socket.
|
| 78 |
|
| 79 | As an example implementation, tcprdr is available here:
|
| 80 | https://git.breakpoint.cc/cgit/fw/tcprdr.git/
|
| 81 | This tool is written by Florian Westphal and it was used for testing during the
|
| 82 | nf_tables implementation.
|
| 83 |
|
| 84 | 3. Iptables and nf_tables extensions
|
| 85 | ====================================
|
| 86 |
|
| 87 | To use tproxy you'll need to have the following modules compiled for iptables:
|
| 88 |
|
| 89 | - NETFILTER_XT_MATCH_SOCKET
|
| 90 | - NETFILTER_XT_TARGET_TPROXY
|
| 91 |
|
| 92 | Or the floowing modules for nf_tables:
|
| 93 |
|
| 94 | - NFT_SOCKET
|
| 95 | - NFT_TPROXY
|
| 96 |
|
| 97 | 4. Application support
|
| 98 | ======================
|
| 99 |
|
| 100 | 4.1. Squid
|
| 101 | ----------
|
| 102 |
|
| 103 | Squid 3.HEAD has support built-in. To use it, pass
|
| 104 | '--enable-linux-netfilter' to configure and set the 'tproxy' option on
|
| 105 | the HTTP listener you redirect traffic to with the TPROXY iptables
|
| 106 | target.
|
| 107 |
|
| 108 | For more information please consult the following page on the Squid
|
| 109 | wiki: http://wiki.squid-cache.org/Features/Tproxy4
|