Sing-box 是一个非常强大、多功能的网络代理平台,被称为新一代代理工具的核心。它自2022年底发布以来,凭借其出色的性能和高度的灵活性,迅速在网络社区中流行起来。

核心功能与优势:

Sing-box 旨在提供一个集大成、高性能的解决方案,其主要优势包括:

  • 多协议支持:它内置了大量主流协议,包括 VLESS、VMess、Trojan、Shadowsocks、Hysteria2 等,几乎能满足所有用户的需求。这使得它成为一个非常灵活的工具,可以适应不同的网络环境。
  • 高性能:Sing-box 使用 Go 语言编写,编译后体积小、运行效率高、内存占用低。这意味着它在任何设备上都能提供流畅稳定的连接。
  • 强大的路由功能:这是 Sing-box 的核心亮点。它允许用户根据域名、IP地址、协议类型等多种条件,对网络流量进行精细化分流。例如,你可以设置让访问国内网站的流量直连,而访问国外网站的流量走代理。
  • 跨平台:Sing-box 的核心可以运行在 Windows、macOS、Linux、Android 和 iOS 等几乎所有主流操作系统上,这让它具有极强的通用性。
1
2
3
4
5
6
7
→  sing-box version
sing-box version 1.12.4

Environment: go1.25.0 linux/amd64
Tags: with_gvisor,with_quic,with_dhcp,with_wireguard,with_utls,with_acme,with_clash_api,with_tailscale
Revision: 980e96250bf693bb8400183d6a05665da8ad9d03
CGO: disabled

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
2
3
4
5
6
7
8
9
10
11
git clone https://github.com/SagerNet/sing-box.git
cd sing-box
# make编译
make
# 生成可执行文件
./build/sing-box

# 也可以用go构建
go build -o sing-box ./cmd/sing-box

go build -trimpath -ldflags "-s -w -buildid=" -o sing-box ./cmd/sing-box

可以将二进制文件复制到系统目录:

1
2
3
4
5
6
7
8
sudo cp sing-box /usr/local/bin/
sing-box version
# 创建配置文件目录及配置
sudo mkdir -p /etc/sing-box
sudo nano /etc/sing-box/config.json

# 运行
sing-box run -c /etc/sing-box/config.json

全功能编译

1
2
3
4
5
6
7
8
# 所有功能全开 + 最佳体积优化
go build -tags "with_quic with_utls with_reality with_clash_api with_grpc with_wireguard with_tun with_gvisor with_dhcp with_ech" \
-trimpath -ldflags "-s -w" -o sing-box ./cmd/sing-box
# 全功能 + 版本信息注入(推荐生产环境)
go build -tags "with_quic with_utls with_reality with_clash_api with_grpc with_wireguard with_tun with_gvisor with_dhcp with_ech" \
-trimpath -ldflags "-s -w -X github.com/sagernet/sing-box/constant.Version=1.12.8 -X github.com/sagernet/sing-box/constant.Commit=$(git rev-parse HEAD)" \
-o sing-box ./cmd/sing-box

跨平台编译:

1
2
3
4
# Linux AMD64:
GOOS=linux GOARCH=amd64 go build ...
# OpenWrt ARM64:
GOOS=linux GOARCH=arm64 go build ...

官方Debian/APT:

1
2
3
4
5
6
7
8
9
10
11
12
13
sudo mkdir -p /etc/apt/keyrings &&
sudo curl -fsSL https://sing-box.app/gpg.key -o /etc/apt/keyrings/sagernet.asc &&
sudo chmod a+r /etc/apt/keyrings/sagernet.asc &&
echo '
Types: deb
URIs: https://deb.sagernet.org/
Suites: *
Components: *
Enabled: yes
Signed-By: /etc/apt/keyrings/sagernet.asc
' | sudo tee /etc/apt/sources.list.d/sagernet.sources &&
sudo apt-get update &&
sudo apt-get install sing-box # or sing-box-beta

手动安装:

1
2
3
4
5
6
# 稳定版发行版
curl -fsSL https://sing-box.app/install.sh | sh
# 最新测试版
curl -fsSL https://sing-box.app/install.sh | sh -s -- --beta
# 或自定义安装版本
curl -fsSL https://sing-box.app/install.sh | sh -s -- --version <version>

为了让 sing-box 在服务器上长期稳定运行(即使关闭 SSH 连接或重启后也能自动启动),需要将其设置为一个系统服务。

systemd (现代 Linux 系统标准)

创建服务文件: sudo nano /etc/systemd/system/sing-box.service

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[Unit]
Description=Sing-box Service
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/sing-box run -c /etc/sing-box/config.json
WorkingDirectory=/etc/sing-box
User=nobody
Restart=on-failure
RestartSec=10
NoNewPrivileges=yes
LimitNOFILE=65536
CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE

[Install]
WantedBy=multi-user.target

然后就可以通过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
  • 参数层级与作用范围

    • 配置是层层嵌套的。例如,inbounds 数组中的每一个元素都是一个独立的对象,这个对象有自己的参数,如 type (协议类型), listen (监听地址), listen_port (监听端口), 以及最重要的 tag
    • tag (标签): 这是配置中最重要的概念之一。tag 是一个你自定义的字符串,用于唯一标识一个入站或出站。路由模块 (route) 就是通过 tag 来引用这些出站的。所有需要被路由引用的入站和出站都必须有一个唯一的 tag

简单来说,就是:inbounds 接收连接 → route 决定走向 → 导向 outbounds 发送。

配置文件结构:

1
2
3
4
5
6
7
8
9
10
11
12
{
"log": {},
"dns": {},
"ntp": {},
"certificate": {},
"endpoints": [],
"inbounds": [],
"outbounds": [],
"route": {},
"services": [],
"experimental": {}
}

写一个最小配置: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 里定义了一个 tagsocks-in 的 SOCKS5 代理,监听在 127.0.0.1:1080
    • outbounds 里定义了一个 tagdirect-out 的直连出站。
    • route.rules 里只有一条规则:所有从 socks-in 进来的流量,全部交给 direct-out 处理。

检查配置文件有没有错误:

1
sing-box check -c /path/to/config.json

创建一个最简单的 sing-box 配置文件 minimal.json。这个配置文件将实现一个基础的代理功能。

minimal.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
{
"log": {
"disabled": false,
"level": "info"
},
"inbounds": [
{
"type": "http",
"tag": "http-in",
"listen": "::",
"listen_port": 1080
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct-out"
}
],
"route": {
"rules": [
{
"outbound": "direct-out"
}
]
}
}

解读:

  • **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: 监听 tcp udp 之一

      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-gcmchacha20-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)一种透明代理模式,通常用在路由器或网关设备上。它需要配合 iptablesnftables 等防火墙工具进行复杂的流量重定向。

vless

除了listen fields,Fields中包括: users(必需)、users.uuid(必需)、users.flowtlsmultiplextransport

  • users(数组,必填)
    • uuid(string,必填):用户唯一 ID,客户端必须一致。可使用sing-box generate uuiduuidgen生成。
    • flow(string,可选):流控模式,XTLS 特有,可用值:xtls-rprx-vision

结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"type": "vless",
"tag": "vless-in",

... // Listen Fields

"users": [
{
"name": "sekai",
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"flow": "xtls-rprx-vision"
}
],
"tls": {},
"multiplex": {},
"transport": {}
}

实践

为了学习和测试基础功能 ,建立一个基础的代理隧道,不考虑高级别的伪装和抗审查,那么使用 IP 地址且不加 TLS 的配置会简单得多。

不使用tls 配置块:在服务端入站和客户端出站中,都不再需要 tls 对象。

不指定transport 配置块:当不指定 transport 时,Sing-box 默认使用原生 TCP 进行数据传输。这是最简单、最直接的方式。

使用 IP 地址:在客户端出站的 server 字段中,直接填写服务端的 IP 地址。

更改端口:由于不使用 TLS,我们不再需要占用 443 端口。可以选择一个不常用的高位端口(例如 10000-65535 之间),以避免端口冲突。

服务端:

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
{
"log": {
"level": "info"
},
"inbounds": [
{
"type": "vless",
"tag": "vless-in",
"listen": "0.0.0.0",
"listen_port": 23456, // 使用一个非标准端口
"users": [
{
"uuid": "你的UUID" // 请使用 `sing-box generate uuid` 命令生成一个新的
}
]
// 这里没有 transport 和 tls 配置,默认为原生TCP传输
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"rules": [
{
"inbound": "vless-in",
"outbound": "direct"
}
]
}
}

客户端:

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
{
"log": {
"level": "info"
},
"inbounds": [
{
"type": "socks",
"tag": "socks-in",
"listen": "127.0.0.1",
"listen_port": 1080
}
],
"outbounds": [
{
"type": "vless",
"tag": "vless-out",
"server": "你的VPS_IP地址", // 直接填写服务器的IP
"server_port": 23456, // 必须与服务端 listen_port 一致
"uuid": "你的UUID" // 必须与服务端 users -> uuid 一致
// 这里同样没有 transport 和 tls 配置
}
],
"route": {
"rules": [
{
"inbound": "socks-in",
"outbound": "vless-out"
}
]
}
}

注意:

  • 安全性: 这种连接是未加密的。虽然 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 的虚拟网卡,并自动修改系统路由表,将大部分网络流量导向这个网卡,从而实现全局代理。

延伸:理解 VLESS 与 VMess 在加密、性能和抗审查上的差异

  • 加密:
    • VMess: 内置了一层独立的加密,流量特征相对明显。时间验证严格,客户端与服务端时间相差不能过大。
    • VLESS: 协议本身不包含加密。它是一个轻量化的传输协议,完全依赖于外层的 TLS (或其他加密传输) 来保证数据安全。这使得它的流量特征与标准 HTTPS 流量几乎无法区分。
  • 性能:
    • 由于 VLESS 移除了不必要的加密层,减少了数据包的处理开销,其性能通常优于 VMess。在相同的硬件和网络环境下,VLESS 能达到更高的吞吐量和更低的延迟。
  • 抗审查:
    • 两者都可以通过伪装(如 WebSocket、gRPC)和 TLS 来抗审查。但 VLESS 的设计哲学使其更“纯粹”地依赖于 TLS,伪装效果更好。特别是配合 XTLS Vision 这样的“流控”(flow)技术时,可以进一步减少 TLS 加密/解密的次数,提升性能并降低被探测的风险。**因此,对于抗审查和性能,VLESS 是当前的首选方案。

出站协议 (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 使用 uuidalterId 等)。
      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) 发送请求,自动选择延迟最低的出站作为出口。这是实现“永远用最快的节点”的自动化策略。
      • 应用场景: 你有多个性质相同的节点,不关心具体是哪个,只要保证当前用的是最快的就行。

实践

  1. 配置多个 outbounds,并用路由规则区分流量

    • 这个实践的核心在于定义好“零件”,为下一节的“路由系统”做准备。
    • 在你的客户端 config.jsonoutbounds 数组中,配置如下结构:
      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
  2. 设置 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-usproxy-jp 中选择当前延迟最低的一个来发送流量。这极大地提升了网络的稳定性和速度。

vless

Inbound(服务端)里的 vlessusers 数组,uuidusers 里;但 outbound(客户端/上游)里的 vless 则把 uuid 放在顶层字段 uuid 这点常被混淆,导致 "json: unknown field \"encryption\"" 之类的报错或 unknown field "users" 的错误。

结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
"type": "vless",
"tag": "vless-out",

"server": "127.0.0.1",
"server_port": 1080,
"uuid": "bf000d23-0752-40b4-affe-68f7707a9661",
"flow": "xtls-rprx-vision",
"network": "tcp",
"tls": {},
"packet_encoding": "",
"multiplex": {},
"transport": {},

... // Dial Fields
}

字段:

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_sha256utlsechreality 等高级字段可做证书 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"
    • wspathheadersmax_early_dataearly_data_header_name 等(path 必须和服务端一致,early_data_header_name 用于与 Xray 兼容)。
    • httphostpathheaders 等。
  • 如果你要用 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_cidrsource_portsource_ip_is_private:当 sing-box 被用作网关 / TUN 时,可区分“哪个客户端发来的请求”。例如:只让局域网内某台机器走特定 outbound。
  • 进程 / 应用(只在桌面/支持平台生效)
    • process_name / process_path / process_path_regex:把某个进程(比如 curlsteam.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:把流量送到指定 outboundoutbound 字段填写目标 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
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
"route": {
"rules": [
{
"action": "sniff",
"timeout": "300ms"
},
{
"type": "logical",
"mode": "or",
"rules": [
{ "inbound": "dns-in" },
{ "port": 53 },
{ "protocol": "dns" }
],
"action": "hijack-dns"
},
{
"ip_is_private": true,
"outbound": "direct"
},
{
"port": 853,
"network": "tcp",
"action": "reject",
"method": "default"
},
{
"domain_suffix": [ ".example.cn", ".intranet.local" ],
"outbound": "direct"
},
{
"domain_suffix": [ ".youtube.com", ".googlevideo.com" ],
"outbound": "proxy"
},
{
"type": "logical",
"mode": "and",
"rules": [
{ "process_name": [ "backupd" ] },
{ "network": "tcp" }
],
"outbound": "direct"
}
],
"final": "proxy",
"auto_detect_interface": true
}

常见坑、调试建议与最佳实践

  • 顺序重要:把精确/危险的规则放前面,通用/catch-all 的放后面。
  • 不要盲用 geosite / geoip:建议迁移到 rule-set 或其它方案。
  • 域名与 IP 的匹配差异:IP 规则对域名请求未必生效,需启用 reverse mapping / DNS hijack / explicit resolving。
  • TUN 环境注意回环:开启 auto_detect_interface / 设置 default_interfaceoutbound.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"
      }
  • 按域名、IP、端口、协议分流 (常见的匹配条件)

    • domain, domain_suffix, domain_keyword, domain_regex: 按域名匹配。
      • "domain_suffix": [".cn", "aliyuncs.com"] 是最高效、最常用的方式,匹配所有以 .cnaliyuncs.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.dbgeosite.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. 实现 “国内流量直连,国际流量走代理” 并屏蔽广告

    • 这是一个非常实用和通用的路由配置。注意规则的顺序至关重要。
      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"
      }
      ]
      }
  2. 实现 “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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
"dns": {
"servers": [],
"rules": [],
"final": "",
"strategy": "",
"disable_cache": false,
"disable_expire": false,
"independent_cache": false,
"cache_capacity": 0,
"reverse_mapping": false,
"client_subnet": "",
"fakeip": {}
}
}
  • 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.serversdns.rulesdns.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_ipv4prefer_ipv6ipv4_onlyipv6_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 内设置 strategydisable_cacherewrite_ttlclient_subnet 等选项;
    • reject:直接拒绝 DNS 查询(可设 method: drop|default);
    • predefined:直接用预定义的 DNS 记录响应(用于本地域或黑名单);
    • route-options:仅修改 routing options(如 rewrite_ttl)而不切换 server。
  • 常用场景:对国内域名用本地 hosts/直连 DNS;对危险域名用 reject;对要走代理的域名把 DNS 指向 fakeip server(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: truedisable_expire: true 做排查;生产环境用合理 cache_capacityrewrite_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.comnslookup 本地测试。

实用配置示例(可直接拷贝并按需修改)

  1. 最简:DoH(Cloudflare)+ 本地 hosts + 默认直连
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
{
"dns": {
"servers": [
{
"type": "hosts",
"tag": "local-hosts",
"address": "hosts"
},
{
"type": "https",
"tag": "cloudflare-doh",
"server": "cloudflare-dns.com",
"server_port": 443,
"path": "/dns-query",
"tls": {
"enabled": true,
"server_name": "cloudflare-dns.com"
}
}
],
"final": "cloudflare-doh",
"strategy": "prefer_ipv4",
"cache_capacity": 4096
}
}
  1. TUN 环境常见:启用 fakeip,把局域/国内域名直连,其它域名走 fakeip -> proxy;并持久化 fake 映射
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
{
"dns": {
"servers": [
{ "type": "local", "tag": "local" },
{ "type": "fakeip", "tag": "fake-dns" },
{ "type": "https", "tag": "cloudflare", "server": "cloudflare-dns.com", "server_port": 443 }
],
"rules": [
{
"inbound": "tun-in",
"query_type": ["A","AAAA"],
"server": "fake-dns",
"disable_cache": true
},
{
"domain_suffix": [".cn", ".local"],
"server": "local",
"rewrite_ttl": 600
},
{
"outbound": ["any"],
"server": "cloudflare"
}
],
"fakeip": {
"enabled": true,
"inet4_range": "198.18.0.0/15",
"inet6_range": "fc00::/18"
},
"reverse_mapping": true,
"strategy": "prefer_ipv4"
},
"experimental": {
"cache_file": {
"enabled": true,
"path": "cache.db",
"store_fakeip": true
}
}
}
  • 说明:第一个 rule 把来自 TUN 的 A/AAAA 查询指向 fake-dns,sing-box 返回假 IP;reverse_mapping:true 保留 IP→domain 的映射;experimental.cache_file.store_fakeip 持久化映射,重启不丢失。
  1. DNS rule action 示例:单条规则指定 rewrite_ttl 与 client_subnet
1
2
3
4
5
6
7
{
"domain": ["example.com"],
"action": "route",
"server": "cloudflare",
"rewrite_ttl": 120,
"client_subnet": "203.0.113.0/24"
}
  • 说明:对 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 解析”从而避免污染和抢答的关键。
  • FakeIP 的工作原理与使用

    • 场景痛点: 在传统的透明代理(TUN 模式)中,一个 TCP 连接的流程是:
      1. App 发起 DNS 查询 google.com -> Sing-box (或系统) 返回真实 IP 1.2.3.4
      2. App 发起对 IP 1.2.3.4 的 TCP 连接。
      3. Sing-box (TUN) 捕获到这个去往 1.2.3.4 的 IP 包,再根据路由规则判断这个 IP 应该走代理还是直连。
        这个过程依赖于 geoip 规则,如果 geoip 不准,或者一个网站同时使用国内和国外 CDN,分流就容易出错。
    • FakeIP (假 IP) 原理:
      1. dns 配置中启用 fakeip
      2. 当 App 查询 google.com 时,Sing-box 不会去真正查询它的 IP,而是立即返回一个来自特定地址池(如 198.18.0.0/16)的假 IP,例如 198.18.0.10,并在内部建立一个映射关系:google.com <-> 198.18.0.10
      3. App 拿到这个假 IP 后,发起对 198.18.0.10 的 TCP 连接。
      4. Sing-box (TUN) 捕获到这个去往 198.18.0.10 的连接,立即反查自己的映射表,得知这个连接的**真实目标是域名 google.com**。
      5. Sing-box 直接使用域名 google.com 去匹配路由规则 (route.rules)。
    • 核心优势:
      • 分流更精准: 路由规则从“基于 IP 判断”升级为“基于域名判断”,大大提高了 geosite 等域名规则的准确性,不再受 DNS 污染影响。
      • 响应更快: DNS 查询无需等待上游服务器返回,本地立即响应,降低了连接建立的延迟。
    • 配置:
      1
      2
      3
      4
      5
      6
      7
      "dns": {
      // ... servers 和 rules 配置 ...
      "fakeip": {
      "enabled": true,
      "inet4_range": "198.18.0.0/16" // 定义假 IP 地址池
      }
      }
  • DoH、DoQ、DoH3 等加密 DNS 协议

    • 为了防止 DNS 查询在传输过程中被窃听或篡改,我们可以使用加密 DNS 协议。
    • DoH (DNS over HTTPS): 将 DNS 查询封装在 HTTPS 流量中,抗干扰能力强,使用最广泛。地址格式:https://dns.google/dns-query
    • DoQ (DNS over QUIC): 使用 QUIC 协议传输,连接建立更快,性能更好。地址格式:quic://dns.adguard-dns.com
    • DoH3 (DNS over HTTP/3): 与 DoQ 类似,也是基于 QUIC。
    • dns.servers.address 中使用对应的格式即可。
  • DNS 规则动态分流

    • dns.rules 的工作方式与 route.rules 非常相似,也是自上而下,第一匹配
    • 它决定了“哪个域名”的查询,应该交给“哪个 tagserver”去处理。
    • 经典用法:
      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解析
      }

实践

  1. 配置本地 DNS 并测试是否生效

    • 在客户端 config.json 中配置一个完整的 dns 模块,包含 rulesfakeip
      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。
  2. 延伸:结合 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 不仅能加密你的数据,防止被窃听,更是伪装流量、对抗主动探测和审查的关键。

TLS 与加密