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