Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 =========================
0004 Transparent proxy support
0005 =========================
0006 
0007 This feature adds Linux 2.2-like transparent proxy support to current kernels.
0008 To use it, enable the socket match and the TPROXY target in your kernel config.
0009 You will need policy routing too, so be sure to enable that as well.
0010 
0011 From Linux 4.18 transparent proxy support is also available in nf_tables.
0012 
0013 1. Making non-local sockets work
0014 ================================
0015 
0016 The idea is that you identify packets with destination address matching a local
0017 socket on your box, set the packet mark to a certain value::
0018 
0019     # iptables -t mangle -N DIVERT
0020     # iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT
0021     # iptables -t mangle -A DIVERT -j MARK --set-mark 1
0022     # iptables -t mangle -A DIVERT -j ACCEPT
0023 
0024 Alternatively you can do this in nft with the following commands::
0025 
0026     # nft add table filter
0027     # nft add chain filter divert "{ type filter hook prerouting priority -150; }"
0028     # nft add rule filter divert meta l4proto tcp socket transparent 1 meta mark set 1 accept
0029 
0030 And then match on that value using policy routing to have those packets
0031 delivered locally::
0032 
0033     # ip rule add fwmark 1 lookup 100
0034     # ip route add local 0.0.0.0/0 dev lo table 100
0035 
0036 Because of certain restrictions in the IPv4 routing output code you'll have to
0037 modify your application to allow it to send datagrams _from_ non-local IP
0038 addresses. All you have to do is enable the (SOL_IP, IP_TRANSPARENT) socket
0039 option before calling bind::
0040 
0041     fd = socket(AF_INET, SOCK_STREAM, 0);
0042     /* - 8< -*/
0043     int value = 1;
0044     setsockopt(fd, SOL_IP, IP_TRANSPARENT, &value, sizeof(value));
0045     /* - 8< -*/
0046     name.sin_family = AF_INET;
0047     name.sin_port = htons(0xCAFE);
0048     name.sin_addr.s_addr = htonl(0xDEADBEEF);
0049     bind(fd, &name, sizeof(name));
0050 
0051 A trivial patch for netcat is available here:
0052 http://people.netfilter.org/hidden/tproxy/netcat-ip_transparent-support.patch
0053 
0054 
0055 2. Redirecting traffic
0056 ======================
0057 
0058 Transparent proxying often involves "intercepting" traffic on a router. This is
0059 usually done with the iptables REDIRECT target; however, there are serious
0060 limitations of that method. One of the major issues is that it actually
0061 modifies the packets to change the destination address -- which might not be
0062 acceptable in certain situations. (Think of proxying UDP for example: you won't
0063 be able to find out the original destination address. Even in case of TCP
0064 getting the original destination address is racy.)
0065 
0066 The 'TPROXY' target provides similar functionality without relying on NAT. Simply
0067 add rules like this to the iptables ruleset above::
0068 
0069     # iptables -t mangle -A PREROUTING -p tcp --dport 80 -j TPROXY \
0070       --tproxy-mark 0x1/0x1 --on-port 50080
0071 
0072 Or the following rule to nft:
0073 
0074 # nft add rule filter divert tcp dport 80 tproxy to :50080 meta mark set 1 accept
0075 
0076 Note that for this to work you'll have to modify the proxy to enable (SOL_IP,
0077 IP_TRANSPARENT) for the listening socket.
0078 
0079 As an example implementation, tcprdr is available here:
0080 https://git.breakpoint.cc/cgit/fw/tcprdr.git/
0081 This tool is written by Florian Westphal and it was used for testing during the
0082 nf_tables implementation.
0083 
0084 3. Iptables and nf_tables extensions
0085 ====================================
0086 
0087 To use tproxy you'll need to have the following modules compiled for iptables:
0088 
0089  - NETFILTER_XT_MATCH_SOCKET
0090  - NETFILTER_XT_TARGET_TPROXY
0091 
0092 Or the floowing modules for nf_tables:
0093 
0094  - NFT_SOCKET
0095  - NFT_TPROXY
0096 
0097 4. Application support
0098 ======================
0099 
0100 4.1. Squid
0101 ----------
0102 
0103 Squid 3.HEAD has support built-in. To use it, pass
0104 '--enable-linux-netfilter' to configure and set the 'tproxy' option on
0105 the HTTP listener you redirect traffic to with the TPROXY iptables
0106 target.
0107 
0108 For more information please consult the following page on the Squid
0109 wiki: http://wiki.squid-cache.org/Features/Tproxy4