162306a36Sopenharmony_ci.. SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci
362306a36Sopenharmony_ci=========================
462306a36Sopenharmony_ciTransparent proxy support
562306a36Sopenharmony_ci=========================
662306a36Sopenharmony_ci
762306a36Sopenharmony_ciThis feature adds Linux 2.2-like transparent proxy support to current kernels.
862306a36Sopenharmony_ciTo use it, enable the socket match and the TPROXY target in your kernel config.
962306a36Sopenharmony_ciYou will need policy routing too, so be sure to enable that as well.
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ciFrom Linux 4.18 transparent proxy support is also available in nf_tables.
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci1. Making non-local sockets work
1462306a36Sopenharmony_ci================================
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ciThe idea is that you identify packets with destination address matching a local
1762306a36Sopenharmony_cisocket on your box, set the packet mark to a certain value::
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci    # iptables -t mangle -N DIVERT
2062306a36Sopenharmony_ci    # iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
2162306a36Sopenharmony_ci    # iptables -t mangle -A DIVERT -j MARK --set-mark 1
2262306a36Sopenharmony_ci    # iptables -t mangle -A DIVERT -j ACCEPT
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ciAlternatively you can do this in nft with the following commands::
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci    # nft add table filter
2762306a36Sopenharmony_ci    # nft add chain filter divert "{ type filter hook prerouting priority -150; }"
2862306a36Sopenharmony_ci    # nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ciAnd then match on that value using policy routing to have those packets
3162306a36Sopenharmony_cidelivered locally::
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci    # ip rule add fwmark 1 lookup 100
3462306a36Sopenharmony_ci    # ip route add local 0.0.0.0/0 dev lo table 100
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ciBecause of certain restrictions in the IPv4 routing output code you'll have to
3762306a36Sopenharmony_cimodify your application to allow it to send datagrams _from_ non-local IP
3862306a36Sopenharmony_ciaddresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
3962306a36Sopenharmony_cioption before calling bind::
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci    fd = socket(AF_INET, SOCK_STREAM, 0);
4262306a36Sopenharmony_ci    /* - 8< -*/
4362306a36Sopenharmony_ci    int value = 1;
4462306a36Sopenharmony_ci    setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
4562306a36Sopenharmony_ci    /* - 8< -*/
4662306a36Sopenharmony_ci    name.sin_family = AF_INET;
4762306a36Sopenharmony_ci    name.sin_port = htons(0xCAFE);
4862306a36Sopenharmony_ci    name.sin_addr.s_addr = htonl(0xDEADBEEF);
4962306a36Sopenharmony_ci    bind(fd, &name, sizeof(name));
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ciA trivial patch for netcat is available here:
5262306a36Sopenharmony_cihttp://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci2. Redirecting traffic
5662306a36Sopenharmony_ci======================
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ciTransparent proxying often involves "intercepting" traffic on a router. This is
5962306a36Sopenharmony_ciusually done with the iptables REDIRECT target; however, there are serious
6062306a36Sopenharmony_cilimitations of that method. One of the major issues is that it actually
6162306a36Sopenharmony_cimodifies the packets to change the destination address -- which might not be
6262306a36Sopenharmony_ciacceptable in certain situations. (Think of proxying UDP for example: you won't
6362306a36Sopenharmony_cibe able to find out the original destination address. Even in case of TCP
6462306a36Sopenharmony_cigetting the original destination address is racy.)
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ciThe 'TPROXY' target provides similar functionality without relying on NAT. Simply
6762306a36Sopenharmony_ciadd rules like this to the iptables ruleset above::
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci    # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
7062306a36Sopenharmony_ci      --tproxy-mark 0x1/0x1 --on-port 50080
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ciOr the following rule to nft:
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci# nft add rule filter divert tcp dport 80 tproxy to :50080 meta mark set 1 accept
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciNote that for this to work you'll have to modify the proxy to enable (SOL_IP,
7762306a36Sopenharmony_ciIP_TRANSPARENT) for the listening socket.
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ciAs an example implementation, tcprdr is available here:
8062306a36Sopenharmony_cihttps://git.breakpoint.cc/cgit/fw/tcprdr.git/
8162306a36Sopenharmony_ciThis tool is written by Florian Westphal and it was used for testing during the
8262306a36Sopenharmony_cinf_tables implementation.
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci3. Iptables and nf_tables extensions
8562306a36Sopenharmony_ci====================================
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ciTo use tproxy you'll need to have the following modules compiled for iptables:
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci - NETFILTER_XT_MATCH_SOCKET
9062306a36Sopenharmony_ci - NETFILTER_XT_TARGET_TPROXY
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ciOr the floowing modules for nf_tables:
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci - NFT_SOCKET
9562306a36Sopenharmony_ci - NFT_TPROXY
9662306a36Sopenharmony_ci
9762306a36Sopenharmony_ci4. Application support
9862306a36Sopenharmony_ci======================
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci4.1. Squid
10162306a36Sopenharmony_ci----------
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ciSquid 3.HEAD has support built-in. To use it, pass
10462306a36Sopenharmony_ci'--enable-linux-netfilter' to configure and set the 'tproxy' option on
10562306a36Sopenharmony_cithe HTTP listener you redirect traffic to with the TPROXY iptables
10662306a36Sopenharmony_citarget.
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ciFor more information please consult the following page on the Squid
10962306a36Sopenharmony_ciwiki: http://wiki.squid-cache.org/Features/Tproxy4
110