Featured image of post Debian 网关 [Episode 05]: 透明代理

Debian 网关 [Episode 05]: 透明代理

使用 nftables 实现不依赖代理软件分流的透明代理

先决条件

  • 已配置代理程序 (clash、xray、v2ray),且已监听 tproxy 端口
  • 已安装 nftables
  • 已配置 clash.servicexray.servicev2ray.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,6clash.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}
CC BY-NC-SA 4.0 转载或引用本文时请遵守许可协议,注明出处、不得用于商业用途!
最后更新于 Apr 28, 2023 02:38 +0800
人最重要的特点是会思考,写博客的初衷是保存思维的电子快照。 当然各种文档工具亦或是简单的文本编辑器也能随时记录点滴,选择建个人网站无非是想满足技术爱好者的偏执。
Built with Hugo
主题 StackJimmy 设计