先决条件
- 已配置代理程序 (clash、xray、v2ray),且已监听 tproxy 端口
- 已安装 nftables
- 已配置
clash.service、xray.service、v2ray.service中的任意一个
获取 CN IP 地址块
1# 创建 nftables.conf.d 文件夹
2sudo mkdir -p /etc/nftables.conf.d
3
4# 获取 delegated-apnic-latest 文件,需重复使用
5curl -fL "https://ftp.apnic.net/stats/apnic/delegated-apnic-latest" -o /tmp/apnic.iplist
6
7# 写入 ipv4 地址集合
8cat /tmp/apnic.iplist | \
9awk -F '|' '/CN/&&/ipv4/ {print $4 "/" 32-log($5)/log(2)}' | \
10sed ':label;N;s/\n/, /;b label' | sed 's/$/& }/g' | \
11sed 's/^/{ &/g' | sed 's/^/define CN = /' | \
12sudo tee /etc/nftables.conf.d/ip_cn.nftsets > /dev/null
13
14# [选]删除 delegated-apnic-latest
15rm /tmp/apnic.iplist
Tips:
- IPv6 规则 (在删除 delegated-apnic-latest 之前)
1# ipv6 地址集合 2cat /tmp/apnic.iplist | \ 3awk -F '|' '/CN/&&/ipv6/ {print $4 "/" $5}' | \ 4sed ':label;N;s/\n/, /;b label' | sed 's/$/& }/g' | \ 5sed 's/^/{ &/g' | sed 's/^/define CN_V6 = /'
透明代理规则
编写规则
- 编辑
/etc/nftables.tproxy.conf
1table ip proxy {
2 include "/etc/nftables.conf.d/ip_cn.nftsets"
3 define RESERVED = { 0.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 10.0.0.0/8, 100.64.0.0/10, 172.16.0.0/12, 192.168.0.0/16, 224.0.0.0/4, 255.255.255.255/32 }
4 define PROXY_PORT = 5092
5 define REROUTE_MARK = 0xe105
6
7 chain prerouting {
8 type filter hook prerouting priority mangle; policy accept;
9 iifname { "br-lan" } ip daddr != $RESERVED jump proxy_rule
10 }
11
12 chain proxy_rule {
13 tcp dport { 22, 80, 443, 853 } jump proxy_redirect
14 udp dport { 53, 443 } jump proxy_redirect
15 }
16
17 chain proxy_redirect {
18 ip daddr $CN return
19 ip protocol tcp tproxy to :$PROXY_PORT meta mark set $REROUTE_MARK
20 ip protocol udp tproxy to :$PROXY_PORT meta mark set $REROUTE_MARK
21 }
22}
如何 Debug
- 在需要 debug 的地方加上规则
meta nftrace set 1 - 执行
sudo nft monitor trace
tproxy.service
- 将
line 5,6的clash.service换成对应代理软件
1# /etc/systemd/system/tproxy.service
2[Unit]
3Description= Nftables TProxy
4Documentation= https://www.netfilter.org/projects/nftables/manpage.html
5Requires=clash.service
6After=clash.service
7
8[Service]
9Type=oneshot
10RemainAfterExit=yes
11ExecStartPost=ip rule add fwmark 0xe105 table 105
12ExecStartPost=ip route add local default dev lo table 105
13ExecStart=nft -f /etc/nftables.tproxy.conf
14ExecStop=nft delete table ip proxy
15ExecStopPost=ip route del local default dev lo table 105
16ExecStopPost=ip rule del fwmark 0xe105 table 105
17
18[Install]
19WantedBy=multi-user.target
- 启用
1sudo systemctl daemon-reload
2sudo systemctl enable --now tproxy
[选] 代理本机流量
- 有些场景需要代理本机的流量,比如:将本地的部分 DNS 流量代理出去
- 将以下规则添加进上面的配置
- 注意:将上面的
line 9改为下面的line 20
1table ip proxy {
2 define LOCAL_PROXY_RULE = { 1.1.1.1, 1.0.0.1, 8.8.8.8, 8.8.4.4 }
3
4 chain output {
5 type route hook output priority mangle; policy accept;
6 ip daddr $LOCAL_PROXY_RULE jump output_proxy_rule
7 }
8
9 chain output_proxy_rule {
10 tcp dport { 853 } jump output_reroute_mark
11 udp dport { 53 } jump output_reroute_mark
12 }
13
14 chain output_reroute_mark {
15 meta mark set $REROUTE_MARK
16 }
17
18 chain prerouting {
19 type filter hook prerouting priority mangle; policy accept;
20 iifname { "lo", "br-lan" } ip daddr != $RESERVED jump proxy_rule
21 }
22}
![Featured image of post Debian 网关 [Episode 05]: 透明代理](/post/fd2f28d0/cover_hue7d633b2d7f5b1b6e95a4af2800a9c85_31928_800x0_resize_box_3.png)