sing-box
Sing-box 是一个非常强大、多功能的网络代理平台,被称为新一代代理工具的核心。它自2022年底发布以来,凭借其出色的性能和高度的灵活性,迅速在网络社区中流行起来。
核心功能与优势:
Sing-box 旨在提供一个集大成、高性能的解决方案,其主要优势包括:
- 多协议支持:它内置了大量主流协议,包括 VLESS、VMess、Trojan、Shadowsocks、Hysteria2 等,几乎能满足所有用户的需求。这使得它成为一个非常灵活的工具,可以适应不同的网络环境。
- 高性能:Sing-box 使用 Go 语言编写,编译后体积小、运行效率高、内存占用低。这意味着它在任何设备上都能提供流畅稳定的连接。
- 强大的路由功能:这是 Sing-box 的核心亮点。它允许用户根据域名、IP地址、协议类型等多种条件,对网络流量进行精细化分流。例如,你可以设置让访问国内网站的流量直连,而访问国外网站的流量走代理。
- 跨平台:Sing-box 的核心可以运行在 Windows、macOS、Linux、Android 和 iOS 等几乎所有主流操作系统上,这让它具有极强的通用性。
1 | → sing-box version |
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale
- Tags:这些 build tags 表明二进制在编译时包含了哪些可选功能/集成。逐项说明与实务影响:
with_gvisor:包含 gVisor 支持(可用于更强的运行时沙箱隔离)。若要在容器/主机上进一步加固进程隔离,可启用 gVisor 运行。注意:gVisor 会影响网络与系统调用延迟与兼容性。with_quic:支持 QUIC(比如用于加密传输的 QUIC 协议,性能更好、对丢包更鲁棒)。在高延迟或移动网络环境下效果明显。with_dhcp:含 DHCP 客户端/服务相关功能(通常与虚拟网卡/tun/tap 场景有关)。with_wireguard:包含 WireGuard 集成,便于做内网隧道、零信任连接或高性能 VPN。with_utls:包含 uTLS(用户态 TLS 指纹/客户端 hello 定制),用于规避某些流量检测或模拟不同浏览器指纹。with_acme:内置 ACME 客户端支持,能自动申请/续期 Let’s Encrypt 等证书(部署时可减少外部依赖)。with_clash_api:提供与 Clash GUI / 控制面集成的 API,方便在桌面/路由上统一管理/可视化。with_tailscale:包含 Tailscale 相关集成(通过 Tailscale 组网把节点连入私人网格),便于远程管理和内网穿透。
- 实务建议:确认是否确实需要所有这些功能;每增加一个集成都会扩大攻击面与维护复杂度。原则:按需启用。
安装sing-box
源码安装
获取源码并编译:
1 | git clone https://github.com/SagerNet/sing-box.git |
可以将二进制文件复制到系统目录:
1 | sudo cp sing-box /usr/local/bin/ |
全功能编译
1 | # 所有功能全开 + 最佳体积优化 |
跨平台编译:
1 | # Linux AMD64: |
官方Debian/APT:
1 | sudo mkdir -p /etc/apt/keyrings && |
手动安装:
1 | # 稳定版发行版 |
为了让 sing-box 在服务器上长期稳定运行(即使关闭 SSH 连接或重启后也能自动启动),需要将其设置为一个系统服务。
systemd (现代 Linux 系统标准)
创建服务文件: sudo nano /etc/systemd/system/sing-box.service
1 | [Unit] |
然后就可以通过systemd管理服务了。
配置文件结构与核心概念
JSON 配置整体架构
- Sing-box 的所有行为都由一个 JSON (JavaScript Object Notation) 文件定义。JSON 是一种键值对的文本格式,你需要严格遵守其语法(例如,花括号
{}代表对象,方括号[]代表数组,字符串必须用双引号""包裹,条目间用逗号,分隔)。 - 配置文件主要由以下几个顶层模块构成:
log: 日志模块。控制日志的输出级别(如 debug, info, warn, error)和格式。是排查问题的首要入口。dns: DNS 模块。配置上游 DNS 服务器、解析策略、FakeIP 等,对流量分流和抗 DNS 污染至关重要。inbounds: 入站模块。定义 Sing-box 如何接收来自客户端(如浏览器、其他应用)的流量。它是一个数组,可以配置多个不同协议的入站。outbounds: 出站模块。定义 Sing-box 如何将处理后的流量发送出去(例如,连接到代理服务器、直接连接目标网站、或阻止连接)。它也是一个数组,可以配置多个出站。route: 路由模块。这是 Sing-box 的“大脑”,它根据你设定的规则(rules),决定将来自某个inbound的流量导向哪个outbound。
- Sing-box 的所有行为都由一个 JSON (JavaScript Object Notation) 文件定义。JSON 是一种键值对的文本格式,你需要严格遵守其语法(例如,花括号
参数层级与作用范围
- 配置是层层嵌套的。例如,
inbounds数组中的每一个元素都是一个独立的对象,这个对象有自己的参数,如type(协议类型),listen(监听地址),listen_port(监听端口), 以及最重要的tag。 tag(标签): 这是配置中最重要的概念之一。tag是一个你自定义的字符串,用于唯一标识一个入站或出站。路由模块 (route) 就是通过tag来引用这些出站的。所有需要被路由引用的入站和出站都必须有一个唯一的tag。
- 配置是层层嵌套的。例如,
简单来说,就是:从 inbounds 接收连接 → route 决定走向 → 导向 outbounds 发送。
配置文件结构:
1 | { |
写一个最小配置:SOCKS5 入站 + Direct 出站
这个配置的功能是:在本地
1080端口开启一个 SOCKS5 代理,所有通过这个代理的流量都直接连接到目标服务器(不经过任何其他代理)。创建
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{
"log": {
"level": "info",
"output": "box.log", // 输出文件路径。启用后不会将日志写入控制台。
"timestamp": true
},
"inbounds": [
{
"type": "socks",
"tag": "socks-in",
"listen": "127.0.0.1",
"listen_port": 1080
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
}
],
"route": {
"rules": [
{
"inbound": "socks-in",
"outbound": "direct-out"
}
]
}
}解读:
inbounds里定义了一个tag为socks-in的 SOCKS5 代理,监听在127.0.0.1:1080。outbounds里定义了一个tag为direct-out的直连出站。route.rules里只有一条规则:所有从socks-in进来的流量,全部交给direct-out处理。
检查配置文件有没有错误:
1 | sing-box check -c /path/to/config.json |
创建一个最简单的 sing-box 配置文件 minimal.json。这个配置文件将实现一个基础的代理功能。
minimal.json 文件:
1 | { |
解读:
- **
log**:我们设置了日志级别为info,这将打印出服务启动和关键运行信息,帮助我们了解 sing-box 是否正常工作。 - **
inbounds**:我们定义了一个入站,类型是 **http**,监听地址是::(所有地址,包括 IPv4 和 IPv6),端口是1080。这意味着 sing-box 会在1080端口上等待一个 http 协议的连接。tag(标签)是http-in,这是我们给这个入口起的名字。 - **
outbounds**:我们定义了一个出站,类型是 **direct**。direct是一个特殊的类型,意味着“直连”,即不使用任何代理,直接将流量发送到目的地。它的标签是direct-out。 - **
route**:我们只设置了一条简单的规则。"outbound": "direct-out"意味着所有收到的流量都将被导向名为direct-out的出站,也就是直连。
进入到保存 minimal.json 文件的目录,然后运行以下命令:
1 | sing-box run -c minimal.json |
观察终端的输出。 如果一切顺利,你会看到类似“sing-box started”的字样,这表示你的服务已经成功运行了。
然后,你可以尝试在你设备的代理设置中,将代理类型设置为 http,地址设置为 **127.0.0.1**,端口设置为 **1080**,然后尝试访问一个网站。如果能正常访问,恭喜你,你的第一个 sing-box 服务已经成功运行了!
调节日志级别分析配置问题
将上面配置中的
"level": "info"修改为"level": "debug"。1
2
3
4
5
6
7{
"log": {
"level": "debug",
"timestamp": true
},
...
}现在重新运行
sing-box run -c config.json并通过这个代理访问一个网站(例如curl -x http://127.0.0.1:1080 https://www.google.com)。你会看到终端输出了远比
info级别详细得多的信息,包括连接的来源、目标、匹配到的路由规则等。这是调试路由规则不生效、连接失败等问题的最重要手段。
核心功能
入站协议 (Inbounds)
学习目标:掌握常见入站协议的配置和使用场景,能够根据实际需求(本地代理、远程服务器、透明代理等)选择并配置最合适的入站方式。
入站(Inbound)定义了 Sing-box 如何“接收”流量。根据使用场景,可以分为三类:本地代理、远程代理和系统级代理。
SOCKS5、HTTP → 本地代理
场景: 在客户端上,如个人电脑,为浏览器等应用程序提供代理服务。这是最基础、最常见的用法。
socks: 支持 TCP 和 UDP 流量,通用性强,是本地代理的首选。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17{
"type": "socks",
"tag": "socks-in",
"listen": "127.0.0.1",
"listen_port": 1080
}
// 也可设置用户名和密码,users是数组,可以设置多个用户及密码对。
{
...
"users": [
{
"username": "admin",
"password": "password"
}
]
}http: 主要用于 HTTP/HTTPS 流量,一些不支持 SOCKS5 的老旧应用可能会需要它。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17{
"type": "http",
"tag": "http-in",
"listen": "127.0.0.1",
"listen_port": 8080
}
// 同样也可设置用户名和密码认证,我的小米11手机wifi设置中只支持http代理,而且不支持设置用户及密码
{
...
"users": [
{
"username": "admin",
"password": "admin"
}
]
}
mixed:是 socks4、socks4a、socks5 和 http 混合代理
1
2
3
4
5
6
7
8
9
10
11
12
13
14{
"type": "mixed",
"tag": "mixed-in",
... // Listen Fields
"users": [
{
"username": "admin",
"password": "admin"
}
],
"set_system_proxy": false // 仅支持 Linux、Android、Windows 和 macOS
}direct: 监听
tcpudp之一1
2
3
4
5
6
7
8
9
10{
"type": "direct",
"tag": "direct-in",
... // Listen Fields
"network": "udp",
"override_address": "1.0.0.1", // 如果未设置listen,可以设置override覆写 具体什么作用后面再研究
"override_port": 53
}
VMess、VLESS、Trojan → 远程代理 (服务端)
- 场景: 通常配置在你的 VPS(云服务器)上,用于接收从客户端发来的加密流量。
vless: 目前主流推荐的协议。它本身不加密,依赖于下层传输(Transport)的 TLS 来提供安全性,性能高,扩展性强。vmess: V2Ray 的经典协议,自带加密和验证机制,配置相对 VLESS 复杂一些。trojan: 一种模仿 HTTPS 协议的代理,旨在将代理流量伪装成正常的网站访问,抗审查能力强。
Shadowsocks → 轻量化兼容 (服务端/客户端)
- 场景: 一个非常流行且轻量级的加密代理协议,因其简单高效而被广泛使用。可以作为服务端入站,也可以在某些特殊场景下作为客户端入站(例如,链式代理)。
- 支持多种加密方法(
method),包括aes-256-gcm和chacha20-poly1305等。
Hysteria2、TUIC → 高性能 UDP (服务端)
- 场景: 专为不稳定和高延迟网络(如跨国、移动网络)优化的现代协议。它们基于 QUIC (UDP),能有效降低连接延迟、抵抗丢包,非常适合视频通话、在线游戏等对实时性要求高的场景。
WireGuard → VPN 场景 (服务端)
- 场景: 将 Sing-box 作为一台 WireGuard VPN 服务器。客户端连接后,会获得一个虚拟局域网 IP,所有流量都通过 VPN 隧道传输。它工作在网络层,与应用层的 SOCKS/HTTP 代理不同。
TUN、TProxy → 系统级代理
- 场景: 实现“透明代理”或“全局代理”,无需为每个应用程序单独配置代理。所有(或指定的)系统网络流量都会被自动接管。
tun: 创建一个虚拟网卡。Sing-box 会捕获所有路由到这个网卡的流量。这是在 Windows/macOS/Linux/Android/iOS 上实现全局代理的通用方式。移动端客户端的“VPN”模式就是基于 TUN 实现的。tproxy: (仅 Linux)一种透明代理模式,通常用在路由器或网关设备上。它需要配合iptables或nftables等防火墙工具进行复杂的流量重定向。
vless
除了listen fields,Fields中包括: users(必需)、users.uuid(必需)、users.flow、tls、multiplex、transport
users(数组,必填)uuid(string,必填):用户唯一 ID,客户端必须一致。可使用sing-box generate uuid或uuidgen生成。flow(string,可选):流控模式,XTLS 特有,可用值:xtls-rprx-vision。
结构:
1 | { |
实践
为了学习和测试基础功能 ,建立一个基础的代理隧道,不考虑高级别的伪装和抗审查,那么使用 IP 地址且不加 TLS 的配置会简单得多。
不使用tls 配置块:在服务端入站和客户端出站中,都不再需要 tls 对象。
不指定transport 配置块:当不指定 transport 时,Sing-box 默认使用原生 TCP 进行数据传输。这是最简单、最直接的方式。
使用 IP 地址:在客户端出站的 server 字段中,直接填写服务端的 IP 地址。
更改端口:由于不使用 TLS,我们不再需要占用 443 端口。可以选择一个不常用的高位端口(例如 10000-65535 之间),以避免端口冲突。
服务端:
1 | { |
客户端:
1 | { |
注意:
- 安全性: 这种连接是未加密的。虽然 VLESS 协议本身不是明文,但流量特征非常明显。中间人可以轻易地观察到你在使用代理,并且在技术上有可能解包和分析你的流量。
- 抗审查性: 极低。由于没有 TLS 伪装,这种流量很容易被防火墙(如 GFW)通过深度包检测 (DPI) 识别并阻断。
在服务器上配置一个 VLESS 入站,vless + tls,使用acme协议自动获取证书。
服务端
config.json示例 (VLESS + TLS):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{
"log": { "level": "info" },
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "0.0.0.0",
"listen_port": 443,
"users": [
{
"uuid": "你的UUID", // 请使用 `sing-box generate uuid` 命令生成
"flow": "xtls-rprx-vision"
}
],
"transport": {
"type": "ws" // 使用 WebSocket 作为传输层
},
"tls": {
"enabled": true,
"server_name": "你的域名",
"acme": {
"domain": "你的域名",
"email": "你的邮箱",
"disable_http_challenge": true,
"disable_tls_alpn_challenge": false
}
}
}
],
"outbounds": [
{ "type": "direct", "tag": "direct" }
],
"route": {
"rules": [
{ "inbound": "vless-in", "outbound": "direct" }
]
}
}- 说明: 此配置监听
443端口,使用 VLESS 协议和 WebSocket 传输。TLS 证书通过 ACME 自动申请和续签。客户端需要使用对应的 UUID、域名、端口443和 WebSocket 路径 (/) 来连接。 transport如果不设置path对外观上不做任何伪装(容易被 DPI 或流量分析识别为非普通网站流量), 无法和其他 Web 服务区分。TLS与加密- 一般要添加ntp模块,原因后面再讲。
- 说明: 此配置监听
配置 TUN 入站,使整个系统透明代理 (客户端配置)
- 场景: 在你的个人电脑上,让所有网络请求都通过 Sing-box 处理,移动端通常用这种方式,显示vpn。
- 客户端
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{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "sing-tun",
"stack": "system",
"address": [ // 地址不能和客户端物理ip在同一网段,否则路由循环
"172.19.0.1/30", // IPv4 地址
"fd12:3456:789a::1/126" // IPv6 地址
],
"auto_route": true, // 自动设置系统路由
"strict_route": true
}
],
"outbounds": [
// ... 此处应配置你的 VLESS/Trojan 等服务器出站 ...
{
"type": "vless",
"tag": "vless-out",
// ... 服务器连接信息 ...
},
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"rules": [
{
"inbound": "tun-in",
"outbound": "vless-out" // 将所有来自 TUN 的流量都发往代理服务器
}
]
}
}- 说明: 运行此配置需要管理员/root 权限。启动后,Sing-box 会创建一个名为
sing-tun的虚拟网卡,并自动修改系统路由表,将大部分网络流量导向这个网卡,从而实现全局代理。
- 说明: 运行此配置需要管理员/root 权限。启动后,Sing-box 会创建一个名为
延伸:理解 VLESS 与 VMess 在加密、性能和抗审查上的差异
- 加密:
- VMess: 内置了一层独立的加密,流量特征相对明显。时间验证严格,客户端与服务端时间相差不能过大。
- VLESS: 协议本身不包含加密。它是一个轻量化的传输协议,完全依赖于外层的 TLS (或其他加密传输) 来保证数据安全。这使得它的流量特征与标准 HTTPS 流量几乎无法区分。
- 性能:
- 由于 VLESS 移除了不必要的加密层,减少了数据包的处理开销,其性能通常优于 VMess。在相同的硬件和网络环境下,VLESS 能达到更高的吞吐量和更低的延迟。
- 抗审查:
- 两者都可以通过伪装(如 WebSocket、gRPC)和 TLS 来抗审查。但 VLESS 的设计哲学使其更“纯粹”地依赖于 TLS,伪装效果更好。特别是配合
XTLS Vision这样的“流控”(flow)技术时,可以进一步减少 TLS 加密/解密的次数,提升性能并降低被探测的风险。**因此,对于抗审查和性能,VLESS 是当前的首选方案。
- 两者都可以通过伪装(如 WebSocket、gRPC)和 TLS 来抗审查。但 VLESS 的设计哲学使其更“纯粹”地依赖于 TLS,伪装效果更好。特别是配合
出站协议 (Outbounds)
学习目标:能够设计由多个出站构成的复杂结构,为精细化的流量分流和自动化的容灾、择优打下基础。
出站(Outbound)定义了 Sing-box 将接收到的流量发往何处。除了连接到代理服务器,它还包括了许多强大的控制和组合功能。
Direct、Block → 基础控制
direct: 这是最基础的出站,代表直连。所有导向此出站的流量都会通过设备自身的网络直接访问目标服务器,不经过任何代理。这是分流国内流量、访问局域网设备的基础。1
2
3
4{
"type": "direct",
"tag": "direct-out"
}block: 代表阻止。所有导向此出站的流量都会被直接丢弃,就像一个黑洞。它常用于屏蔽广告、跟踪器和恶意网站。1
2
3
4{
"type": "block",
"tag": "block-out"
}
VMess/VLESS/Trojan/Shadowsocks → 主流代理出口
- 场景: 这是出站的核心功能,定义了如何连接到你的远程代理服务器。我们在此前的客户端配置中已经反复使用过
vless类型的出站。其他协议的配置也大同小异,只是认证参数不同(例如 Shadowsocks 使用密码和加密方法,VMess 使用uuid和alterId等)。1
2
3
4
5
6
7
8{
"type": "vless",
"tag": "proxy-us", // 给节点起一个有意义的标签
"server": "us.yourdomain.com",
"server_port": 443,
"uuid": "your-uuid",
// ... tls 和 transport 配置 ...
}
- 场景: 这是出站的核心功能,定义了如何连接到你的远程代理服务器。我们在此前的客户端配置中已经反复使用过
Hysteria2、TUIC → 高速出口
- 场景: 当你的代理服务器支持这些基于 QUIC 的高性能协议时,配置相应的出站可以显著改善在高延迟、易丢包网络(如移动网络)下的体验,尤其适合视频、游戏等场景。
URLTest、Selector → 多出口负载均衡与自动/手动切换
- 这是出站的精髓所在。它们本身不是代理协议,而是**出站组 (Outbound Group)**,用于管理和调度其他出站。
selector(手动选择): 提供一个预设的出站列表,让你可以在客户端(通常是 GUI 客户端)或通过 API 手动切换当前要使用的出口。就像一个电视遥控器,你想看哪个频道就按哪个。- 应用场景: 你有日本、美国、香港三个节点。你想看 Netflix 时,手动切换到美国节点;想玩日服游戏时,手动切换到日本节点。
urltest(自动测速选择): 它包含一个出站列表,并会定期向一个测试 URL (如http://www.gstatic.com/generate_204) 发送请求,自动选择延迟最低的出站作为出口。这是实现“永远用最快的节点”的自动化策略。- 应用场景: 你有多个性质相同的节点,不关心具体是哪个,只要保证当前用的是最快的就行。
实践
配置多个 outbounds,并用路由规则区分流量
- 这个实践的核心在于定义好“零件”,为下一节的“路由系统”做准备。
- 在你的客户端
config.json的outbounds数组中,配置如下结构: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"outbounds": [
// 出站 1: 美国代理节点
{
"type": "vless",
"tag": "proxy-us",
"server": "us.yourdomain.com",
// ... 其他参数 ...
},
// 出站 2: 日本代理节点
{
"type": "trojan",
"tag": "proxy-jp",
"server": "jp.yourdomain.com",
// ... 其他参数 ...
},
// 出站 3: 直连
{
"type": "direct",
"tag": "direct-out"
},
// 出站 4: 拦截
{
"type": "block",
"tag": "block-out"
}
] - 解读: 我们现在有了四个可以被路由规则 (
route.rules) 调用的“目的地”:proxy-us,proxy-jp,direct-out,block-out。
设置 URLTest 自动选择延迟最低的节点
- 在上述配置的基础上,我们再增加一个
urltest类型的出站。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15"outbounds": [
// ... (保留 proxy-us, proxy-jp, direct-out, block-out 的定义) ...
// 出站 5: 自动测速组
{
"type": "urltest",
"tag": "auto-proxy", // 给这个自动组起一个标签
"outbounds": [
"proxy-us", // 引用上面定义的出站标签
"proxy-jp"
],
"url": "http://www.gstatic.com/generate_204",
"interval": "10m" // 每10分钟测试一次延迟
}
] - 解读: 我们创建了一个名为
auto-proxy的新出口。当路由规则将流量指向auto-proxy时,Sing-box 会自动从proxy-us和proxy-jp中选择当前延迟最低的一个来发送流量。这极大地提升了网络的稳定性和速度。
- 在上述配置的基础上,我们再增加一个
vless
Inbound(服务端)里的 vless 用 users 数组,uuid 在 users 里;但 outbound(客户端/上游)里的 vless 则把 uuid 放在顶层字段 uuid。 这点常被混淆,导致 "json: unknown field \"encryption\"" 之类的报错或 unknown field "users" 的错误。
结构:
1 | { |
字段:
type(string,必填)
- 固定为
"vless",用于标识 outbound 类型。
tag(string,可选但强烈建议)
- 出站的标签,路由/调试时引用,用于
route.final或规则指定上游。生产环境建议给明确名字(如vless-ws-vps1)。
server(string,必填)
- 上游服务器地址(IP 或域名)。在未来版本若使用域名并且有多个 DNS,请注意
domain_resolver的配置
server_port(int,必填)
- 远端监听端口(例如 443、8443、23456 等)。
uuid(string,必填)
- VLESS 用户 ID(客户端用此认证到服务端)。注意:outbound 是顶层
uuid,不是users数组(inbound 才用users)。如果服务端用多个用户,在客户端上必须选择匹配的uuid。
flow(string,可选)
- VLESS 子协议流控,目前文档列出的值主要为
xtls-rprx-vision(用于 XTLS / Vision 场景)。只有在服务端/上游支持此 flow 时才配置。
network(string,可选)
指定允许的网络类型:
"tcp"或"udp"。两者默认都是启用的(即不写就同时支持);若把它写成tcp,就可能导致 UDP 不被转发(例如 DNS 或游戏流量会失效)。生产若需同时支持 TCP/UDP 通常可不写或明确根据需求设置。tls(object,可选)TLS 客户端选项(当上游是 TLS/REALITY 时需要):常见字段:
enabled(bool):启用 TLS。server_name(string):用于 SNI / 证书验证(client only)。insecure(bool):在测试时可接受任意证书(不推荐生产使用)。disable_sni(bool):在 ClientHello 中不发送 SNI。alpn(array):ALPN 列表(例如["h2","http/1.1"])。certificate_public_key_sha256、utls、ech、reality等高级字段可做证书 pin、ClientHello 指纹仿真或启用 REALITY。
实战建议:生产用真实域名 + 合法证书(或 pin 公钥),测试时可用
insecure: true。
packet_encoding(string,可选)
- 针对 UDP 的编码方式(仅与 UDP 相关)。可选值示例:
""(禁用)、packetaddr(v2ray5+ 支持)或xudp(xray 支持)。如果你要穿透 NAT 或做 UDP 转发(游戏/VoIP),这里需正确配置并保证两端兼容。
multiplex(object,可选)
- 多路复用设置(如果服务端也支持),用于在一个 TCP/TLS 连接内复用多个逻辑流,减少握手数,提高并发效率。生产使用需确认上游是否支持并评估对延迟/连通性的影响。
transport(object,可选)
- V2Ray Transport 配置(WebSocket / HTTP / QUIC / gRPC / HTTPUpgrade 等),常见子字段:
type:"ws"|"http"|"quic"|"grpc"|"httpupgrade"。- 对
ws:path、headers、max_early_data、early_data_header_name等(path必须和服务端一致,early_data_header_name用于与 Xray 兼容)。 - 对
http:host、path、headers等。
- 如果你要用
VLESS+WS,就在 outbound 写transport.type = "ws"并在transport.ws.path指定路径(客户端与服务器必须一致)。
路由系统 (Route System)
sing-box 中的路由(route / route rules)
route 的总体结构(顶层字段)
route是顶层对象,用来把“入站流量”映射到特定outbound、执行特殊动作(reject、hijack-dns、sniff 等)或设置默认策略。常见字段:rules:规则数组(核心,按规则逐项匹配)。rule_set:外部/远程规则集列表(把大型域名/IP 列表托管为 rule-set)。final:当没有任何规则匹配时的默认 outbound tag(若空,使用第一个 outbound)。auto_detect_interface/default_interface/default_mark:与多网卡 / TUN 场景相关,用来防止路由回环并控制出站绑定。default_domain_resolver/default_network_strategy等:影响规则内建立连接时的解析与联网策略。
规则的匹配逻辑(默认组合逻辑)
每条 route rule 的默认匹配逻辑是:
(domain 或 domain_suffix 或 domain_keyword 或 domain_regex 或 geosite 或 geoip 或 ip_cidr 或 ip_is_private)&& (port 或 port_range)&& (source_geoip 或 source_ip_cidr 或 source_ip_is_private)&& (source_port 或 source_port_range)&& (其它字段)也就是说:域名/IP/规则集 等是最基础的匹配条件,端口/源地址 等作为进一步筛选。条目里可以组合多种字段以做到精确匹配。
常用匹配字段(按用途用)
下面按类别列出常用字段,并说明实际场景和注意点。
- 域名相关
domain:精确域名匹配(例:"example.com")。domain_suffix:域名后缀(例:.google.com,匹配*.google.com)。domain_keyword:只要包含关键字就匹配(例:"video")。domain_regex:正则匹配(注意性能与正确转义)。- 实战建议:对常见网站用
domain_suffix做白名单/直连,针对单站用domain。
- IP / 网段
ip_cidr:直接用 CIDR(例:"1.2.3.0/24")。ip_is_private:匹配 RFC1918 / 私有网段(方便把内网地址走direct)。- 注意:域名->IP 并不会总是在路由阶段自动展开到 IP。若你想基于 IP 规则路由,要确保请求本身是 IP 或使用 reverse mapping / 显式解析。
- 端口
port/port_range:按目的端口过滤(如 53、443、游戏端口段等)。- 场景:把 53/853(DNS/DoT)单独拦截、把游戏端口走支持 UDP 的节点等。
- 源(source)相关
source_ip_cidr、source_port、source_ip_is_private:当 sing-box 被用作网关 / TUN 时,可区分“哪个客户端发来的请求”。例如:只让局域网内某台机器走特定 outbound。
- 进程 / 应用(只在桌面/支持平台生效)
process_name/process_path/process_path_regex:把某个进程(比如curl、steam.exe)的流量单独路由到 direct 或专用代理。注意:此项仅在 Linux/Windows/macOS 支持,移动平台不可用。
- 平台/网络类型(GUI 客户端/移动端相关)
network_type(wifi/cellular/ethernet)、network_is_expensive等,用于在移动场景下按网络类型做不同策略(节省流量/切换节点)。
- 逻辑/复合规则
type: "logical"+mode: "and"|"or"+rules: [ ... ]:可以把几条子规则组合成复杂逻辑。
规则 action(匹配到后能做什么)
action是必须项(默认是route),常见 action 有:route:把流量送到指定outbound。outbound字段填写目标 outbound 的tag。reject:在建立连接前直接拒绝(对 TCP 发 RST,对 UDP 可返回 ICMP unreachable,1.13+ 支持对 ping/ICMP 拒绝)。sniff:触发协议嗅探(例如在 TUN 场景对 TLS/HTTP 做进一步判定),可与timeout一起控制嗅探时间。hijack-dns:把 DNS 请求拦截到 sing-box 的 DNS 模块(用于 fakeip / hijack 场景)。resolve/route-options:在 DNS 规则里可为 DNS 选择上游 server 或配置 rewrite TTL。
rule_set(规则集)与“无头规则”(headless rule)
rule_set用来引用大型的外部规则文件(URL、定期更新),适合维护大型域名/IP 列表。rule_set会被合并到规则集合中。- 外部 rule-set 与本地 rule 的合并/优先级可能带来奇怪行为,所以把关键/精确的规则写在本地靠前更可靠。
- Headless Rule(用于 rule-set 文件格式)是无
action的规则集合,常用于 DNS、rule-set 的子规则格式。
域名解析(DNS)与路由的关系
- sing-box 在匹配路由时并不总是把域名先解析成 IP 来再用 IP 规则匹配。
- 解决方法:
- 使用
hijack-dns+ fakeip:DNS 请求被劫持并返回 fake IP,之后可以反查回域名用于路由。 - 使用
default_domain_resolver/outbound.domain_resolver显式指定解析器,以避免连接走错出口。
- 使用
典型 route JSON 示例
1 | "route": { |
常见坑、调试建议与最佳实践
- 顺序重要:把精确/危险的规则放前面,通用/catch-all 的放后面。
- 不要盲用 geosite / geoip:建议迁移到 rule-set 或其它方案。
- 域名与 IP 的匹配差异:IP 规则对域名请求未必生效,需启用 reverse mapping / DNS hijack / explicit resolving。
- TUN 环境注意回环:开启
auto_detect_interface/ 设置default_interface与outbound.bind_interface可以避免回环。 - 进程规则在不同平台差异化:移动端/部分 GUI 客户端受限。
- 启用日志,校验并观察路由匹配与 DNS 行为。
掌握编写路由规则的逻辑,实现精准、高效、自动化的流量调度与分流。
路由模块 (route) 的核心是 rules 数组。Sing-box 会从上到下依次检查这个数组中的每一条规则。一旦流量匹配了某条规则,就会被交给该规则指定的 outbound 处理,后续的规则将不再被检查。这个 “第一匹配原则” 是理解所有路由行为的基础。
rules的基本语法- 每一条规则都是一个 JSON 对象,通常包含一组“匹配条件”和一个“出口动作” (
outbound)。 - 基本结构:
1
2
3
4
5
6{
"//": "这是一个注释,说明规则的用途",
"MATCH_CONDITION_1": ["value1", "value2"],
"MATCH_CONDITION_2": "value3",
"outbound": "tag_of_your_outbound"
}
- 每一条规则都是一个 JSON 对象,通常包含一组“匹配条件”和一个“出口动作” (
按域名、IP、端口、协议分流 (常见的匹配条件)
domain,domain_suffix,domain_keyword,domain_regex: 按域名匹配。"domain_suffix": [".cn", "aliyuncs.com"]是最高效、最常用的方式,匹配所有以.cn或aliyuncs.com结尾的域名。
ip_cidr: 按目标 IP 地址或地址段匹配。"ip_cidr": ["192.168.0.0/16", "10.0.0.0/8"]匹配所有内网 IP 地址。
destination_port: 按目标端口匹配。"destination_port": [22, 3389]匹配 SSH 和 RDP 流量。
protocol: 按应用层协议匹配(需要开启嗅探)。"protocol": ["http", "tls", "bittorrent"]匹配特定协议的流量。
GeoIP、Geosite 数据库的使用
- 这是实现自动化、精准分流的核心武器。它们是预先编译好的域名和 IP 地址列表,让你无需手动维护成千上万条规则。
- 前提: 你需要下载
geoip.db和geosite.db这两个数据库文件,并将它们与你的config.json放在同一个目录下。你可以从SagerNet/sing-geoip的 GitHub Releases 页面获取最新版本。 geoip: 按国家/地区 IP 归属匹配。"geoip": "cn"匹配所有归属于中国的 IP 地址。
geosite: 按网站/服务域名集合匹配。"geosite": "cn"匹配所有常见的中国网站域名。"geosite": "google"匹配 Google 旗下所有服务的域名。"geosite": "category-ads-all"匹配所有已知的广告域名。
Sniffing(域名嗅探)实现 SNI 分流
- 场景: 当你访问一个
https网站时,你的 DNS 查询和实际的 TLS 连接是分开的。如果 DNS 查询受到了污染,Sing-box 可能只知道你在连接一个 IP 地址,而不知道你访问的真实域名,导致基于域名的分流规则失效。 - 原理: 在
inbounds中开启sniff: true后,Sing-box 会尝试“嗅探” TLS 连接的初始 ClientHello 包,从中读取 SNI (Server Name Indication) 字段,这个字段包含了客户端想要访问的真实域名。 - 配置:
1
2
3
4
5
6
7
8
9"inbounds": [
{
"type": "tun",
"tag": "tun-in",
// ...其他tun参数...
"sniff": true,
"sniff_override_destination": true // 建议开启,用嗅探结果作为真实目标
}
]
- 场景: 当你访问一个
实践
我们将使用上一节定义的 outbounds (proxy-us, proxy-jp, auto-proxy, direct-out, block-out) 来构建一个经典的路由配置。
实现 “国内流量直连,国际流量走代理” 并屏蔽广告
- 这是一个非常实用和通用的路由配置。注意规则的顺序至关重要。
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"route": {
"rules": [
// 规则 1: 屏蔽所有广告流量
{
"geosite": "category-ads-all",
"outbound": "block-out"
},
// 规则 2: 所有内网流量直连
{
"geosite": "private",
"outbound": "direct-out"
},
// 规则 3: 中国大陆地区的 IP 直连
{
"geoip": "cn",
"outbound": "direct-out"
},
// 规则 4: 常见的中国大陆域名直连
{
"geosite": "cn",
"outbound": "direct-out"
},
// 规则 5 (最终规则): 其他所有流量都走自动测速的代理出口
{
"network": ["tcp", "udp"], // 匹配所有TCP和UDP流量
"outbound": "auto-proxy"
}
]
}
- 这是一个非常实用和通用的路由配置。注意规则的顺序至关重要。
实现 “Netflix/Disney+ 走美国节点,其他国外流量自动选择,国内流量直连”
- 这个需求需要在上面的基础上,插入针对特定服务的规则。因为“第一匹配原则”,特定服务的规则必须放在通用规则(如
geoip:cn)的前面。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"route": {
"rules": [
// 规则 1: 屏蔽广告 (优先级最高)
{
"geosite": "category-ads-all",
"outbound": "block-out"
},
// 规则 2 (新增): Netflix 流量,强制走美国节点
{
"geosite": "netflix",
"outbound": "proxy-us"
},
// 规则 3 (新增): Disney+ 流量,也走美国节点
{
"geosite": "disney",
"outbound": "proxy-us"
},
// --- 以下规则与上一个例子相同 ---
{
"geosite": "private",
"outbound": "direct-out"
},
{
"geoip": "cn",
"outbound": "direct-out"
},
{
"geosite": "cn",
"outbound": "direct-out"
},
{
"network": ["tcp", "udp"],
"outbound": "auto-proxy"
}
]
}
- 这个需求需要在上面的基础上,插入针对特定服务的规则。因为“第一匹配原则”,特定服务的规则必须放在通用规则(如
探索高级场景,例如基于进程名或设备分流
- 基于进程名/包名分流 (Android/Linux/macOS): 这是一个杀手级功能。你可以让特定 App 的流量走指定的出口,而其他 App 走默认规则。
- 匹配条件:
process_name(进程名, e.g.,chrome),process_path(进程完整路径),package_name(Android 包名, e.g.,com.android.chrome)。 - 示例: 让 Telegram 走日本节点,Chrome 走美国节点。
1
2
3
4
5
6
7
8{
"package_name": "org.telegram.messenger",
"outbound": "proxy-jp"
},
{
"package_name": "com.android.chrome",
"outbound": "proxy-us"
}
- 匹配条件:
DNS 系统
能够设计和配置一套高性能、精准、抗污染的 DNS 解析策略,并理解 FakeIP 的工作原理及其优势。
路由系统决定了流量的“去向”,而 DNS 系统则决定了流量“找路”的准确性和效率。一个设计良好的 DNS 系统能有效防止 DNS 污染,提升访问速度,并与路由系统完美配合。
结构:
1 | { |
- sing-box 的 DNS 模块负责域名解析,并可用于:
- 驱动基于域名的路由决策(domain-driven routing);
- 做 DNS 劫持(hijack-dns)与 fake-IP(把域名解析成内网/保留 IP,再通过路由把流量导向代理);
- 提供多种上游协议(UDP/TCP/DoT/DoH/HTTP3/QUIC 等),并支持按规则选择解析器或修改解析行为(如 rewrite TTL、EDNS client subnet)。
- 你在 config 中的
dns是全局对象(dns.servers、dns.rules、dns.fakeip等),很多运行时行为(缓存、reverse mapping、client_subnet)在这里配置。
顶层字段
servers:DNS 服务器数组(每个 entry 指定类型、tag、address、detour/transport 等)。rules:DNS 专属的规则数组(按顺序匹配,匹配后执行该规则的 action,如 route/reject/predefined)。final:未命中任何 rule 时使用的默认 DNS server tag(为空则使用servers[0])。strategy:解析策略(prefer_ipv4、prefer_ipv6、ipv4_only、ipv6_only)。disable_cache/disable_expire:是否关闭缓存或关闭缓存过期(调试用)。independent_cache:是否让每个 DNS server 拥有独立缓存(特殊场景下有用,但性能略降)。cache_capacity:LRU 缓存大小(>=1024 生效)。reverse_mapping:是否在响应时保存 IP→domain 的反向映射(fake-IP + domain 驱动路由时常需要)。client_subnet:全局 EDNS-Client-Subnet 前缀,单条规则可以覆盖它。fakeip:fake-IP 服务配置(启用、IPv4/IPv6 区间等)。- 小结:这些字段决定解析方式、缓存行为、fake-IP 的生成与后续路由是否能“把 IP 反查回域名”。
DNS Server 类型(常用到的几种)
udp/tcp:传统 DNS over UDP/TCP,上游地址可写 IP 或域名(若用域名须配置 domain_resolver)。udp默认端口 53,tcp类似。适合低延迟环境,但被劫持/篡改风险高。- 典型字段:
server(地址)、server_port(端口)、dial 字段(超时、绑定等)。
- 典型字段:
tls(DoT):DNS over TLS,端口通常 853,适合对抗被篡改且性能相对稳定。https(DoH):DoH(默认 path/dns-query,port 443),支持自定义 headers 与 TLS 选项,浏览器 + 本地 DoH 配合很好。h3/quic:HTTP/3 或 QUIC 上的 DNS(新选项,适合高丢包或想用 h3 ALPN 的场景)。local/hosts:内置本地解析或 hosts 文件式解析,适合把内部域名或白名单固定返回。fakeip:特殊类型,用来返回“假 IP”(通常在 TUN+fakeip 场景下,客户端收到假 IP 后,后续真正连接会被 sing-box 根据 fake 映射处理)。resolved:一个“已解析”的服务器类型,表示使用已知地址/本地解析结果。- 选择建议:公网上优先 DoH / DoT;在 LAN 或对延迟敏感场景可用 UDP;想隐藏 DNS 指纹或被 DPI 检测时选 DoH/DoT/H3。
DNS 规则(dns.rules)与 Rule Action(能做什么)
- DNS 规则的匹配字段很多(domain、domain_suffix、domain_keyword、domain_regex、rule_set、port、query_type、inbound、source_ip 等),逻辑与 route rule 类似,可以非常细粒度地选择用哪个 DNS server 或做特殊动作。
- 规则的
action(DNS Rule Action)常见值:route(默认):把 DNS 请求发送到指定server(DNS server 的 tag),并可以在 action 内设置strategy、disable_cache、rewrite_ttl、client_subnet等选项;reject:直接拒绝 DNS 查询(可设method: drop|default);predefined:直接用预定义的 DNS 记录响应(用于本地域或黑名单);route-options:仅修改 routing options(如 rewrite_ttl)而不切换 server。
- 常用场景:对国内域名用本地
hosts/直连 DNS;对危险域名用reject;对要走代理的域名把 DNS 指向fakeipserver(query_type 限定为 A/AAAA),配合reverse_mapping实现 domain→fakeIP→路由链路。
Fake-IP(fakeip)工作流程与要点
- 思路:当启用 fakeip,针对特定 DNS 请求(一般在
dns.rules里指定 inbound/tun 或 query_type),sing-box 不返回真实 IP,而是返回一个在保留/私有段内的“假 IP”(例如 198.18.0.0/15),并在内部记录 “fake IP → 原始域名” 的映射(reverse mapping)。随后,当客户端对该假 IP 发起连接时,sing-box 能根据映射把该连接“还原”为对应域名并按域名路由(让流量通过代理)。 - 优点:无需把所有流量都先发到服务端进行域名判断;对 TUN+fakeip 场景非常关键(客户端系统收到假 IP,流量仍走本机,但 sing-box 能识别并转发)。
- 风险/坑:fakeip 依赖“先做 DNS,再发连接”的行为;在某些系统(macOS、某些 Android 代理实现)DNS 被系统级缓存或代理,导致反向映射失败;历史版本存在 fakeip 返回不一致或造成 loop 的已知 bug(需要注意 sing-box 版本与 cache/route 配置)。
- 持久化:可启用 experimental.cache_file 中的
store_fakeip把 fake 映射持久化到磁盘(重启后仍可保留映射),但要注意 cache file 的路径与并发访问策略。
常见陷阱与调试建议(运维角度)
- DNS 循环/Loop:当 DNS 的 detour 指向一个需要 DNS 解析的 outbound(例如
dns.servers[].detour = "proxy",而那个 proxy 的服务器名需要解析),可能产生 DNS query loopback 错误;如果遇到DNS query loopback in transport,排查 server detour / outbound 的域名解析链。 - hijack-dns 行为异常:在使用
hijack-dns(路由层把 DNS 请求交给 sing-box) + fakeip 时,某些版本/场景下只回复首条查询、或后续查询超时,应关注 sing-box 版本(遇到异常先尝试升级或查看 issue)。 - fakeip 不稳定:fake-ip 在不同版本或不同 rule 顺序下可能表现不同(例如部分 rule_set/顺序会影响 fakeip 是否生效),调试时把 fake-ip 相关规则放到 dns.rules 前端并开启 debug 日志。
- 缓存与 TTL:当 DNS 行为不稳定时,先
disable_cache: true或disable_expire: true做排查;生产环境用合理cache_capacity与rewrite_ttl(rewrite_ttl 用于在 rule action 里强制修改返回 TTL,避免短 TTL 导致频繁解析)。 - 系统/平台差异:macOS 的 DNS 层可能导致 reverse_mapping 失效;移动端 GUI 客户端可能对 process/network 判断有限制。
- 调试命令:
sing-box check -c config.json校验语法;启动时加--log-level debug或--log-level trace观察 DNS 交互与路由匹配;使用dig @127.0.0.1 -p <port> example.com或nslookup本地测试。
实用配置示例(可直接拷贝并按需修改)
- 最简:DoH(Cloudflare)+ 本地 hosts + 默认直连
1 | { |
- TUN 环境常见:启用 fakeip,把局域/国内域名直连,其它域名走 fakeip -> proxy;并持久化 fake 映射
1 | { |
- 说明:第一个 rule 把来自 TUN 的 A/AAAA 查询指向
fake-dns,sing-box 返回假 IP;reverse_mapping:true保留 IP→domain 的映射;experimental.cache_file.store_fakeip持久化映射,重启不丢失。
- DNS rule action 示例:单条规则指定 rewrite_ttl 与 client_subnet
1 | { |
- 说明:对
example.com使用 cloudflare DoH,并把返回 TTL 改为 120 秒,同时在查询中附带 EDNS0 client-subnet。
实战建议(给运维/部署参考)
- 总体策略:客户端使用 TUN + fakeip 时,DNS 放在客户端较常见;路由器级集中管理可把 DNS 也置于网关(根据人数与延迟权衡)。
- 安全性:如果在不可信网络(公共 Wi-Fi、运营商 DNS 篡改)下运行,优先 DoH/DoT/H3;并尽量做证书/公钥 pin(如果上游支持)与
insecure: false。 - 性能:适当设置
cache_capacity(例如 4k+)来减少重复解析;对高并发网关可开启independent_cache=false以共享缓存减少内存。 - 持久化 fake 映射:若你的网络依赖 fakeip 做长期 NAT/路由决策,建议启用 experimental.cache_file 的
store_fakeip,并定期备份 cache.db。 - 版本与兼容性:sing-box 的 DNS/fakeip/route 相关功能在不同小版本有修复与行为变化,生产环境请锁定稳定版本并关注 change-log。
内置 DNS 服务器的作用
- Sing-box 内置了一个功能强大的 DNS 服务器。当你在
tun模式下或将系统 DNS 指向 Sing-box 时,它会接管所有的 DNS 查询请求。 - 核心优势: 它不是简单地转发查询,而是可以根据你设定的规则,将不同的域名查询发送到不同的上游 DNS 服务器,并将解析结果缓存起来。这是实现“国内域名用国内 DNS 解析,国外域名用国外 DNS 解析”从而避免污染和抢答的关键。
- Sing-box 内置了一个功能强大的 DNS 服务器。当你在
FakeIP 的工作原理与使用
- 场景痛点: 在传统的透明代理(TUN 模式)中,一个 TCP 连接的流程是:
- App 发起 DNS 查询
google.com-> Sing-box (或系统) 返回真实 IP1.2.3.4。 - App 发起对 IP
1.2.3.4的 TCP 连接。 - Sing-box (TUN) 捕获到这个去往
1.2.3.4的 IP 包,再根据路由规则判断这个 IP 应该走代理还是直连。
这个过程依赖于geoip规则,如果geoip不准,或者一个网站同时使用国内和国外 CDN,分流就容易出错。
- App 发起 DNS 查询
- FakeIP (假 IP) 原理:
- 在
dns配置中启用fakeip。 - 当 App 查询
google.com时,Sing-box 不会去真正查询它的 IP,而是立即返回一个来自特定地址池(如198.18.0.0/16)的假 IP,例如198.18.0.10,并在内部建立一个映射关系:google.com <-> 198.18.0.10。 - App 拿到这个假 IP 后,发起对
198.18.0.10的 TCP 连接。 - Sing-box (TUN) 捕获到这个去往
198.18.0.10的连接,立即反查自己的映射表,得知这个连接的**真实目标是域名google.com**。 - Sing-box 直接使用域名
google.com去匹配路由规则 (route.rules)。
- 在
- 核心优势:
- 分流更精准: 路由规则从“基于 IP 判断”升级为“基于域名判断”,大大提高了
geosite等域名规则的准确性,不再受 DNS 污染影响。 - 响应更快: DNS 查询无需等待上游服务器返回,本地立即响应,降低了连接建立的延迟。
- 分流更精准: 路由规则从“基于 IP 判断”升级为“基于域名判断”,大大提高了
- 配置:
1
2
3
4
5
6
7"dns": {
// ... servers 和 rules 配置 ...
"fakeip": {
"enabled": true,
"inet4_range": "198.18.0.0/16" // 定义假 IP 地址池
}
}
- 场景痛点: 在传统的透明代理(TUN 模式)中,一个 TCP 连接的流程是:
DoH、DoQ、DoH3 等加密 DNS 协议
- 为了防止 DNS 查询在传输过程中被窃听或篡改,我们可以使用加密 DNS 协议。
DoH (DNS over HTTPS): 将 DNS 查询封装在 HTTPS 流量中,抗干扰能力强,使用最广泛。地址格式:https://dns.google/dns-queryDoQ (DNS over QUIC): 使用 QUIC 协议传输,连接建立更快,性能更好。地址格式:quic://dns.adguard-dns.comDoH3 (DNS over HTTP/3): 与 DoQ 类似,也是基于 QUIC。- 在
dns.servers.address中使用对应的格式即可。
DNS 规则动态分流
dns.rules的工作方式与route.rules非常相似,也是自上而下,第一匹配。- 它决定了“哪个域名”的查询,应该交给“哪个
tag的server”去处理。 - 经典用法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16"dns": {
"servers": [
{ "tag": "ali-dns", "address": "udp://223.5.5.5" },
{ "tag": "google-doh", "address": "https://8.8.8.8/dns-query" },
{ "tag": "block-dns", "address": "rcode://refused" } // 特殊地址,拒绝解析
],
"rules": [
// 规则1: 广告域名,直接拒绝解析
{ "geosite": "category-ads-all", "server": "block-dns" },
// 规则2: 国内网站域名,交给阿里DNS解析
{ "geosite": "cn", "server": "ali-dns" },
// 规则3: Netflix域名,必须用国外DNS解析才能拿到正确的IP
{ "geosite": "netflix", "server": "google-doh" }
],
"final": "google-doh" // 其他所有未匹配的域名,都用Google DoH解析
}
实践
配置本地 DNS 并测试是否生效
- 在客户端
config.json中配置一个完整的dns模块,包含rules和fakeip。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17"dns": {
"servers": [
{ "tag": "ali-dns", "address": "223.5.5.5", "detour": "direct-out" },
{ "tag": "cf-doh", "address": "https://1.1.1.1/dns-query", "detour": "direct-out" },
{ "tag": "block-dns", "address": "rcode://refused" }
],
"rules": [
{ "geosite": ["cn", "private"], "server": "ali-dns" },
{ "geosite": "category-ads-all", "server": "block-dns" }
],
"final": "cf-doh",
"strategy": "ipv4_only",
"fakeip": {
"enabled": true,
"inet4_range": "198.18.0.0/16"
}
} - 测试: 启用此配置后,尝试
ping一个广告域名(例如ad.doubleclick.net),应该会无法解析。尝试ping一个国内域名(如baidu.com),会返回一个198.18.x.x的假 IP。
- 在客户端
延伸:结合 AdGuardHome/Pi-hole 做广告拦截
- 如果你家里已经有 AdGuardHome 或 Pi-hole 这样的 DNS 广告过滤服务,你可以让 Sing-box 与它们协同工作。
- 思路: 将 AdGuardHome/Pi-hole 作为 Sing-box 的一个上游
server。1
2
3
4
5
6
7
8
9
10
11
12"servers": [
{
"tag": "adguard-home",
"address": "192.168.1.53", // 你 AdGuardHome 的局域网IP
"detour": "direct-out"
},
// ... 其他DNS服务器 ...
],
"rules": [
// 让所有查询都先经过 AdGuardHome
{ "server": "adguard-home" }
] - 这样,AdGuardHome 先进行广告过滤,然后将它无法处理的请求(如国外域名)转发给它的上游(可以再配置成 Sing-box 的另一个 DNS 入口),形成一个处理链。
Sing-box 中保障通信安全和实现流量伪装的核心——TLS 与加密。正确地配置 TLS 不仅能加密你的数据,防止被窃听,更是伪装流量、对抗主动探测和审查的关键。
