sing-box 配置教程:订阅导入、JSON 校验与 TUN 排错
简答:sing-box 配置应先确认内容是否为完整 JSON,再按客户端导入远程或本地配置;启动失败用 sing-box check 定位字段和格式,TUN 无网络则依次检查权限、路由、DNS、端口与连接日志。
定义:sing-box 是一个使用 JSON 描述入站、DNS、出站和路由规则的网络连接内核,图形客户端负责编辑、启动配置并申请系统权限。
先看结论:导入失败,先检查格式而不是改后缀
导入失败最常见的原因是手里的内容与客户端要求的格式不一致。完整 sing-box 配置通常是 JSON;Clash 配置通常是 YAML;Base64 只是编码后的文本;单节点链接只描述一个节点,都不能仅靠改成 .json 变成完整 sing-box 配置。
| 手里的内容 | 典型特征 | 正确处理 |
|---|---|---|
| 完整 sing-box JSON | 能看到 inbounds、outbounds、route 等键 | 作为 Local Profile 导入,或作为 Remote Profile 的返回内容 |
| Clash YAML | 常见顶层键为 proxies、proxy-groups、rules | 不能直接当作 sing-box JSON,优先向配置提供方索取原生 JSON |
| Base64 订阅 | 打开后是一长串编码字符,解码后可能是多条节点链接 | 先确认客户端是否支持该格式;不支持时不要直接粘贴到 JSON 配置框 |
| 单节点链接 | 通常以某种协议名称开头,只描述一个节点 | 使用客户端支持的节点导入入口,不能替代完整配置 |
| HTML 或登录页 | 返回网页、错误页、验证码或空白内容 | 检查 URL、登录状态和服务端返回内容 |
远程配置的关键不是 URL 后缀,而是地址返回的内容是否为客户端可读取的配置。官方通用客户端文档将配置分为 Local Profile、iCloud Profile 和 Remote Profile,具体入口以所用平台版本界面为准,参见sing-box Profile 文档。
sing-box、内核、客户端和配置文件是什么关系
可以把 sing-box 配置理解为三层:内核负责读取 JSON、建立入站和出站连接、执行 DNS 与路由;图形客户端负责配置管理、启动服务和申请系统权限;配置文件则描述本机从哪里接收流量、如何解析 DNS、通过哪个出站连接以及规则如何匹配。
官方配置总览包含 log、dns、inbounds、outbounds、route 和 experimental 等部分。配置不是把几个节点链接堆在一起,而是需要同时定义本地入口、出站、路由和必要的 DNS 行为,详见sing-box 配置总览。
官方图形客户端页面列出的平台包括 Android、iOS、macOS、Windows 和 Linux:Android 对应 Android 客户端,iOS、macOS 和 Apple tvOS 对应 Apple 平台客户端,Windows 和 Linux 对应 Desktop 客户端。其他声称使用 sing-box 的项目不一定由项目维护者维护,下载前应核对发布渠道,参见官方图形客户端列表。
截至2026-10-24,Releases 标记为 Latest 的是 1.14.3;1.15.0 仍处于 alpha 预发布阶段,具体构建号以官方 Releases 页面为准。本文示例按 1.14.x 稳定版通用字段组织,遇到字段报错时应优先对照当前版本文档。
版本—字段变化对照:升级后报错先看这里
| 版本节点 | 变化重点 | 排查含义 |
|---|---|---|
| 1.11.0 | 旧的特殊出站逐步迁移到 Route Rule Action | 新写拦截规则时优先使用 action: reject,不要照搬旧的 outbound: block 写法 |
| 1.12.0 | DNS server 格式重构,新增格式迁移要求 | 旧 DNS 配置升级后要对照新 DNS server 文档,不能只改顶层名称 |
| 1.14.0 | TUN 增加 dns_mode、dns_address 等字段 | 这些字段属于 1.14.0 起的 TUN 配置,低版本不要直接复制 |
| 当前预发布线 | 1.15.0 alpha 仍在迭代 | 不要把预发布文档中的字段直接复制到稳定版配置 |
上表依据官方Migration 文档、Change Log和 TUN 字段说明整理。需要注意的是,官方 Change Log 曾说明 block 出站在某个版本中暂时取消弃用,因此这里的建议不是“所有旧配置立即失效”,而是新写拦截规则时优先采用当前 Rule Action 语法,并用当前版本二进制校验。
第一步:按平台选择客户端和配置入口
| 平台 | 优先入口 | 需要注意 |
|---|---|---|
| Windows | 官方 Desktop 客户端或命令行内核 | 系统代理与 TUN 是不同层级;TUN、服务或网络权限按钮名称以所用版本界面为准 |
| macOS | 官方 Apple 平台客户端 | 系统扩展或网络权限被拦截时,按“隐私与安全性”中的系统提示放行;不要为未知文件关闭整体安全机制 |
| Linux | 官方 Desktop 客户端或命令行内核 | systemd 服务要检查专用用户、配置文件、证书和运行目录权限 |
| Android | 官方 Android 客户端 | 系统流量接管依赖 Android VPN 授权;不要假设所有 Base64 或单节点入口都存在 |
| iOS | 官方 Apple 平台客户端 | 通过系统 VPN 授权和 Profile 管理,不能照搬 Linux 的 root、systemd 或命令行步骤 |
官方平台范围和客户端名称以Graphical Clients 页面为准。第三方图形界面的按钮名称、订阅转换能力和权限模型可能不同,因此正文只使用官方文档能确认的通用操作。
第二步:导入远程订阅或本地 JSON
导入远程配置
- 复制配置提供方明确标注为 sing-box JSON 的 URL。
- 在客户端新增 Remote Profile,输入名称并粘贴 URL。
- 执行更新,查看返回内容是否为合法 JSON,而不是 HTML、Clash YAML、Base64 或单节点文本。
- 确认配置中存在可用的
outbounds,再选择 Profile 启动。
如果配置提供方只给出 Clash YAML、Base64 或单节点链接,先询问是否有原生 sing-box JSON。官方客户端页面能够确认 Profile 管理方式,但不能据此推断每个平台都支持任意订阅格式;格式不在官方入口范围内时,不要在客户端里盲目寻找不存在的导入按钮。
导入本地配置
- 把配置保存为
config-<版本号>.json,不要把订阅 URL、UUID、密码、私钥和访问令牌发到公开平台。 - 选择 Local Profile 或本地文件导入。
- 先运行校验,再启动服务;第一次排查时不要同时修改 DNS、TUN、路由和节点参数。
- 远程配置需要更新时,先备份原内容;远程更新可能覆盖本地手工修改。
订阅 URL 通常包含访问凭据。若必须转换格式,应先确认转换服务的保存、日志和删除规则;能从配置提供方获得原生 sing-box JSON 时,优先使用原生格式。
第三步:用最小 JSON 验证本地入口是否正常
下面示例适用于 sing-box 1.14.x 稳定版,只验证本地 Mixed 入站和直连出站。它没有远程节点,因此不能证明节点、认证、TLS 或远端网络可用;示例也不放置已弃用迁移路径中的 block 出站。
{
"$schema": "https://sing-box.sagernet.org/schema.json",
"log": {
"level": "info",
"timestamp": true
},
"dns": {
"servers": [
{
"type": "local",
"tag": "local"
}
],
"final": "local"
},
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "127.0.0.1",
"listen_port": 7890
}
],
"outbounds": [
{
"type": "direct",
"tag": "direct"
}
],
"route": {
"final": "direct",
"auto_detect_interface": true
}
}mixed 入站提供本地 HTTP 和 SOCKS 入口;direct 表示直连;route.final 是没有被其他规则匹配时使用的最终出站。端口不是 sing-box 内核固定的默认值,而是由配置中的 listen_port 决定。本例手动填写了 7890,实际使用时以配置和客户端设置页为准。
若需要拒绝匹配到的流量,应使用 Route Rule Action,例如:
{
"route": {
"rules": [
{
"domain_suffix": [
"example.invalid"
],
"action": "reject"
}
],
"final": "direct"
}
}新旧特殊出站的迁移关系见官方Migration 文档,Rule Action 的字段定义见Route Rule Action 文档。
第四步:校验、格式化、启动和检查端口
命令中的 <版本号> 是文件名占位符,不要原样输入。先校验,再格式化,最后启动:
sing-box check -c config-<版本号>.json
sing-box format -w -c config-<版本号>.json
sing-box run -c config-<版本号>.jsoncheck 通过只表示当前二进制能够读取配置,不代表节点可达、认证正确、DNS 正常或系统权限充足。格式化前建议复制一份原始文件,因为 format -w 会直接写回配置。命令和配置结构以官方配置文档为准。
Linux 使用 systemd 时,可以查看服务状态和日志:
sudo systemctl status sing-box
sudo journalctl -u sing-box --output cat -e
sudo journalctl -u sing-box --output cat -f排查端口占用时,Linux 使用带 sudo 的 ss;macOS 使用 lsof:
sudo ss -lntup | grep 7890sudo lsof -nP -iTCP:7890 -sTCP:LISTEN如果系统没有 ss 或其他非系统自带工具,先按发行版包管理器安装。端口冲突时,改动配置中的 listen_port,并同步修改系统代理或客户端入口。
TUN、系统代理、DNS 和路由分别解决什么问题
| 功能 | 主要作用 | 排查重点 |
|---|---|---|
| Mixed 入站 | 提供本地 HTTP 和 SOCKS 代理入口 | 应用是否支持代理,端口是否监听 |
| 系统代理 | 让遵循系统代理的应用使用本地入口 | 应用是否遵循系统代理,地址和端口是否一致 |
| TUN | 通过虚拟网卡接管更多系统流量 | 系统权限、自动路由、回环、DNS 和 IPv6 |
| DNS | 决定域名由哪个 DNS server 解析 | DNS 请求是否进入 sing-box,服务器是否可达 |
| Route | 决定流量匹配后使用哪个出站或动作 | 规则顺序、最终出站和日志命中情况 |
Mixed、TUN 和 DNS 是不同层级,不能因为 TUN 已启动就认为应用一定走了代理。验证时应查看连接日志中命中的出站或策略,也可以对比开启前后的出口 IP。先用 Mixed 验证节点,再单独开启 TUN,通常比一开始同时改动多层设置更容易定位问题。
TUN 示例:只保留一种 DNS 劫持思路,避免无条件规则
在 sing-box 1.14.x 中,TUN 的 dns_mode 和 dns_address 属于 1.14.0 起提供的字段。dns_mode: hijack 会让 TUN 按文档定义处理平台 DNS,并带有 DNS 劫持行为;如果同时再写一个无条件的 hijack-dns 路由规则,读者很难判断究竟是哪一层在处理 DNS。因此,入门排查时建议先使用 TUN 的 dns_mode,不要额外复制无条件 DNS 劫持规则。
{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"address": [
"172.18.0.1/30",
"fdfe:dcba:9876::1/126"
],
"mtu": 9000,
"dns_mode": "hijack",
"dns_address": [
"172.18.0.2",
"fdfe:dcba:9876::2"
],
"auto_route": true
}
],
"route": {
"final": "direct",
"auto_detect_interface": true
}
}这个片段不能单独运行,还需要完整的 dns、outbounds 和其他顶层配置。interface_name 已省略,表示由系统自动选择;官方 TUN 文档说明该字段为空时会自动选择虚拟设备名称,因此不要把 tun0 当成 Windows、macOS 和 Linux 都相同的固定名称。
若你需要手动写 Route Rule Action,应让规则有明确匹配条件,例如先识别协议,再仅匹配 DNS:
{
"route": {
"rules": [
{
"action": "sniff"
},
{
"protocol": "dns",
"action": "hijack-dns"
}
],
"final": "direct",
"auto_detect_interface": true
}
}两种写法不要在没有理解版本行为的情况下叠加。遇到字段校验失败或 TUN 无网络,应先回到当前版本的TUN 文档,确认字段和默认行为,再逐项恢复配置。
症状速查:先查什么、用什么命令
| 症状 | 首查项目 | 动作或命令 |
|---|---|---|
| 解析失败 | JSON 逗号、引号、括号和字段类型 | sing-box check -c config-<版本号>.json,按行号修正 |
| 端口绑定失败 | 是否被其他程序占用 | Linux 用 sudo ss -lntup;macOS 用 sudo lsof |
| TUN 无网络 | 权限、DNS、自动路由和回环 | 先关闭 TUN,仅用 Mixed 验证;再查看日志和路由 |
| 远程配置为空 | URL 返回格式 | 确认不是 HTML、登录页、YAML、Base64 或单节点文本 |
| 校验通过但节点失败 | 地址、端口、认证和 TLS 参数 | 查看连接日志,不要把节点问题误判为 JSON 问题 |
| 启动后仍直连 | 系统代理、TUN 和 route.final | 确认日志命中的出站,并对比出口 IP |
- 导入失败:先保存 URL 返回内容,确认首字符不是 HTML 或错误页。
- JSON 失败:删除 Markdown 代码围栏和注释,再运行
check。 - 启动失败:先查端口,再查 TUN 权限、配置文件权限和日志。
- TUN 无网络:先关闭 TUN,只保留 Mixed;如果 Mixed 正常而 TUN 异常,重点检查自动路由、DNS 和 IPv6。
- DNS 失败:确认请求是否进入 sing-box DNS 模块,避免先盲目替换多个字段。
- 验证代理:查看日志中的出站或策略命中情况,并对比开启前后的出口 IP。
平台权限与配置安全检查
- Windows:系统代理和 TUN 不是同一功能;普通应用能使用系统代理,不代表所有 UDP 或后台服务都会被接管。
- macOS:系统扩展被拦截时,只按“隐私与安全性”的系统提示放行;下载来源和发布者无法确认时不要强行运行。
- Linux:systemd 专用用户需要读取配置、证书和相关运行目录;TUN 或自动路由还可能需要额外权限。
- Android:开启系统 VPN 前,检查是否已有其他 VPN;同时留意电池优化造成的后台中断。
- iOS:使用系统 VPN 授权和客户端 Profile,不要套用 Linux 的 root、systemd 或命令行步骤。
- 下载校验:如果发布页提供校验值,校验对象应是下载的原始压缩包或安装资产,不是解压后的配置文件;没有提供校验值时不要自行编造。
- 订阅脱敏:分享日志、截图或配置前,删除订阅 URL、UUID、密码、私钥和访问令牌。
- 远程更新:远程 Profile 更新后可能覆盖本地改动,长期维护前先复制一份脱敏本地备份。
配置修改建议遵循“只改一个变量、保留原文件、先校验再启动”的顺序。这样即使出现无网络,也能判断问题来自格式、字段、权限、DNS、路由还是节点本身。
常见问题
sing-box 能直接导入 Clash YAML 吗?
不能把 Clash YAML 直接当作 sing-box JSON。两者字段体系不同,应获取完整 sing-box JSON,或完成可信转换后再用当前版本的 sing-box check 校验。
为什么 JSON 校验通过,启动后还是无法联网?
check 只说明当前二进制能够读取配置,不代表节点可达、认证正确、DNS 正常或系统权限充足。继续看端口监听、启动日志、DNS 请求、规则命中和实际出口 IP。
TUN 和系统代理需要同时开启吗?
不需要在排查初期同时开启。先用 Mixed 或系统代理验证本地入口、节点和 DNS,再单独开启 TUN,可以减少多个入口同时变化造成的干扰。
为什么远程订阅导入后没有节点?
先确认 URL 返回的是完整 sing-box JSON,而不是 HTML、Clash YAML、Base64 或单节点链接;再检查客户端更新是否成功,以及配置中的 outbounds 是否存在可用出站。
sing-box 配置中的端口应该填多少?
端口由配置中的 listen_port 决定,示例中的 7890 只是手动填写的示例值,并非 sing-box 内核固定默认值。以配置文件和客户端设置页为准。
为什么升级后配置字段报错?
字段会随内核版本新增、迁移、弃用或改变默认行为。先确认当前二进制版本,再对照对应版本的官方 Migration、Change Log 和配置文档,不要混用 alpha 文档或其他内核字段。
常见问题
sing-box 能直接导入 Clash YAML 吗?
不能直接导入。应获取完整 sing-box JSON,或完成转换后使用当前版本的 sing-box check 校验。
为什么 JSON 校验通过,启动后还是无法联网?
校验通过不等于节点可达、认证正确或权限充足。继续检查端口、TUN 权限、DNS、路由、日志和实际出口 IP。
TUN 和系统代理需要同时开启吗?
排查初期不需要同时开启。先用 Mixed 或系统代理验证节点和 DNS,再单独开启 TUN。
为什么远程订阅导入后没有节点?
确认 URL 返回完整 sing-box JSON,而不是 HTML、YAML、Base64 或单节点链接,并检查 outbounds 是否存在可用出站。
sing-box 配置中的端口应该填多少?
端口由 listen_port 决定,7890 只是示例值,不是内核固定默认值;实际以配置文件和客户端设置页为准。
为什么升级后配置字段报错?
先确认当前二进制版本,再对照对应版本的 Migration、Change Log 和配置文档,不要混用预发布文档或其他内核字段。