sing-box TUN 模式无法启动:先按报错排查权限、配置与虚拟网卡
简答:先运行与启动时相同版本的 sing-box check,确认不是 JSON 或旧字段错误;检查通过后,再按 Permission denied、Access is denied、interface already exists、端口占用或启动后断网分别处理权限、接口、路由和 DNS。
定义:sing-box TUN 模式是通过创建虚拟网络接口并接管部分系统流量来工作的功能,启动失败通常发生在配置解析、系统权限、虚拟接口冲突或路由设置阶段。
先按报错原文分流:最快定位入口
先保存完整日志和当前配置副本,再按照最接近的报错处理。下面的命令只用于定位,不要把示例中的“配置文件.json”“接口名”和“端口号”原样执行。
| 日志或现象 | 优先检查 | 可执行动作 |
|---|---|---|
unknown field、decode config、JSON 行列错误 | 配置语法、内核版本和旧字段 | 执行 sing-box check -c 配置文件.json,再按迁移说明改字段 |
Permission denied、operation not permitted、open /dev/net/tun | root、管理员权限、TUN 设备和系统授权 | Linux 先用 sudo,Windows 以管理员身份运行,macOS 检查网络扩展授权 |
Access is denied、Initialize TUN device failed、configure tun interface | 权限优先,其次检查虚拟网卡和其他 VPN | 补足权限后重试,再清理残留接口或修改 interface_name |
interface already exists | 同名接口、旧进程、其他 VPN、虚拟机或容器 | 关闭冲突程序,删除确认无用的残留接口,或换一个未占用的接口名 |
address already in use | 监听端口被占用 | 按系统查询 PID,停止冲突进程或修改监听端口 |
| TUN 已创建但网页打不开 | 路由、DNS、回环、strict_route 或 auto_redirect | 恢复最小配置,每次只恢复一个变量 |
官方 TUN 文档列出了 address、auto_route、auto_redirect、strict_route、interface_name 等字段,详见Tun 配置文档。
先执行 check,再用最小 TUN 配置复现
必须使用与实际启动相同的 sing-box 二进制版本。检查通过只代表配置能够解析,不代表系统已有权限创建 TUN,也不代表启动后路由和 DNS 一定可用。
- Windows PowerShell:
.\sing-box.exe check -c .\配置文件.json - macOS 或 Linux:
./sing-box check -c ./配置文件.json
正常标准是没有 FATAL、decode config、unknown field 或 JSON 行列错误。需要格式化时先备份,再使用 sing-box format -w -c 配置文件.json;文件路径替换为实际路径。官方项目说明可参考sing-box 配置文件文档。
如果原配置很复杂,可以先用下面的最小 TUN 入站片段做语法复现。它只适合作为当前文档结构下的排障起点,不能单独提供可用的出站、DNS 或完整路由:
{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"address": ["172.18.0.1/30"],
"auto_route": true,
"strict_route": false
}
]
}如果这份片段能通过 check,而原配置不能通过,优先对比最近新增的 TUN、DNS、规则集和路由字段。若最小配置能解析但启动仍失败,问题更可能在系统权限、接口、端口或其他网络组件。
版本迁移:1.12.0 之后先清理旧字段
官方迁移文档将 TUN 地址字段合并列为 1.10.0 的迁移事项,TUN 页面同时注明旧字段将在 1.12.0 移除。因此运行 1.12.0 或更高版本时,遇到旧字段应直接按 unknown field 处理,而不是继续尝试保留。
| 旧写法或风险 | 当前核对方向 | 判定标准 |
|---|---|---|
inet4_address、inet6_address | 合并到 address | IPv4、IPv6 前缀放入同一个数组 |
inet4_route_address、inet6_route_address | 改为 route_address | 不要同时保留新旧字段 |
inet4_route_exclude_address、inet6_route_exclude_address | 改为 route_exclude_address | 确认排除网段格式正确且没有重复 |
gso | 不要继续依赖旧字段 | 官方文档标注其在 1.11.0 弃用,并在 1.12.0 移除 |
geoip、geosite、source_geoip | 迁移到 rule_set;私有地址规则可核对 ip_is_private | 规则引用的 tag 与 rule-set 定义一致 |
旧版 DNS server 的 address 写法 | 按 1.12.0 迁移为带 type 的 DNS server 对象 | 例如 local 使用 type: local,不要把旧格式和新格式混写 |
截至 2026-10-24,官方 TUN 页面确实列出 dns_mode 和 dns_address 为 1.14.0 字段;如果客户端内核版本无法确认,应以当前内核对应的官方文档为准,不要仅凭订阅生成器或旧教程添加这些字段。完整迁移示例见Migration 官方迁移说明。
权限排查:按系统补足创建 TUN 的条件
Windows
- 完全退出 sing-box 客户端、其他 VPN、虚拟机和网络过滤工具。
- 命令行方式运行时,右键 PowerShell,选择“以管理员身份运行”,再执行 check 和启动命令。
- 打开“设备管理器”→“查看”→“显示隐藏的设备”→“网络适配器”,只卸载能够确认属于旧客户端、且当前不再使用的残留虚拟网卡。
- 重新启动并查看日志。正常标准是 TUN 接口创建成功,不再出现
Access is denied或open tun失败。
如果某个第三方图形客户端单独提示 wintun.dll,应以该客户端的安装说明为准。本文不把它扩展为所有 sing-box 原始程序都必须单独下载 DLL 的结论,避免从不明来源获取动态库。
Linux
- 先检查设备文件:
ls -l /dev/net/tun。能看到设备文件只是基础条件,不能代替权限检查。 - 用 root 做一次对照启动:
sudo ./sing-box run -c ./配置文件.json。命令中的二进制和配置路径替换为实际路径。 - 如果 root 能启动、普通用户不能启动,可给二进制授予能力:
sudo setcap cap_net_admin,cap_net_bind_service+ep ./sing-box。 - 用
getcap ./sing-box验证,正常应能看到对应的cap_net_admin和cap_net_bind_service。 - 若由 systemd 启动,在单元中配置
AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE,并确认服务用户能读取配置、规则集和日志目录。
Linux 使用 auto_route 时,官方文档建议使用 auto_redirect 改善路由并减少与 Docker bridge 的冲突;它依赖 nftables 相关能力。若出现 nftables、nfqueue 或权限错误,先关闭 auto_redirect 验证 TUN 是否能单独创建。
macOS 与移动端
- macOS 命令行直接创建 TUN 时,先用
sudo ./sing-box run -c ./配置文件.json做权限对照;使用图形客户端时,按系统提示允许网络扩展。 - macOS 图形客户端若仍失败,退出其他 VPN、过滤器和网络扩展,再重新启动;出现
address already in use时转到端口排查。 - Android 或 iOS 图形客户端需要先允许系统 VPN 配置。后台运行、省电策略和客户端自身权限菜单会随系统与应用版本变化,核心官方文档无法统一核实,按所用客户端说明处理。
接口冲突、同名接口与端口占用
Initialize TUN device failed 不能只归因于残留网卡:它也可能由权限不足、驱动或系统网络扩展失败引起。因此应先完成上一节的权限对照,再处理接口冲突。
interface already exists
- Linux 先查看接口:
ip link show;确认日志中的接口名后,再执行sudo ip link delete 接口名。只删除确认属于旧客户端的接口,不要删除物理网卡、Docker 或虚拟机正在使用的接口。 - Windows 在设备管理器显示隐藏设备,卸载确认属于旧客户端的虚拟网卡。
- macOS 不要直接删除不确定用途的
utun接口,应先退出占用网络扩展的程序。 - 如果接口不能删除,或它确实由另一个程序使用,可在 TUN 入站中设置不同的
interface_name,例如tun-box。新名称必须符合系统接口命名规则且未被占用。
address already in use
- Windows:
netstat -ano | findstr 端口号,再按 PID 在任务管理器定位进程。 - Linux:
ss -ltnp | grep :端口号。 - macOS:
lsof -nP -iTCP:端口号 -sTCP:LISTEN。
把“端口号”替换为日志中的实际数值。正常标准是该端口没有其他监听进程,或配置已改为一个确认未占用的端口。端口冲突与 TUN 地址冲突是两类问题,不要混用解决方法。
TUN 已启动但无法联网:检查路由和 DNS
如果日志显示接口创建成功,说明问题已经从“启动失败”转为“启动后网络异常”。此时不要继续删除虚拟网卡,先恢复最小配置并逐项加回。
| 字段 | 实际作用 | 怎么判断 |
|---|---|---|
auto_route | 将默认路由指向 TUN | 接口存在,系统路由出现 TUN 相关入口,且没有明显回环 |
route.auto_detect_interface | 自动检测出站接口 | 上游连接能走真实物理网卡,而不是再次进入 TUN |
route.default_interface | 手动指定默认出站接口 | 填写系统中真实存在的接口名,例如有线或无线接口 |
strict_route | 启用更严格的路由规则 | 关闭后虚拟机或特定应用恢复,才说明存在兼容冲突 |
auto_redirect | Linux 使用 nftables 改善 TUN 路由 | 关闭后 TUN 可创建,说明应继续检查 nftables、Docker bridge 或防火墙 |
官方文档说明,strict_route 在 Windows 可减少普通多宿主 DNS 解析导致的泄漏,但某些应用例如 VirtualBox 可能因此无法正常工作。与其他 VPN、虚拟机或多网卡冲突时,可以先关闭验证,再决定是否恢复。
如果只是域名打不开,分别测试 IP 连通性和 DNS 解析;不要同时修改 DNS、MTU、路由和节点。MTU 只有在部分网站打不开、分片异常或大包丢失时才做单变量降低测试,并记录每次结果。
恢复顺序:一次只加回一个变量
- 备份配置、订阅生成文件和完整日志。
- 删除近期新增且无法由当前官方文档确认的 TUN 字段。
- 执行
sing-box check -c 配置文件.json,直到没有解析错误。 - 关闭其他 VPN、虚拟机网络、Docker 网络工具和过滤器,单独测试 TUN 创建。
- 先恢复
auto_route,测试已知 IP 是否可达。 - 再恢复 DNS 设置,测试域名解析。
- Linux 最后恢复
auto_redirect,检查 nftables 与路由表。 - 最后测试
strict_route、自定义路由、rule-set 和 MTU。
每次记录配置版本、操作系统、完整报错、是否管理员或 root、TUN 接口是否出现、IP 是否可达和域名是否可解析。这样可以明确区分配置解析失败、TUN 创建失败、接口冲突、路由冲突与启动后 DNS 异常。
本文与 sing-box 项目及其开发者无隶属关系,未核实的图形客户端菜单、组件打包方式和移动端权限路径,应以所用客户端及系统提示为准。
常见问题
为什么 sing-box check 通过了,TUN 还是无法启动?
check 主要验证配置能否解析,不能代替系统权限、TUN 设备、虚拟接口、端口和路由检查。通过后仍需按日志检查管理员或 root 权限、残留接口、其他 VPN 和防火墙规则。
sing-box 1.12.0 还能使用 inet4_address、inet6_address 和 gso 吗?
不应继续依赖这些旧字段。官方文档将地址字段合并到 address,并标注 gso 在 1.11.0 弃用、1.12.0 移除;遇到 unknown field 时应按当前迁移说明改写。
为什么会出现 interface already exists?
常见原因是旧进程残留接口,或其他 VPN、虚拟机、容器占用了相同接口名。先补足权限并关闭冲突程序,再查看接口;确认无法安全删除时,可以修改 TUN 的 interface_name。
route.auto_detect_interface 和 route.default_interface 有什么区别?
前者是布尔值,用于自动检测出站接口;后者用于手动指定默认出站接口。不要把 true 写给 default_interface,也不要把接口名称写给 auto_detect_interface。
strict_route 要不要关闭?
如果 TUN 能创建但虚拟机、特定应用或多网卡环境无法联网,可以先关闭 strict_route 做单变量验证。若关闭后恢复,说明存在严格路由兼容问题,再根据实际需求决定是否启用。
macOS 命令行运行 TUN 为什么还要测试 sudo?
命令行直接创建 TUN 通常需要系统权限。可以先用 sudo 做一次对照;若 sudo 能运行而普通用户不能,再继续配置权限或改用已完成网络扩展授权的图形客户端。