Transparent Proxy¶
Transparent proxy supports two modes: REDIRECT and TPROXY. The REDIRECT mode only supports TCP.
Limitation
Transparent proxy is only available on Linux.
Traffic Sniffing
The TCP transparent proxy supports the detection of HTTP and TLS traffic. The HTTP Host header information or the SNI extension information of TLS is used as the target access address.
Traffic sniffing is enabled through the sniffing option, which is not enabled by default.
If the SNI information is not sniffed for HTTPS traffic, you can enable the sniffing.fallback option and try to connect again using the original target address.
REDIRECT¶
Transparent proxy using REDIRECT can choose to mark packets. Using Mark requires administrator privileges to run.
Without Mark¶
iptables-Local Global TCP Proxy
With Mark¶
Using Mark can avoid an infinite loop caused by secondary interception of egress traffic.
Forwarding Chain¶
services: - name: service-0 addr: :12345 handler: type: red chain: chain-0 metadata: sniffing: true listener: type: red chains: - name: chain-0 hops: - name: hop-0 sockopts: mark: 100 nodes: - name: node-0 addr: 192.168.1.1:1080 # node level sockopts, will override hop level value. # sockopts: # mark: 100 connector: type: http dialer: type: tcp Set the mark value via the so_mark (command line) or sockopts (config file) parameter.
iptables Rules
iptables -t nat -N GOST # Ignore LAN traffic, please adjust it according to the actual network environment iptables -t nat -A GOST -d 192.168.0.0/16 -j RETURN # Ignore egress traffic iptables -t nat -A GOST -p tcp -m mark --mark 100 -j RETURN # Redirect TCP traffic to port 12345 iptables -t nat -A GOST -p tcp -j REDIRECT --to-ports 12345 # Intercept LAN traffic iptables -t nat -A PREROUTING -p tcp -j GOST iptables -t nat -A OUTPUT -p tcp -j GOST TPROXY¶
TCP¶
Forwarding Chain¶
services: - name: service-0 addr: :12345 handler: type: red chain: chain-0 metadata: sniffing: true tproxy: true listener: type: red metadata: tproxy: true chains: - name: chain-0 hops: - name: hop-0 sockopts: mark: 100 nodes: - name: node-0 addr: 192.168.1.1:8080 connector: type: http dialer: type: tcp Routing and iptables Rules
# ipv4 ip rule add fwmark 1 lookup 100 ip route add local default dev lo table 100 iptables -t mangle -N DIVERT iptables -t mangle -A DIVERT -j MARK --set-mark 1 iptables -t mangle -A DIVERT -j ACCEPT iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT iptables -t mangle -N GOST iptables -t mangle -A GOST -p tcp -d 127.0.0.0/8 -j RETURN iptables -t mangle -A GOST -p tcp -d 192.168.0.0/16 -j RETURN iptables -t mangle -A GOST -p tcp -m mark --mark 100 -j RETURN iptables -t mangle -A GOST -p tcp -j TPROXY --tproxy-mark 0x1/0x1 --on-port 12345 iptables -t mangle -A PREROUTING -p tcp -j GOST # Only for local mode iptables -t mangle -N GOST_LOCAL iptables -t mangle -A GOST_LOCAL -p tcp -d 127.0.0.0/8 -j RETURN iptables -t mangle -A GOST_LOCAL -p tcp -d 255.255.255.255/32 -j RETURN iptables -t mangle -A GOST_LOCAL -p tcp -d 192.168.0.0/16 -j RETURN iptables -t mangle -A GOST_LOCAL -p tcp -m mark --mark 100 -j RETURN iptables -t mangle -A GOST_LOCAL -p tcp -j MARK --set-mark 1 iptables -t mangle -A OUTPUT -p tcp -j GOST_LOCAL # ipv6 ip -6 rule add fwmark 1 lookup 100 ip -6 route add local default dev lo table 100 ip6tables -t mangle -N DIVERT ip6tables -t mangle -A DIVERT -j MARK --set-mark 1 ip6tables -t mangle -A DIVERT -j ACCEPT ip6tables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT ip6tables -t mangle -N GOST ip6tables -t mangle -A GOST -p tcp -d ::/128 -j RETURN ip6tables -t mangle -A GOST -p tcp -d ::1/128 -j RETURN ip6tables -t mangle -A GOST -p tcp -d fe80::/10 -j RETURN ip6tables -t mangle -A GOST -p tcp -d ff00::/8 -j RETURN ip6tables -t mangle -A GOST -p tcp -m mark --mark 100 -j RETURN ip6tables -t mangle -A GOST -p tcp -j TPROXY --tproxy-mark 0x1/0x1 --on-port 12345 ip6tables -t mangle -A PREROUTING -p tcp -j GOST # Only for local mode ip6tables -t mangle -N GOST_LOCAL ip6tables -t mangle -A GOST_LOCAL -p tcp -d ::/128 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p tcp -d ::1/128 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p tcp -d fe80::/10 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p tcp -d ff00::/8 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p tcp -m mark --mark 100 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p tcp -j MARK --set-mark 1 ip6tables -t mangle -A OUTPUT -p tcp -j GOST_LOCAL UDP¶
Forwarding Chain¶
ttl(duration, default=30s)- UDP tunnel timeout period.
readBufferSize(int, default=4096)- UDP read buffer size
Routing and iptables Rules
# ipv4 ip rule add fwmark 1 lookup 100 ip route add local default dev lo table 100 iptables -t mangle -N GOST iptables -t mangle -A GOST -p udp -d 127.0.0.0/8 -j RETURN iptables -t mangle -A GOST -p udp -d 255.255.255.255/32 -j RETURN iptables -t mangle -A GOST -p udp -d 192.168.0.0/16 -j RETURN iptables -t mangle -A GOST -p udp -m mark --mark 100 -j RETURN iptables -t mangle -A GOST -p udp -j TPROXY --tproxy-mark 0x1/0x1 --on-port 12345 iptables -t mangle -A PREROUTING -p udp -j GOST # Only for local mode iptables -t mangle -N GOST_LOCAL iptables -t mangle -A GOST_LOCAL -p udp -d 127.0.0.0/8 -j RETURN iptables -t mangle -A GOST_LOCAL -p udp -d 255.255.255.255/32 -j RETURN iptables -t mangle -A GOST_LOCAL -p udp -d 192.168.0.0/16 -j RETURN iptables -t mangle -A GOST_LOCAL -p udp -m mark --mark 100 -j RETURN iptables -t mangle -A GOST_LOCAL -p udp -j MARK --set-mark 1 iptables -t mangle -A OUTPUT -p udp -j GOST_LOCAL # ipv6 ip -6 rule add fwmark 1 lookup 100 ip -6 route add local default dev lo table 100 ip6tables -t mangle -N GOST ip6tables -t mangle -A GOST -p udp -d ::/128 -j RETURN ip6tables -t mangle -A GOST -p udp -d ::1/128 -j RETURN ip6tables -t mangle -A GOST -p udp -d fe80::/10 -j RETURN ip6tables -t mangle -A GOST -p udp -d ff00::/8 -j RETURN ip6tables -t mangle -A GOST -p udp -m mark --mark 100 -j RETURN ip6tables -t mangle -A GOST -p udp -j TPROXY --tproxy-mark 0x1/0x1 --on-port 12345 ip6tables -t mangle -A PREROUTING -p udp -j GOST # Only for local mode ip6tables -t mangle -N GOST_LOCAL ip6tables -t mangle -A GOST_LOCAL -p udp -d ::/128 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p udp -d ::1/128 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p udp -d fe80::/10 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p udp -d ff00::/8 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p udp -m mark --mark 100 -j RETURN ip6tables -t mangle -A GOST_LOCAL -p udp -j MARK --set-mark 1 ip6tables -t mangle -A OUTPUT -p udp -j GOST_LOCAL Playground¶
The network namespace allows you to build a test environment on a single machine without affecting the normal network settings. Here, ns1 is used to simulate the gateway, ns2 is used to simulate the client, and the default namespace is used to simulate the target host.
Create a new network namespace ns1, and interconnect it with the default namespace through veth0 (10.0.10.1/24) and veth1 (10.0.10.2/24) pair.
ip netns add ns1 ip link add dev veth0 type veth peer name veth1 netns ns1 ip addr add 10.0.10.1/24 dev veth0 ip link set dev veth0 up ip -n ns1 addr add 10.0.10.2/24 dev veth1 ip -n ns1 link set dev lo up ip -n ns1 link set dev veth1 up Create a new network namespace ns2, and interconnect namespace ns2 with ns1 through veth2 (10.0.20.1/24) and veth3 (10.0.20.2/24) pair. Namespace ns2 uses ns1 as the gateway.
ip netns add ns2 ip netns exec ns1 ip link add veth2 type veth peer name veth3 netns ns2 ip netns exec ns1 ip addr add 10.0.20.1/24 dev veth2 ip netns exec ns1 ip link set veth2 up ip netns exec ns2 ip addr add 10.0.20.2/24 dev veth3 ip netns exec ns2 ip link set veth3 up ip netns exec ns2 ip link set lo up ip netns exec ns2 ip route add default via 10.0.20.1 dev veth3 Configure routing and iptables rules in namespace ns1.
ip netns exec ns1 ip rule add fwmark 1 lookup 100 ip netns exec ns1 ip route add local default dev lo table 100 # TCP ip netns exec ns1 iptables -t mangle -N DIVERT ip netns exec ns1 iptables -t mangle -A DIVERT -j MARK --set-mark 1 ip netns exec ns1 iptables -t mangle -A DIVERT -j ACCEPT ip netns exec ns1 iptables -t mangle -A PREROUTING -p tcp -m socket -j DIVERT ip netns exec ns1 iptables -t mangle -N GOST ip netns exec ns1 iptables -t mangle -A GOST -p tcp -d 127.0.0.0/8 -j RETURN ip netns exec ns1 iptables -t mangle -A GOST -p tcp -d 255.255.255.255/32 -j RETURN ip netns exec ns1 iptables -t mangle -A GOST -p tcp -m mark --mark 100 -j RETURN ip netns exec ns1 iptables -t mangle -A GOST -p tcp -j TPROXY --tproxy-mark 0x1/0x1 --on-port 12345 ip netns exec ns1 iptables -t mangle -A PREROUTING -p tcp -j GOST # UDP ip netns exec ns1 iptables -t mangle -A GOST -p udp -d 127.0.0.0/8 -j RETURN ip netns exec ns1 iptables -t mangle -A GOST -p udp -d 255.255.255.255/32 -j RETURN ip netns exec ns1 iptables -t mangle -A GOST -p udp -m mark --mark 100 -j RETURN ip netns exec ns1 iptables -t mangle -A GOST -p udp -j TPROXY --tproxy-mark 0x1/0x1 --on-port 12345 ip netns exec ns1 iptables -t mangle -A PREROUTING -p udp -j GOST Start relay service in default namespace.
Run GOST transparent proxy (TCP/UDP) in namespace ns1 and forward through the relay proxy service of the default namespace.
ip netns exec ns1 gost -L "red://:12345?tproxy=true" -L "redu://:12345?ttl=30s" -F "relay://10.0.10.1:8420?so_mark=100" Run the iperf3 service in the default namespace.
Execute iperf test in namespace ns2.
Cleaning