摘要
这是sing-box翻墙客户端,一般运行在openwrt上。sing-box的配置一般分为以下几个部分:
logdnsinboundsoutboundsrouteexperimental(可选)
一般每一种配置类型使用一个配置文件,但route规则可能比较多,我将route拆分为两个配置文件,路由规则集配置和路由配置。
GeoIP
- 全称:Geographic IP(地理位置 IP)
- 内容:包含了全球各地的 IP 地址范围段。
- 作用:让软件知道某个 IP 属于哪个国家或哪个特定的组织(如 Google, Cloudflare)。
GeoSite
- 全称:Geographic Domain Sites(地理位置域名列表)
- 内容:包含了各大互联网服务的域名列表,通常按类别(如
category-ads)或国家(如cn)分类。 - 作用:让软件知道某个域名属于哪个服务。
sing-box新版不支持传统geo数据库,而是使用Sing-box Rule-Set文件,后缀为srs。它的设计目的是为了高性能。相比于普通的 JSON 文本文件,srs 经过了预编译和压缩,加载速度极快,且在匹配成千上万条规则时占用的内存非常低。
另外使用geosite、geoip规则有远程规则集和本地规则集两种方式,这里主要介绍使用本地规则集的方式。
构造本地geosite、geoip规则集
下载geosite规则集
直接访问
https://github.com/SagerNet/sing-geosite/tree/rule-set
或者访问
https://github.com/SagerNet/sing-geosite
在分支选择rule-set

下载geoip规则集
方法同geosite,地址如下:
https://github.com/SagerNet/sing-geoip/tree/rule-set
构造本地规则集目录
目前已经得到geosite和geoip两个压缩包。

创建一个文件夹,我这里为rule-set。
将geosite、geoip两个压缩包中的全部srs文件放入rule-set文件夹中。

将rule-set文件夹传入到sing-box工作目录中,这里是:
/usr/share/sing-box/rule-set
log
配置文件路径
/etc/sing-box/conf.d/00_log.json
典型配置文件
{
"log": {
"level": "warn",
"timestamp": true
}
}
日志等级可以指定以下几种:
infowarninfo
dns
配置文件路径
/etc/sing-box/conf.d/10_dns.json
典型配置文件
{
"dns": {
"strategy": "ipv4_only",
"servers": [
{
"tag": "dns-remote",
"type": "https",
"server": "1.1.1.1",
"path": "/dns-query",
"detour": "proxy-default"
},
{
"tag": "dns-local",
"type": "udp",
"server": "192.168.1.2"
}
],
"rules": [
{
"domain_suffix": [
"lan",
"home.arpa"
],
"server": "dns-local",
"disable_cache": true
},
{
"rule_set": [
"geosite-cn",
"geosite-geolocation-cn"
],
"server": "dns-local"
},
{
"rule_set": [
"geosite-geolocation-!cn"
],
"server": "dns-remote",
"disable_cache": true
}
],
"final": "dns-remote",
"independent_cache": true
}
}
inbounds
配置文件路径
/etc/sing-box/conf.d/20_inbounds.json
典型配置文件
{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "singtun0",
"address": [
"172.19.0.1/30"
],
"auto_route": true,
"strict_route": true,
"auto_redirect": false
},
{
"type": "mixed",
"tag": "mixed-in",
"listen": "0.0.0.0",
"listen_port": 7890
},
{
"type": "direct",
"tag": "dns-in",
"listen": "127.0.0.1",
"listen_port": 6053
}
]
}
tun接口
auto_route
自动创建路由,也就是添加系统路由,将流量引入到tun网卡上,如果为false则需要手动添加系统路由到tun网卡才能实现翻墙。该功能只能给流量进行路由,不能修改流量数据包。
strict_route
严格路由,为true时意味着全部流量必须走tun接口,不允许流量走原始网关。可以防止流量绕过代理进而出现DNS泄漏的情况。主要的技术手段就是确保sing-box添加的路由位于最高优先级并对未命中sing-box路由的数据包进行丢弃。与auto_route相同,该功能不能修改流量数据包。
举个例子:在strict_route为false时,因为Linux默认路由的优先级小于本地路由,当openwrt dns指定为本地地址时,dns请求会直接发送到指定dns,而不经过sing-box,进而出现DNS污染。
auto_redirect
自动透明代理,用防火墙规则“劫持流量”进入 sing-box,这个选项基本上可以理解成“是否用防火墙强行抓流量”。该功能具备修改数据包的能力,比如将发给8.8.8.8的DNS请求包的目的地址直接改成sing-box的地址。这个功能主要是给透明代理使用的,在tun模式使用会出现“DNS 自我循环”症状(openwrt的UDP端口耗尽,CPU占用率拉满),所以在tun接口中要关闭这个功能。
mixed接口
这里除了创建了tun虚拟网卡,还开启了混合代理(mixed),即同一个端口同时支持socks和HTTP两种代理模式。
有的时候需要用代理模式来测试sing-box翻墙的有效性,同时又不想设置代理密码增加操作,可以让混合代理只绑定“127.0.0.1”,这样只有sing-box本机可以使用这个代理,这种情况一般在VPS端的sing-box上使用较多。
outbounds
配置文件路径
/etc/sing-box/conf.d/30_outbounds.json
典型配置文件
{
"outbounds": [
{
"type": "urltest",
"tag": "proxy-auto",
"outbounds": [
"hk1-outbound"
],
"url": "https://www.gstatic.com/generate_204",
"interval": "3m",
"tolerance": 50
},
{
"type": "selector",
"tag": "proxy-default",
"outbounds": [
"hk1-outbound"
],
"default": "hk1-outbound"
},
{
"type": "vless",
"tag": "hk1-outbound",
"server": "x.x.x.x",
"server_port": xxx,
"uuid": "x-x-x-x-x",
"flow": "xtls-rprx-vision",
"tls": {
"enabled": true,
"server_name": "www.xxx.com",
"utls": {
"enabled": true,
"fingerprint": "chrome"
},
"reality": {
"enabled": true,
"public_key": "xxxxxxxxxxxxxxxx",
"short_id": "xxxxxx"
}
}
},
{
"type": "direct",
"tag": "direct"
},
{
"type": "block",
"tag": "block-out"
}
]
}
这里面的配置要和VPS上的sing-box服务端对应,服务端具体配置参见:
需要根据sing-box服务器配置填写的字段有以下几个:
serverserver_portserver_namepublic_keyshort_id(可选)
rule-set
配置文件路径
/etc/sing-box/conf.d/40_route_rule_set.json
典型配置文件
{
"route": {
"rule_set": [
{
"tag": "geosite-cn",
"type": "local",
"format": "binary",
"path": "rule-set/geosite-cn.srs"
},
{
"tag": "geoip-cn",
"type": "local",
"format": "binary",
"path": "rule-set/geoip-cn.srs"
},
{
"tag": "geosite-geolocation-cn",
"type": "local",
"format": "binary",
"path": "rule-set/geosite-geolocation-cn.srs"
},
{
"tag": "geosite-geolocation-!cn",
"type": "local",
"format": "binary",
"path": "rule-set/geosite-geolocation-!cn.srs"
}
]
}
}
rule
配置文件路径
/etc/sing-box/conf.d/50_route_rules.json
典型配置文件
{
"route": {
"default_domain_resolver": "dns-local",
"auto_detect_interface": true,
"final": "proxy-unmatched",
"rules": [
{
"inbound": ["dns-in"],
"action": "hijack-dns"
},
{
"inbound": ["tun-in"],
"protocol": "dns",
"action": "hijack-dns"
},
{
"inbound": "tun-in",
"action": "sniff",
"timeout": "1s"
},
{
"inbound": "mixed-in",
"action": "sniff",
"timeout": "1s"
},
{
"ip_cidr": [
"vps1_ip/32",
"vps2_ip/32"
],
"action": "route",
"outbound": "direct"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"domain_suffix": [
"lan",
"home.arpa"
],
"outbound": "direct"
},
{
"protocol": "udp",
"port": [443],
"action": "reject",
"method": "drop"
},
{
"rule_set": [
"geosite-cn",
"geoip-cn",
"geosite-geolocation-cn"
],
"domain_suffix": [
"chiphell.com"
],
"outbound": "direct"
},
{
"rule_set": [
"geosite-geolocation-!cn"
],
"domain_suffix": [
"iwara.tv"
],
"outbound": "proxy-default"
}
]
}
}
hijack-dns的工作过程
配置文件中有一段是
{
"inbound": ["dns-in"],
"action": "hijack-dns"
}
这个dns劫持具体劫持的是什么?
有些APP会硬编码DNS,即不使用操作系统指定的DNS服务器(这里认为是sing-box所在openwrt),比如硬编码8.8.8.8。这些DNS查询流量到了openwrt上,如果不劫持则会直接转发给8.8.8.8,这样就很容易被GFW污染导致翻墙失败。这个劫持的意义就是可以将所有DNS流量都劫持过来,使用sing-box配置的DNS规则进行查询,从而抵抗GFW的DNS污染。
sniff的工作过程
{
"inbound": "tun-in",
"action": "sniff",
"timeout": "1s"
}
通过偷看数据包握手阶段的特定字段(如 TLS 的 SNI 或 HTTP 的 Host),在不解密的情况下识别出该连接要访问的真实域名,从而实现基于域名的精确路由。
嗅探过程:
- 截获请求:一个 App 没发 DNS 请求,直接向某个 IP 发起 TLS 连接(加密连接)。
- 偷看握手:
sing-box拦住这个连接,盯着它发出的第一个“打招呼”的数据包(Client Hello),从中读取出明文传输的 SNI (Server Name Indication)。 - 重新路由:
sing-box瞬间明白“哦,这个IP其实是google.com”,然后查表发现google.com需要走代理,于是就把这个连接转给了你的远端节点。
experimental
配置文件路径
/etc/sing-box/conf.d/60_experimental.json
远程srs规则集
srs规则集url可以从上面提到过的github页面获取到。
{
"tag": "geosite-cn",
"type": "remote",
"format": "binary",
"url": "https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-cn.srs",
"download_detour": "proxy-default"
}
设置dnsmasq上游DNS
目前sing-box已经是一个合格的socks、http代理服务器了,但目前还不能将openwrt作为翻墙旁路由。因为openwrt的DNS服务默认由dnsmasq提供,目前dnsmasq收到DNS查询请求时还无法转发给sing-box,所以要配置dnsmasq的上游DNS为sing-box。
==========================================================================
【 场景 A:未配置转发(默认状态)】
流量直接从 dnsmasq 发往公共 DNS,缺乏策略控制。
用户设备 (PC/手机)
|
| (DNS 请求: 53 端口)
v
[ OpenWrt: dnsmasq ]
|
| (根据 /etc/resolv.conf 转发)
v
[ 运营商 DNS / 公共 DNS (如 114.114.114.114) ]
|
| (返回解析结果)
v
[ 成功解析 ]
==========================================================================
【 场景 B:配置转发给 sing-box(推荐状态)】
流量经由 sing-box 过滤和分流,实现防污染、去广告或规则分流。
用户设备 (PC/手机)
|
| (DNS 请求: 53 端口)
v
[ OpenWrt: dnsmasq ]
|
| ( server=127.0.0.1#6053 ) <-- 核心配置生效处
v
[ OpenWrt: sing-box (监听 6053) ]
|
|--------------------------------------------|
| (分流策略) |
v v
[ 国内 DNS (阿里/腾讯) ] [ 远程 DNS (P DNS/TLS) ]
| |
|-------------------( 返回结果 )--------------|
v
[ 成功解析 (更安全、精准) ]
==========================================================================
在 OpenWrt 中,修改UCI配置文件是最推荐的方式,这里就采用这种方式。dnsmasq 的配置主要存储在 /etc/config/dhcp 文件中。假定sing-box的dns端口是6053,该端口可在inbounds配置中指定。
1. 打开配置文件:nano /etc/config/dhcp
2. 找到 config dnsmasq 这一段,添加或修改以下选项:
- 找到
option resolvfile,将其改为一个不存在的文件或添加option noresolv '1'(防止读取运营商 DNS)。 - 添加
list server '127.0.0.1#6053'。
修改后的样子应该是这样的:
config dnsmasq
option domainneeded '1'
option boguspriv '1'
option noresolv '1' # 不使用本地解析文件
list server '127.0.0.1#6053' # 转发到 6053
option localservice '1'
3. 保存并重启服务:/etc/init.d/dnsmasq restart
发表回复