16M 小闪存(Flash)MT7621A 芯片路由器使用 sing-box 搭建 TProxy 透明代理
OpenWrt 25.12.5 + sing-box TProxy 透明代理完整配置指南
上篇文章16M 小闪存(Flash)MT7621A 芯片路由器安装 sing-box 透明代理,我们在低配置硬路由设置好了 tun 透明代理,这篇文章详细介绍 tproxy 透明代理设置。
对于 MT7621A 芯片来说,tun 透明代理和 tproxy 透明代理从直觉上感觉不到什么区别,决定代理性能的是 CPU 性能,两种代理模式下,MT7621A 芯片路由器性能上限都很低,YouTube 1080p 视频观看没有问题,4k 不行;直连性能上 tun 透明代理和 tproxy 透明代理也是半斤八两,伯仲之间,常规下载都能轻松达到几十兆每秒。
注意⚠️:如果之前设置过 tun 代理,最好是先重置路由器,否则残留配置会影响 tproxy 设置
官方固件下载:OpenWrt Firmware Selector,或者去我的 dropbox 网盘下载文件名含有 tproxy 固件 youhua_wr1200js-openwrt-singbox,OpenWrt 官方在线编译,只自定义预安装软件包,不做其他任何修改。
环境信息
在开始之前,先了解本次配置的硬件和软件环境:
| 项目 | 配置 |
|---|---|
| OpenWrt 版本 | 25.12.5 |
| 内核版本 | 6.12.94 |
| 路由器型号 | YouHua WR1200JS (MediaTek MT7621) |
| LAN 网卡 | br-lan |
| LAN 地址 | 10.0.0.1/24,IPv6 ULA:fdc7:92fa:9c61::/64 |
| WAN 网卡 | wan |
| WAN 地址 | 192.168.1.22/24,IPv6 由上游 DHCP 提供 |
| sing-box 版本 | 1.13.21 |
| TProxy 端口 | 9898 |
| fwmark 标记值 | 0x80 |
| 策略路由表 | 100 |
| 代理协议 | AnyTLS |
第一步:理解整个流程
在动手之前,先明白整个工作流程:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
LAN 设备发出请求
↓
到达路由器 LAN 口
↓
nftables 防火墙检查(mangle_prerouting)
↓
符合条件?
├─ 是 → 标记为 0x80,目标改为 TProxy 9898 端口
└─ 否 → 正常转发
↓
sing-box 接收标记为 0x80 的流量
↓
根据域名/IP 规则进行路由决策
├─ 国内 IP/域名 → direct-out(直连)
├─ 国外网站 → proxy(通过代理转发)
└─ 广告域名 → reject(拦截)
第二步:创建防火墙规则文件
作用说明
这个文件定义了哪些流量需要进入 sing-box,哪些流量可以直接转发。关键的概念是规则顺序很重要——前面的规则如果匹配就会停止执行,不会继续往下检查。
创建文件
文件路径:/etc/singbox-tproxy.nft
# =========================================================
# DNS -> sing-box
# Must be placed before LAN/private return rules
# =========================================================
iifname "br-lan" meta l4proto udp udp dport 53 \
tproxy to :9898 meta mark set 0x80
iifname "br-lan" meta l4proto tcp tcp dport 53 \
tproxy to :9898 meta mark set 0x80
# =========================================================
# LAN -> LAN
# =========================================================
iifname "br-lan" ip daddr 10.0.0.0/24 return
# =========================================================
# IPv4 local/private/multicast/broadcast
# =========================================================
iifname "br-lan" ip daddr 127.0.0.0/8 return
iifname "br-lan" ip daddr 192.168.0.0/16 return
iifname "br-lan" ip daddr 224.0.0.0/4 return
iifname "br-lan" ip daddr 255.255.255.255 return
# =========================================================
# IPv6 local/ULA/link-local/multicast
# =========================================================
iifname "br-lan" ip6 daddr ::1 return
iifname "br-lan" ip6 daddr fc00::/7 return
iifname "br-lan" ip6 daddr fe80::/10 return
iifname "br-lan" ip6 daddr ff00::/8 return
# =========================================================
# Specific IP bypass
# =========================================================
iifname "br-lan" ip daddr 8.219.1.15 return
iifname "br-lan" ip daddr 47.245.124.74 return
# =========================================================
# TCP / UDP -> TProxy
# =========================================================
iifname "br-lan" meta l4proto tcp \
tproxy to :9898 meta mark set 0x80
iifname "br-lan" meta l4proto udp \
tproxy to :9898 meta mark set 0x80
重要细节
DNS 规则一定要放在前面! 这是常见的坑。
LAN 内部的地址(10.0.0.1 等)默认是直连的,如果 DNS 规则放在后面,那么:
- LAN 设备请求
10.0.0.1:53(即路由器自身的 DNS)会被提前转发,无法进入 sing-box 的 DNS 处理 - 结果就是 DNS 查询不经过 sing-box 的规则,导致一些域名路由不生效
第三步:把防火墙规则注入到 fw4
作用说明
OpenWrt 的现代防火墙是 fw4(基于 nftables),我们需要把刚才创建的规则文件”注册”给它,这样 OpenWrt 重启时会自动加载。
添加配置
编辑 /etc/config/firewall,在末尾加入:
config include
option type 'nftables'
option path '/etc/singbox-tproxy.nft'
option position 'chain-pre'
option chain 'mangle_prerouting'
参数说明:
type 'nftables':表示这是个 nftables 规则文件position 'chain-pre':规则要加在链的前面(优先级高)chain 'mangle_prerouting':加到 mangle_prerouting 链(这是 linux 路由的标准处理链)
验证配置
1
2
# 查看配置是否保存
uci show firewall | grep singbox
加载配置
1
2
3
4
5
# 先检查语法是否正确
fw4 check
# 无错误则重新加载防火墙规则到内核
fw4 reload
确认规则已生效
1
2
# 列出内核中真实存在的 nftables 规则
nft -a list chain inet fw4 mangle_prerouting
输出应该包含:
1
tproxy to :9898 meta mark set 0x00000080
如果看不到这行,说明 fw4 还没重新加载。执行 fw4 reload 后重新查看。
第四步:配置策略路由(Policy Routing)
作用说明
策略路由是 Linux 内核的一个特性,允许根据包的特征(如 fwmark)来选择不同的路由表。我们的做法是:
- 把标记为 0x80 的包指向特殊的路由表 100
- 在表 100 中,设置默认路由指向本地回环网卡 lo
- 这样包就会进入 sing-box(bind 了这个 TProxy 端口)
创建 IPv4 策略路由
1
2
3
4
5
# 为 fwmark 0x80 的包指定使用路由表 100
ip rule add fwmark 0x80 table 100
# 在表 100 中添加默认路由到本地回环设备
ip route add local default dev lo table 100
创建 IPv6 策略路由
1
2
3
4
5
# IPv6 版本
ip -6 rule add fwmark 0x80 table 100
# IPv6 默认路由
ip -6 route add local default dev lo metric 1024 table 100
验证配置
1
2
3
4
5
# 查看 IPv4 规则
ip rule
# 查看 IPv6 规则
ip -6 rule
应该能看到:
1
32765: from all fwmark 0x80 lookup 100
(IPv4 和 IPv6 各一条)
1
2
# 查看表 100 的路由
ip route show table 100
应该显示:
1
local default dev lo scope host
1
2
# IPv6 版本
ip -6 route show table 100
应该显示:
1
local default dev lo metric 1024
清理重复规则
如果在调试过程中执行了多次 ip rule add,可能会产生重复的规则:
1
2
3
4
5
# 一次性删除所有重复的 IPv4 规则
while ip rule del fwmark 0x80 table 100 2>/dev/null; do :; done
# 重新添加一条
ip rule add fwmark 0x80 table 100
IPv6 同样处理:
1
2
while ip -6 rule del fwmark 0x80 table 100 2>/dev/null; do :; done
ip -6 rule add fwmark 0x80 table 100
第五步:配置内核参数
作用说明
这些参数控制了 Linux 内核的转发和防火墙行为:
ip_forward:启用 IPv4 转发(路由器必须)forwarding:启用 IPv6 转发rp_filter:反向路径过滤(设为 0 禁用,否则 TProxy 的回包会被丢弃)
创建配置文件
文件路径:/etc/sysctl.d/99-singbox-tproxy.conf
1
2
3
4
net.ipv4.ip_forward=1
net.ipv6.conf.all.forwarding=1
net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
立即生效
1
sysctl -p /etc/sysctl.d/99-singbox-tproxy.conf
验证
1
2
3
4
sysctl net.ipv4.ip_forward
sysctl net.ipv6.conf.all.forwarding
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.default.rp_filter
预期结果:
1
2
3
4
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
第六步:关闭 Flow Offload
作用说明
Flow Offload 是硬件加速功能,可以让 CPU 密集的网络转发交给硬件处理。但在调试 TProxy 时,应该关闭它,避免一些包绕过了我们的规则。等系统稳定后,可以再试着打开。
1
2
3
4
uci set firewall.@defaults[0].flow_offloading='0'
uci set firewall.@defaults[0].flow_offloading_hw='0'
uci commit firewall
/etc/init.d/firewall restart
第七步:配置 sing-box
作用说明
sing-box 是代理软件,负责:
- 监听 TProxy 9898 端口接收流量
- 根据配置的规则判断域名/IP 属于哪个分类
- 要么直连,要么通过 AnyTLS 代理转发
核心配置
文件路径:/etc/sing-box/config.json
完整配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
{
"log": {
"disabled": true,
"level": "info",
"timestamp": false
},
"dns": {
"servers": [
{
"tag": "dns-direct",
"type": "udp",
"server": "192.168.1.1",
"server_port": 53
},
{
"type": "h3",
"tag": "dns-remote",
"server": "1.1.1.1",
"server_port": 443,
"path": "/dns-query",
"detour": "proxy"
}
],
"reverse_mapping": false,
"rules": [
{
"domain_suffix": [
"addons.mozilla.org",
"analytics.google.com",
"onedrive.live.com",
"primevideo.com",
"steamcommunity.com",
"tpc.googlesyndication.com"
],
"server": "dns-remote"
},
{
"domain_suffix": [
"accuweather.com",
"aviationweather.gov",
"edu.kg",
"google.cn",
"hdcdn.online",
"localsend.org",
"made-in-china.com",
"micstatic.com",
"meixi-mgo.com",
"met.no",
"openweathermap.org",
"rustdesk.com",
"tigress.cc",
"vis.ee",
"vivaldi.net",
"xzmgo.com",
"bjxuejing.cn",
"wanyiwan.top"
],
"server": "dns-direct"
},
{
"rule_set": [
"geosite-category-ads"
],
"action": "reject"
},
{
"domain_keyword": [
"gdtimg",
"pangolin",
"pglstatp"
],
"action": "reject"
},
{
"domain_suffix": [
"ad.10010.com",
"ads.cup.com.cn",
"boot.biz.weibo.com",
"bootpreload.uve.weibo.com",
"bootrealtime.uve.weibo.com",
"brandvideo.biz.weibo.com",
"dsp-ad.yy.com",
"e.qq.com",
"gdt.qq.com",
"splash.yy.com"
],
"action": "reject"
},
{
"rule_set": [
"geosite-category-ru",
"geosite-cn"
],
"server": "dns-direct"
},
{
"rule_set": [
"geosite-github",
"geosite-google",
"geosite-linkedin",
"geosite-meta",
"geosite-tiktok"
],
"server": "dns-remote"
},
{
"rule_set": [
"geosite-amazon",
"geosite-microsoft",
"geosite-mozilla"
],
"server": "dns-direct"
}
],
"disable_cache": false,
"disable_expire": false,
"cache_capacity": 5000,
"final": "dns-remote"
},
"inbounds": [
{
"type": "tproxy",
"tag": "tproxy-in",
"listen": "::",
"listen_port": 9898
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
},
{
"type": "anytls",
"tag": "proxy",
"server": "服务器ip",
"server_port": 端口,
"password": "uuid",
"idle_session_check_interval": "30s",
"idle_session_timeout": "30s",
"min_idle_session": 0,
"domain_resolver": "dns-direct",
"tls": {
"enabled": true,
"server_name": "域名",
"insecure": true
}
}
],
"route": {
"auto_detect_interface": false,
"default_interface": "wan",
"default_domain_resolver": "dns-remote",
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
},
{
"domain_keyword": [
"gdtimg",
"pangolin",
"pglstatp"
],
"action": "reject"
},
{
"domain_suffix": [
"ad.10010.com",
"ads.cup.com.cn",
"amap-aos-info-nogw.amap.com",
"boot.biz.weibo.com",
"bootpreload.uve.weibo.com",
"bootrealtime.uve.weibo.com",
"brandvideo.biz.weibo.com",
"dsp-ad.yy.com",
"e.qq.com",
"gdt.qq.com",
"splash.yy.com",
"xpis-xcdn.youku.com"
],
"action": "reject"
},
{
"domain_suffix": [
"accuweather.com",
"aviationweather.gov",
"edu.kg",
"google.cn",
"hdcdn.online",
"localsend.org",
"made-in-china.com",
"micstatic.com",
"meixi-mgo.com",
"met.no",
"openweathermap.org",
"rustdesk.com",
"tigress.cc",
"vis.ee",
"vivaldi.net",
"xzmgo.com",
"bjxuejing.cn",
"wanyiwan.top"
],
"action": "route",
"outbound": "direct-out"
},
{
"domain_suffix": [
"addons.mozilla.org",
"analytics.google.com",
"onedrive.live.com",
"primevideo.com",
"steamcommunity.com",
"tpc.googlesyndication.com"
],
"action": "route",
"outbound": "proxy"
},
{
"rule_set": [
"geosite-category-ads"
],
"action": "reject"
},
{
"rule_set": [
"geosite-category-ru",
"geosite-cn"
],
"outbound": "direct-out"
},
{
"rule_set": [
"geosite-github",
"geosite-google",
"geosite-linkedin",
"geosite-meta",
"geosite-tiktok"
],
"action": "route",
"outbound": "proxy"
},
{
"rule_set": [
"geosite-amazon",
"geosite-microsoft",
"geosite-mozilla",
"geosite-category-games"
],
"action": "route",
"outbound": "direct-out"
},
],
"rule_set": [
{"tag": "geosite-github", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-github.srs"},
{"tag": "geosite-google", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-google.srs"},
{"tag": "geosite-linkedin", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-linkedin.srs"},
{"tag": "geosite-meta", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-meta.srs"},
{"tag": "geosite-tiktok", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-tiktok.srs"},
{"tag": "geosite-cn", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-cn.srs"},
{"tag": "geosite-amazon", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-amazon.srs"},
{"tag": "geosite-microsoft", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-microsoft.srs"},
{"tag": "geosite-mozilla", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-mozilla.srs"},
{"tag": "geosite-category-ru", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-category-ru.srs"},
{"tag": "geosite-category-ads", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-category-ads.srs"},
{"tag": "geosite-category-games", "type": "local", "format": "binary", "path": "/etc/sing-box/geosite-category-games.srs"},
],
"final": "proxy"
}
}
规则文件下载
首先确保当前目录是 /etc/sing-box/
1
cd /etc/sing-box/
从 lyc8503 仓库下载所有规则文件
下载 geosite 文件
1
2
3
for name in amazon category-ads category-games category-ru cn github google linkedin meta microsoft mozilla tiktok; do
wget -O "geosite-$name.srs" "https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-$name.srs"
done
如果说因为网络原因路由器无法下载这些文件,电脑有科学网络的情况下,先下载到电脑上然后传到路由器;光猫地址基本都是 192.168.1.1,你的路由器地址要改为 192.168.1.2 等其他地址。
1
scp -O *.srs [email protected]:/etc/sing-box/
电脑上如果安装了 aria2,那么可以一次性批量下载所有文件
1
2
3
4
5
6
{
for name in amazon category-ads category-games category-ru cn github google linkedin meta microsoft mozilla tiktok; do
echo "https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-$name.srs"
echo " out=geosite-$name.srs"
done
} | aria2c -i - -j 16
Windows 电脑可以复制以下内容,在 motrix next,fluxdown 等下载工具中新建下载。
1
2
3
4
5
6
7
8
9
10
11
12
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-amazon.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-category-ads.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-category-games.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-category-ru.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-cn.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-github.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-google.srsd
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-linkedin.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-meta.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-microsoft.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-mozilla.srs
https://raw.githubusercontent.com/lyc8503/sing-box-rules/refs/heads/rule-set-geosite/geosite-tiktok.srs
检查配置文件语法
1
sing-box check -c /etc/sing-box/config.json
无输出或显示 OK 表示配置正确。 /etc/init.d/sing-box restart 重启 sing-box 服务
验证 sing-box 状态
1
2
3
4
5
# 检查 sing-box 进程是否运行
ps | grep '[s]ing-box'
# 检查 TProxy 端口是否监听
netstat -lnptu | grep 9898
预期输出:
1
2
tcp :::9898 ... sing-box
udp :::9898 ... sing-box
说明 sing-box 正在同时监听 TCP 和 UDP 的 9898 端口。
第八步:实现开机自启和策略路由持久化
问题描述
如果只是手工执行 ip rule add 和 ip route add,重启路由器后这些规则会丢失。需要两个方面来解决:
- init 脚本:保证开机时执行这些命令
- hotplug 脚本:网络接口状态变化时重新应用(解决启动顺序问题)
创建 init 脚本
文件路径:/etc/init.d/singbox-tproxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/bin/sh /etc/rc.common
START=99
STOP=10
apply_tproxy_route() {
sysctl -p /etc/sysctl.d/99-singbox-tproxy.conf >/dev/null 2>&1
while ip rule del fwmark 0x80 table 100 2>/dev/null; do :; done
while ip -6 rule del fwmark 0x80 table 100 2>/dev/null; do :; done
ip rule add fwmark 0x80 table 100
ip -6 rule add fwmark 0x80 table 100
ip route replace local default dev lo table 100
ip -6 route replace local default dev lo metric 1024 table 100
logger -t singbox-tproxy "policy routing applied"
}
start() {
apply_tproxy_route
}
stop() {
while ip rule del fwmark 0x80 table 100 2>/dev/null; do :; done
while ip -6 rule del fwmark 0x80 table 100 2>/dev/null; do :; done
}
参数说明:
START=99:开机启动优先级,99 表示很后面启动(在网络接口初始化之后)STOP=10:关机停止优先级,10 表示很前面停止
启用脚本:
1
2
3
chmod +x /etc/init.d/singbox-tproxy
/etc/init.d/singbox-tproxy enable
/etc/init.d/singbox-tproxy start
创建 hotplug 脚本(重要!)
文件路径:/etc/hotplug.d/iface/99-singbox-tproxy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/bin/sh
[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifupdate" ] || exit 0
case "$INTERFACE" in
lan|wan|wan6)
;;
*)
exit 0
;;
esac
sleep 1
while ip rule del fwmark 0x80 table 100 2>/dev/null; do :; done
while ip -6 rule del fwmark 0x80 table 100 2>/dev/null; do :; done
ip rule add fwmark 0x80 table 100
ip -6 rule add fwmark 0x80 table 100
ip route replace local default dev lo table 100
ip -6 route replace local default dev lo metric 1024 table 100
logger -t singbox-tproxy "policy routing applied after $ACTION on $INTERFACE"
参数说明:
ACTION为ifup或ifupdate时执行(网络接口启动或更新)sleep 1:等待 1 秒,给系统时间完成初始化- 只处理 lan、wan、wan6 这几个网络接口
设置权限:
1
2
mkdir -p /etc/hotplug.d/iface
chmod +x /etc/hotplug.d/iface/99-singbox-tproxy
启动顺序
配置好后,完整的启动顺序如下:
1
2
3
4
5
6
1. 内核启动
2. OpenWrt 网络接口初始化
3. hotplug 脚本触发(iface 事件)
4. fw4 防火墙加载
5. 99-singbox-tproxy hotplug 脚本
6. 策略路由规则(fwmark 0x80 + table 100)生效
这样就保证了:重启路由器后,无需手动执行命令,策略路由会自动恢复。
最终检查清单
配置完成后,按照下面的清单一一验证:
1. sing-box 配置
1
sing-box check -c /etc/sing-box/config.json
必须无错误输出。
2. sing-box 进程
1
ps | grep '[s]ing-box'
应该看到 sing-box 进程在运行。
3. 防火墙配置
1
2
fw4 check
fw4 reload
无错误表示 fw4 配置正确。
4. TProxy 规则
1
nft -a list chain inet fw4 mangle_prerouting
输出应该包含:
1
tproxy to :9898 meta mark set 0x00000080
5. IPv4 策略路由
1
ip rule
应该包含:
1
32765: from all fwmark 0x80 lookup 100
1
ip route show table 100
应该包含:
1
local default dev lo scope host
6. IPv6 策略路由
1
ip -6 rule
应该包含:
1
32765: from all fwmark 0x80 lookup 100
1
ip -6 route show table 100
应该包含:
1
local default dev lo metric 1024
7. TProxy 端口
1
netstat -lnptu | grep 9898
应该同时看到 TCP 和 UDP:
1
2
tcp :::9898 ... sing-box
udp :::9898 ... sing-box
8. 内核参数
1
2
3
4
sysctl net.ipv4.ip_forward
sysctl net.ipv6.conf.all.forwarding
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.default.rp_filter
预期值:
1
2
3
4
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
故障排查指南
如果系统出现问题,不要立即重置路由器。按下面的顺序逐一检查:
检查流程
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1. sing-box 进程是否运行?
↓
2. TProxy 端口 9898 是否监听?
↓
3. nftables 规则是否正确加载?
↓
4. fwmark 0x80 是否正确打上?
↓
5. 策略路由表 100 是否存在?
↓
6. DNS 是否正常解析?
↓
7. IPv4/IPv6 连接是否正常?
↓
8. UDP/QUIC 流量是否正常?
对应检查命令
第一步:sing-box 进程
1
ps | grep '[s]ing-box'
如果没有看到进程,说明 sing-box 没有启动或崩溃了。查看日志:
1
logread | grep sing-box
第二步:TProxy 端口
1
netstat -lnptu | grep 9898
两个都应该看到(TCP 和 UDP)。
第三步:nftables 规则
1
nft -a list chain inet fw4 mangle_prerouting
应该包含 TProxy 规则。
第四步:fwmark 标记
1
2
ip rule
ip -6 rule
查看是否有 fwmark 0x80 lookup 100 这样的规则。
第五步:策略路由表
1
2
ip route show table 100
ip -6 route show table 100
应该看到 local default dev lo。
第六步:DNS 解析
1
2
nslookup www.google.com 10.0.0.1
nslookup www.google.com 1.1.1.1
测试对不同 DNS 的查询是否正常。
第七步:IPv4/IPv6 连接
1
2
curl -4 -I --connect-timeout 10 https://www.google.com
curl -6 -I --connect-timeout 10 https://www.google.com
测试 IPv4 和 IPv6 的 HTTPS 连接。
第八步:UDP/QUIC 流量
观察 UDP 相关的应用(如 DNS over QUIC)是否正常工作。
fw4 分流设置
从 https://github.com/gaoyifan/china-operator-ip 下载 IP 地址库
下载两个文件 china.txt,china6.txt,分别是ipv4, ipv6,并传到路由器的 /etc/sing-box/ 目录。
生成 IPv4 nft set
1
2
3
4
5
6
7
8
9
10
{
echo 'set china_ipv4 {'
echo ' type ipv4_addr'
echo ' flags interval'
echo ' elements = {'
sed '/^[[:space:]]*$/d; /^[[:space:]]*#/d; s/[[:space:]]*$/,/; s/^/ /' \
/etc/sing-box/china.txt
echo ' }'
echo '}'
} > /etc/sing-box/china-ipv4.nft
生成 IPv6 nft set
1
2
3
4
5
6
7
8
9
10
{
echo 'set china_ipv6 {'
echo ' type ipv6_addr'
echo ' flags interval'
echo ' elements = {'
sed '/^[[:space:]]*$/d; /^[[:space:]]*#/d; s/[[:space:]]*$/,/; s/^/ /' \
/etc/sing-box/china6.txt
echo ' }'
echo '}'
} > /etc/sing-box/china-ipv6.nft
创建中国 IP set 文件
先把两个文件合并成一个:
(如果空间不足,可以删除文件 china.txt,china6.txt;合并为 china-sets.nft 后,china-ipv4.nft 和 china-ipv6.nft 也可以删除)
1
2
cat /etc/sing-box/china-ipv4.nft /etc/sing-box/china-ipv6.nft \
> /etc/sing-box/china-sets.nft
检查:
1
head -8 /etc/sing-box/china-sets.nft
应该看到:
1
2
3
4
5
6
set china_ipv4 {
type ipv4_addr
flags interval
elements = {
1.0.1.0/24,
...
让 fw4 在 table-pre 加载这个 set
编辑:
1
vi /etc/config/firewall
在文件末尾增加以下内容
1
2
3
4
config include
option type 'nftables'
option path '/etc/sing-box/china-sets.nft'
option position 'table-pre'
在上文的防火墙规则文件中 /etc/singbox-tproxy.nft,在 Specific IP bypass 之前加入 China mainland IP direct,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
# =========================================================
# China mainland IP direct
# =========================================================
iifname "br-lan" ip daddr @china_ipv4 return
iifname "br-lan" ip6 daddr @china_ipv6 return
# =========================================================
# Specific IP bypass
# =========================================================
iifname "br-lan" ip daddr 8.219.1.15 return
iifname "br-lan" ip daddr 47.245.124.74 return
先检查
1
fw4 check
如果没有报错,再:
1
fw4 reload
确认 set 已经进入 fw4:
1
2
nft list set inet fw4 china_ipv4
nft list set inet fw4 china_ipv6
应该可以看到以下内容:
1
2
3
4
5
6
7
table inet fw4 {
set china_ipv4 {
type ipv4_addr
flags interval
...
}
}
确认防火墙规则
1
nft list chain inet fw4 mangle_prerouting
应该可以看到以下内容:
1
2
iifname "br-lan" ip daddr @china_ipv4 return
iifname "br-lan" ip6 daddr @china_ipv6 return
这样设置,会让中国 IP 直连流量直接通过路由器硬件转发,不经过 sing-box;对于传统硬路由,直连流量经过 fw4 转发,不经过 sing-box,效率最高,而对于 CPU 性能较强的软路由,选择 eBPF 加持 dae 透明代理更好。
开启 Flow Offload
直接复制粘贴输入以下命令启用硬件流卸载,
1
2
3
4
5
6
7
uci set firewall.@defaults[0].flow_offloading='1'
uci set firewall.@defaults[0].flow_offloading_hw='1'
uci commit firewall
/etc/init.d/firewall restart
fw4 转发的直连流量可以开启硬件流卸载,一旦流量进入到 sing-box,由 /etc/sing-box/config.json 配置文件中的路由规则判定的直连流量是不能开启硬件流卸载的。
总结
配置完成后,你的家庭网络就实现了:
✅ 透明代理:LAN 设备无需任何配置,所有流量自动进入代理
✅ 智能分流:国内网站直连,国外网站走代理,广告自动拦截
✅ IPv4/IPv6 支持:同时支持 IPv4 和 IPv6
✅ DNS 处理:DNS 查询由 sing-box 处理,配合分流规则精准路由
✅ 开机自启:系统启动后自动恢复所有配置,不需要手动操作
如果后续遇到问题,记住:不要重置路由器,先按照故障排查指南一步步检查,通常能快速定位问题所在。
祝配置顺利!🚀
