18c2ecf20Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci=========================
48c2ecf20Sopenharmony_ciTransparent proxy support
58c2ecf20Sopenharmony_ci=========================
68c2ecf20Sopenharmony_ci
78c2ecf20Sopenharmony_ciThis feature adds Linux 2.2-like transparent proxy support to current kernels.
88c2ecf20Sopenharmony_ciTo use it, enable the socket match and the TPROXY target in your kernel config.
98c2ecf20Sopenharmony_ciYou will need policy routing too, so be sure to enable that as well.
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ciFrom Linux 4.18 transparent proxy support is also available in nf_tables.
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci1. Making non-local sockets work
148c2ecf20Sopenharmony_ci================================
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ciThe idea is that you identify packets with destination address matching a local
178c2ecf20Sopenharmony_cisocket on your box, set the packet mark to a certain value::
188c2ecf20Sopenharmony_ci
198c2ecf20Sopenharmony_ci    # iptables -t mangle -N DIVERT
208c2ecf20Sopenharmony_ci    # iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
218c2ecf20Sopenharmony_ci    # iptables -t mangle -A DIVERT -j MARK --set-mark 1
228c2ecf20Sopenharmony_ci    # iptables -t mangle -A DIVERT -j ACCEPT
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ciAlternatively you can do this in nft with the following commands::
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci    # nft add table filter
278c2ecf20Sopenharmony_ci    # nft add chain filter divert "{ type filter hook prerouting priority -150; }"
288c2ecf20Sopenharmony_ci    # nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_ciAnd then match on that value using policy routing to have those packets
318c2ecf20Sopenharmony_cidelivered locally::
328c2ecf20Sopenharmony_ci
338c2ecf20Sopenharmony_ci    # ip rule add fwmark 1 lookup 100
348c2ecf20Sopenharmony_ci    # ip route add local 0.0.0.0/0 dev lo table 100
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ciBecause of certain restrictions in the IPv4 routing output code you'll have to
378c2ecf20Sopenharmony_cimodify your application to allow it to send datagrams _from_ non-local IP
388c2ecf20Sopenharmony_ciaddresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
398c2ecf20Sopenharmony_cioption before calling bind::
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci    fd = socket(AF_INET, SOCK_STREAM, 0);
428c2ecf20Sopenharmony_ci    /* - 8< -*/
438c2ecf20Sopenharmony_ci    int value = 1;
448c2ecf20Sopenharmony_ci    setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
458c2ecf20Sopenharmony_ci    /* - 8< -*/
468c2ecf20Sopenharmony_ci    name.sin_family = AF_INET;
478c2ecf20Sopenharmony_ci    name.sin_port = htons(0xCAFE);
488c2ecf20Sopenharmony_ci    name.sin_addr.s_addr = htonl(0xDEADBEEF);
498c2ecf20Sopenharmony_ci    bind(fd, &name, sizeof(name));
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ciA trivial patch for netcat is available here:
528c2ecf20Sopenharmony_cihttp://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci2. Redirecting traffic
568c2ecf20Sopenharmony_ci======================
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ciTransparent proxying often involves "intercepting" traffic on a router. This is
598c2ecf20Sopenharmony_ciusually done with the iptables REDIRECT target; however, there are serious
608c2ecf20Sopenharmony_cilimitations of that method. One of the major issues is that it actually
618c2ecf20Sopenharmony_cimodifies the packets to change the destination address -- which might not be
628c2ecf20Sopenharmony_ciacceptable in certain situations. (Think of proxying UDP for example: you won't
638c2ecf20Sopenharmony_cibe able to find out the original destination address. Even in case of TCP
648c2ecf20Sopenharmony_cigetting the original destination address is racy.)
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ciThe 'TPROXY' target provides similar functionality without relying on NAT. Simply
678c2ecf20Sopenharmony_ciadd rules like this to the iptables ruleset above::
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci    # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
708c2ecf20Sopenharmony_ci      --tproxy-mark 0x1/0x1 --on-port 50080
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ciOr the following rule to nft:
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci# nft add rule filter divert tcp dport 80 tproxy to :50080 meta mark set 1 accept
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ciNote that for this to work you'll have to modify the proxy to enable (SOL_IP,
778c2ecf20Sopenharmony_ciIP_TRANSPARENT) for the listening socket.
788c2ecf20Sopenharmony_ci
798c2ecf20Sopenharmony_ciAs an example implementation, tcprdr is available here:
808c2ecf20Sopenharmony_cihttps://git.breakpoint.cc/cgit/fw/tcprdr.git/
818c2ecf20Sopenharmony_ciThis tool is written by Florian Westphal and it was used for testing during the
828c2ecf20Sopenharmony_cinf_tables implementation.
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci3. Iptables and nf_tables extensions
858c2ecf20Sopenharmony_ci====================================
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ciTo use tproxy you'll need to have the following modules compiled for iptables:
888c2ecf20Sopenharmony_ci
898c2ecf20Sopenharmony_ci - NETFILTER_XT_MATCH_SOCKET
908c2ecf20Sopenharmony_ci - NETFILTER_XT_TARGET_TPROXY
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_ciOr the floowing modules for nf_tables:
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci - NFT_SOCKET
958c2ecf20Sopenharmony_ci - NFT_TPROXY
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci4. Application support
988c2ecf20Sopenharmony_ci======================
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci4.1. Squid
1018c2ecf20Sopenharmony_ci----------
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ciSquid 3.HEAD has support built-in. To use it, pass
1048c2ecf20Sopenharmony_ci'--enable-linux-netfilter' to configure and set the 'tproxy' option on
1058c2ecf20Sopenharmony_cithe HTTP listener you redirect traffic to with the TPROXY iptables
1068c2ecf20Sopenharmony_citarget.
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ciFor more information please consult the following page on the Squid
1098c2ecf20Sopenharmony_ciwiki: http://wiki.squid-cache.org/Features/Tproxy4
110