Skip to content

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

gost -L red://:12345?sniffing=true -F 192.168.1.1:1080 
services: - name: service-0  addr: :12345  handler:  type: red  chain: chain-0  metadata:  sniffing: true  sniffing.timeout: 5s  sniffing.fallback: true  listener:  type: red chains: - name: chain-0  hops:  - name: hop-0  nodes:  - name: node-0  addr: 192.168.1.1:1080  connector:  type: http  dialer:  type: tcp 

iptables-Local Global TCP Proxy

iptables -t nat -A OUTPUT -p tcp --match multiport ! --dports 12345,1080 -j DNAT --to-destination 127.0.0.1:12345 

With Mark

Using Mark can avoid an infinite loop caused by secondary interception of egress traffic.

gost -L "red://:12345?sniffing=true&so_mark=100" 
services: - name: service-0  addr: :12345  sockopts:  mark: 100  handler:  type: red  metadata:  sniffing: true  listener:  type: red 

Forwarding Chain

gost -L red://:12345?sniffing=true -F "http://192.168.1.1:1080?so_mark=100" 
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

gost -L "red://:12345?sniffing=true&tproxy=true&so_mark=100" 
services: - name: service-0  addr: :12345  sockopts:  mark: 100   handler:  type: red  metadata:  tproxy: true  sniffing: true  sniffing.timeout: 5s  sniffing.fallback: true  listener:  type: red  metadata:  tproxy: true 

Forwarding Chain

gost -L "red://:12345?sniffing=true&tproxy=true" -F http://192.168.1.1:8080?so_mark=100 
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

gost -L "redu://:12345?ttl=30s&so_mark=100" 
services: - name: service-0  addr: :12345  sockopts:  mark: 100   handler:  type: redu  listener:  type: redu  metadata:  ttl: 30s 

Forwarding Chain

gost -L redu://:12345?ttl=30s -F relay://192.168.1.1:8421?so_mark=100 
services: - name: service-0  addr: :12345  handler:  type: redu  chain: chain-0  listener:  type: redu  metadata:  ttl: 30s chains: - name: chain-0  hops:  - name: hop-0  sockopts:  mark: 100   nodes:  - name: node-0  addr: 192.168.1.1:8421  connector:  type: relay  dialer:  type: tcp 
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.

gost -L relay://:8420 

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.

iperf3 -s 

Execute iperf test in namespace ns2.

# TCP ip netns exec ns2 iperf3 -c 10.0.10.1  # UDP ip netns exec ns2 iperf3 -c 10.0.10.1 -u 

Cleaning

ip netns delete ns1 ip netns delete ns2 

Comments