TProxy實現透明代理

上一篇介紹的透明代理,使用的是REDIRECT(TCP)+TProxy(UDP)的方式,此篇要介紹完全使用TProxy透明代理的方式,注意shadowsocks是不支持TCP使用TProxy的.

1. 加载TPROXY模块

临时加载TPROXY模块:

sudo modprobe xt_TPROXY

编辑/etc/modules-load.d/TPROXY.conf 使自动加载TPROXY模块:

xt_TPROXY

2. V2Ray設置

{
  "inbounds": [
    {
      "tag":"transparent",
      "port": 12345,
      "protocol": "dokodemo-door",
      "settings": {
        "network": "tcp,udp",
        "followRedirect": true
      },
      "sniffing": {
        "enabled": true,
        "destOverride": [
          "http",
          "tls"
        ]
      },
      "streamSettings": {
        "sockopt": {
          "tproxy": "tproxy" // 透明代理使用TProxy方式
        }
      }
    }
  ],
  "outbounds": [
    {
      "tag": "proxy",
      "protocol": "vmess", // 代理伺服器
      "settings": {
        "vnext": [
          ...
        ]
      },
      "streamSettings": {
        "sockopt": {
          "mark": 2 //這邊建議不要設置為255.
        }
      },
      "mux": {
        "enabled": true
      }
    }
  ]
}

3. 設置ipset

添加保留地址

ipset -N reservedip nethash
ipset add reservedip 224.0.0.0/4
ipset add reservedip 100.64.0.0/10
ipset add reservedip 203.0.113.0/24
ipset add reservedip 192.18.0.0/15
ipset add reservedip 192.88.99.0/24
ipset add reservedip 172.16.0.0/12
ipset add reservedip 0.0.0.0/8
ipset add reservedip 127.0.0.0/8
ipset add reservedip 192.0.2.0/24
ipset add reservedip 192.51.100.0/24
ipset add reservedip 10.0.0.0/8
ipset add reservedip 192.168.0.0/16
ipset add reservedip 255.255.255.255
ipset add reservedip 192.0.0.0/24
ipset add reservedip 240.0.0.0/4
ipset add reservedip 169.254.0.0/16

添加自己伺服器的地址(鏈式代理需要,如果不需要可以不用添加)

ipset -N myip nethash
ipset add myip 2.2.2.2

添加不需要代理的地址(如代理伺服器的地址),1.1.1.1只是例子)

ipset -N noproxy nethash
ipset add noproxy 1.1.1.1 #(1.1.1.1只是例子)

4. iptables設置

ip rule add fwmark 0x01/0x01 table 100
ip route add local 0.0.0.0/0 dev lo table 100
iptables -t mangle -N V2RAY
iptables -t mangle -A V2RAY      -p udp -m set --match-set myip dst        -j TPROXY --on-port  12346 --tproxy-mark 0x01/0x01 --on-ip 0.0.0.0 
iptables -t mangle -A V2RAY      -p tcp -m set --match-set myip dst        -j TPROXY --on-port  12346 --tproxy-mark 0x01/0x01 --on-ip 0.0.0.0
iptables -t mangle -A V2RAY                                                -j RETURN -m mark --mark 2
iptables -t mangle -A V2RAY             -m set --match-set reservedip dst  -j RETURN
iptables -t mangle -A V2RAY             -m set  --match-set noproxy dst    -j RETURN
iptables -t mangle -A V2RAY      -p udp                                    -j TPROXY --on-port 12345 --tproxy-mark 0x01/0x01 --on-ip 0.0.0.0
iptables -t mangle -A V2RAY      -p tcp                                    -j TPROXY --on-port 12345 --tproxy-mark 0x01/0x01 --on-ip 0.0.0.0
iptables -t mangle -N V2RAY_MARK
iptables -t mangle -A V2RAY_MARK        -m set  --match-set reservedip dst -j RETURN
iptables -t mangle -A V2RAY_MARK        -m set  --match-set noproxy dst    -j RETURN
iptables -t mangle -A V2RAY_MARK        -m mark --mark 2                   -j RETURN 
iptables -t mangle -A V2RAY_MARK -p udp                                    -j MARK --set-mark 1
iptables -t mangle -A V2RAY_MARK -p tcp                                    -j MARK --set-mark 1
iptables -t mangle -A PREROUTING                                           -j V2RAY
iptables -t mangle -A OUTPUT                                               -j V2RAY_MARK

5. 開啓NAT

對於路由器需要開啓NAT,如果不是路由器請略過此條
其中internet0為鏈接到互聯網的網卡,net0為連接到局域網網卡.

iptables -t nat -A POSTROUTING -o internet0 -j MASQUERADE
iptables -A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
iptables -A FORWARD -i net0 -o internet0 -j ACCEPT

6. 保持配置

ipset save > /etc/ipset.conf
iptables-save > /etc/iptables/iptables.rules

7.設置開機啓動

編輯/etc/systemd/system/tproxy.service文件,内容如下

[Unit]
Description=Transparent proxy
Before=network-pre.target
Wants=network-pre.target

[Service]
Type=oneshot
ExecStart=/usr/bin/ip rule add fwmark 0x01/0x01 table 100 ; /usr/bin/ip route add local 0.0.0.0/0 dev lo table 100 ; /usr/bin/ipset -f /etc/ipset.conf restore ; /usr/bin/iptables-restore /etc/iptables/iptables.rules
ExecReload=/usr/bin/ipset -f /etc/ipset.conf restore ; /usr/bin/iptables-restore /etc/iptables/iptables.rules
ExecStop=/usr/bin/ip rule del table 100 ; /usr/bin/ip route del local 0.0.0.0/0 dev lo table 100 ; /usr/bin/ipset -f /etc/ipset.conf restore ; /usr/lib/systemd/scripts/iptables-flush
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

編輯/usr/lib/systemd/scripts/iptables-flush文件,内容如下

#/bin/bash
iptables=ip$1tables
if ! type -p "$iptables" &>/dev/null; then
  echo "error: invalid argument"
  exit 1
fi

while read -r table; do
  tables+=("/usr/share/iptables/empty-$table.rules")
done <"/proc/net/ip$1_tables_names"

if (( ${#tables[*]} )); then
  cat "${tables[@]}" | "$iptables-restore"
fi

啓用規則

systemctl enable tproxy

参见


- ArchWiki iptables
- ArchWiki Internet sharing
- Project V Official

Comments