14ac0b122SMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0 24ac0b122SMauro Carvalho Chehab 34ac0b122SMauro Carvalho Chehab========================= 44ac0b122SMauro Carvalho ChehabTransparent proxy support 54ac0b122SMauro Carvalho Chehab========================= 64ac0b122SMauro Carvalho Chehab 74ac0b122SMauro Carvalho ChehabThis feature adds Linux 2.2-like transparent proxy support to current kernels. 84ac0b122SMauro Carvalho ChehabTo use it, enable the socket match and the TPROXY target in your kernel config. 94ac0b122SMauro Carvalho ChehabYou will need policy routing too, so be sure to enable that as well. 104ac0b122SMauro Carvalho Chehab 114ac0b122SMauro Carvalho ChehabFrom Linux 4.18 transparent proxy support is also available in nf_tables. 124ac0b122SMauro Carvalho Chehab 134ac0b122SMauro Carvalho Chehab1. Making non-local sockets work 144ac0b122SMauro Carvalho Chehab================================ 154ac0b122SMauro Carvalho Chehab 164ac0b122SMauro Carvalho ChehabThe idea is that you identify packets with destination address matching a local 174ac0b122SMauro Carvalho Chehabsocket on your box, set the packet mark to a certain value:: 184ac0b122SMauro Carvalho Chehab 194ac0b122SMauro Carvalho Chehab # iptables -t mangle -N DIVERT 20*aa758763S谢致邦 (XIE Zhibang) # iptables -t mangle -A PREROUTING -p tcp -m socket --transparent -j DIVERT 214ac0b122SMauro Carvalho Chehab # iptables -t mangle -A DIVERT -j MARK --set-mark 1 224ac0b122SMauro Carvalho Chehab # iptables -t mangle -A DIVERT -j ACCEPT 234ac0b122SMauro Carvalho Chehab 244ac0b122SMauro Carvalho ChehabAlternatively you can do this in nft with the following commands:: 254ac0b122SMauro Carvalho Chehab 264ac0b122SMauro Carvalho Chehab # nft add table filter 274ac0b122SMauro Carvalho Chehab # nft add chain filter divert "{ type filter hook prerouting priority -150; }" 284ac0b122SMauro Carvalho Chehab # nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept 294ac0b122SMauro Carvalho Chehab 304ac0b122SMauro Carvalho ChehabAnd then match on that value using policy routing to have those packets 314ac0b122SMauro Carvalho Chehabdelivered locally:: 324ac0b122SMauro Carvalho Chehab 334ac0b122SMauro Carvalho Chehab # ip rule add fwmark 1 lookup 100 344ac0b122SMauro Carvalho Chehab # ip route add local 0.0.0.0/0 dev lo table 100 354ac0b122SMauro Carvalho Chehab 364ac0b122SMauro Carvalho ChehabBecause of certain restrictions in the IPv4 routing output code you'll have to 374ac0b122SMauro Carvalho Chehabmodify your application to allow it to send datagrams _from_ non-local IP 384ac0b122SMauro Carvalho Chehabaddresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket 394ac0b122SMauro Carvalho Chehaboption before calling bind:: 404ac0b122SMauro Carvalho Chehab 414ac0b122SMauro Carvalho Chehab fd = socket(AF_INET, SOCK_STREAM, 0); 424ac0b122SMauro Carvalho Chehab /* - 8< -*/ 434ac0b122SMauro Carvalho Chehab int value = 1; 444ac0b122SMauro Carvalho Chehab setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value)); 454ac0b122SMauro Carvalho Chehab /* - 8< -*/ 464ac0b122SMauro Carvalho Chehab name.sin_family = AF_INET; 474ac0b122SMauro Carvalho Chehab name.sin_port = htons(0xCAFE); 484ac0b122SMauro Carvalho Chehab name.sin_addr.s_addr = htonl(0xDEADBEEF); 494ac0b122SMauro Carvalho Chehab bind(fd, &name, sizeof(name)); 504ac0b122SMauro Carvalho Chehab 514ac0b122SMauro Carvalho ChehabA trivial patch for netcat is available here: 524ac0b122SMauro Carvalho Chehabhttp://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch 534ac0b122SMauro Carvalho Chehab 544ac0b122SMauro Carvalho Chehab 554ac0b122SMauro Carvalho Chehab2. Redirecting traffic 564ac0b122SMauro Carvalho Chehab====================== 574ac0b122SMauro Carvalho Chehab 584ac0b122SMauro Carvalho ChehabTransparent proxying often involves "intercepting" traffic on a router. This is 594ac0b122SMauro Carvalho Chehabusually done with the iptables REDIRECT target; however, there are serious 604ac0b122SMauro Carvalho Chehablimitations of that method. One of the major issues is that it actually 614ac0b122SMauro Carvalho Chehabmodifies the packets to change the destination address -- which might not be 624ac0b122SMauro Carvalho Chehabacceptable in certain situations. (Think of proxying UDP for example: you won't 634ac0b122SMauro Carvalho Chehabbe able to find out the original destination address. Even in case of TCP 644ac0b122SMauro Carvalho Chehabgetting the original destination address is racy.) 654ac0b122SMauro Carvalho Chehab 664ac0b122SMauro Carvalho ChehabThe 'TPROXY' target provides similar functionality without relying on NAT. Simply 674ac0b122SMauro Carvalho Chehabadd rules like this to the iptables ruleset above:: 684ac0b122SMauro Carvalho Chehab 694ac0b122SMauro Carvalho Chehab # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \ 704ac0b122SMauro Carvalho Chehab --tproxy-mark 0x1/0x1 --on-port 50080 714ac0b122SMauro Carvalho Chehab 724ac0b122SMauro Carvalho ChehabOr the following rule to nft: 734ac0b122SMauro Carvalho Chehab 744ac0b122SMauro Carvalho Chehab# nft add rule filter divert tcp dport 80 tproxy to :50080 meta mark set 1 accept 754ac0b122SMauro Carvalho Chehab 764ac0b122SMauro Carvalho ChehabNote that for this to work you'll have to modify the proxy to enable (SOL_IP, 774ac0b122SMauro Carvalho ChehabIP_TRANSPARENT) for the listening socket. 784ac0b122SMauro Carvalho Chehab 794ac0b122SMauro Carvalho ChehabAs an example implementation, tcprdr is available here: 804ac0b122SMauro Carvalho Chehabhttps://git.breakpoint.cc/cgit/fw/tcprdr.git/ 814ac0b122SMauro Carvalho ChehabThis tool is written by Florian Westphal and it was used for testing during the 824ac0b122SMauro Carvalho Chehabnf_tables implementation. 834ac0b122SMauro Carvalho Chehab 844ac0b122SMauro Carvalho Chehab3. Iptables and nf_tables extensions 854ac0b122SMauro Carvalho Chehab==================================== 864ac0b122SMauro Carvalho Chehab 874ac0b122SMauro Carvalho ChehabTo use tproxy you'll need to have the following modules compiled for iptables: 884ac0b122SMauro Carvalho Chehab 894ac0b122SMauro Carvalho Chehab - NETFILTER_XT_MATCH_SOCKET 904ac0b122SMauro Carvalho Chehab - NETFILTER_XT_TARGET_TPROXY 914ac0b122SMauro Carvalho Chehab 924ac0b122SMauro Carvalho ChehabOr the floowing modules for nf_tables: 934ac0b122SMauro Carvalho Chehab 944ac0b122SMauro Carvalho Chehab - NFT_SOCKET 954ac0b122SMauro Carvalho Chehab - NFT_TPROXY 964ac0b122SMauro Carvalho Chehab 974ac0b122SMauro Carvalho Chehab4. Application support 984ac0b122SMauro Carvalho Chehab====================== 994ac0b122SMauro Carvalho Chehab 1004ac0b122SMauro Carvalho Chehab4.1. Squid 1014ac0b122SMauro Carvalho Chehab---------- 1024ac0b122SMauro Carvalho Chehab 1034ac0b122SMauro Carvalho ChehabSquid 3.HEAD has support built-in. To use it, pass 1044ac0b122SMauro Carvalho Chehab'--enable-linux-netfilter' to configure and set the 'tproxy' option on 1054ac0b122SMauro Carvalho Chehabthe HTTP listener you redirect traffic to with the TPROXY iptables 1064ac0b122SMauro Carvalho Chehabtarget. 1074ac0b122SMauro Carvalho Chehab 1084ac0b122SMauro Carvalho ChehabFor more information please consult the following page on the Squid 1094ac0b122SMauro Carvalho Chehabwiki: http://wiki.squid-cache.org/Features/Tproxy4 110