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