Commit | Line | Data |
---|---|---|
4ac0b122 MCC |
1 | .. SPDX-License-Identifier: GPL-2.0 |
2 | ||
3 | ========================= | |
d2f26037 KK |
4 | Transparent proxy support |
5 | ========================= | |
6 | ||
7 | This feature adds Linux 2.2-like transparent proxy support to current kernels. | |
fd158d79 FW |
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. | |
d2f26037 | 10 | |
1bfc2bc7 | 11 | From Linux 4.18 transparent proxy support is also available in nf_tables. |
d2f26037 KK |
12 | |
13 | 1. Making non-local sockets work | |
14 | ================================ | |
15 | ||
16 | The idea is that you identify packets with destination address matching a local | |
4ac0b122 | 17 | socket on your box, set the packet mark to a certain value:: |
d2f26037 | 18 | |
4ac0b122 MCC |
19 | # iptables -t mangle -N DIVERT |
20 | # iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT | |
21 | # iptables -t mangle -A DIVERT -j MARK --set-mark 1 | |
22 | # iptables -t mangle -A DIVERT -j ACCEPT | |
d2f26037 | 23 | |
4ac0b122 | 24 | Alternatively you can do this in nft with the following commands:: |
1bfc2bc7 | 25 | |
4ac0b122 MCC |
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 | |
1bfc2bc7 ME |
29 | |
30 | And then match on that value using policy routing to have those packets | |
4ac0b122 | 31 | delivered locally:: |
1bfc2bc7 | 32 | |
4ac0b122 MCC |
33 | # ip rule add fwmark 1 lookup 100 |
34 | # ip route add local 0.0.0.0/0 dev lo table 100 | |
d2f26037 KK |
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 | |
4ac0b122 MCC |
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)); | |
d2f26037 KK |
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 | |
4ac0b122 | 67 | add rules like this to the iptables ruleset above:: |
d2f26037 | 68 | |
4ac0b122 MCC |
69 | # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \ |
70 | --tproxy-mark 0x1/0x1 --on-port 50080 | |
d2f26037 | 71 | |
1bfc2bc7 ME |
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 | ||
d2f26037 KK |
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 | ||
1bfc2bc7 ME |
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. | |
d2f26037 | 83 | |
1bfc2bc7 ME |
84 | 3. Iptables and nf_tables extensions |
85 | ==================================== | |
d2f26037 | 86 | |
1bfc2bc7 | 87 | To use tproxy you'll need to have the following modules compiled for iptables: |
4ac0b122 | 88 | |
1bfc2bc7 ME |
89 | - NETFILTER_XT_MATCH_SOCKET |
90 | - NETFILTER_XT_TARGET_TPROXY | |
d2f26037 | 91 | |
1bfc2bc7 | 92 | Or the floowing modules for nf_tables: |
4ac0b122 | 93 | |
1bfc2bc7 ME |
94 | - NFT_SOCKET |
95 | - NFT_TPROXY | |
d2f26037 KK |
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 |