← 返回 STC-SPADES Review & Setup Guide for New Users 首页

sing-box bypass 路由问题怎么排查?先分清 direct 与内核绕过

更新于 2026-10-20 · stc-spadesdns.cyou

简答:先判断你要的是普通直连,还是 Linux TUN 场景的内核绕过:多数 Windows、macOS、Android VPNService 用户应使用 action: route + outbound: direct;只有 Linux 且启用 auto_route、auto_redirect 时,才继续排查未指定 outbound 的 action: bypass。若出现断网、回环或超时,先恢复 direct,再检查 debug 日志、nftables、nfqueue、ip rule 和实际路由表。

定义:sing-box 的 bypass 是一种路由规则动作:在满足 Linux 与 auto_redirect 条件的预匹配场景中,让连接在内核层绕过 sing-box,而不是适用于所有平台的直连开关。

30 秒速查:先判断能不能用 bypass

先按下面四种情况定位,不要一开始就修改固定 mark 或清空系统路由。

sing-box bypass 路由问题速查卡
你的环境或现象先用什么下一步
Windows、macOS 或普通 Android VPNServiceaction: route + outbound: direct检查规则顺序、出站标签、DNS 解析和已建立连接。
Linux,但版本低于 1.13.0route + direct先升级或暂时不要使用未指定 outbound 的 bypass。
Linux 1.13.0 及以上,且有 auto_route、auto_redirect可以测试未指定 outbound 的 action: bypass检查 nfqueue、nftables、预匹配和路由表。
IPv4 正常、IPv6 单独超时先查 ip -6 rule 和 table 2022确认标记实际查到的 IPv6 默认路由没有回到 TUN。

官方规则动作文档说明,bypass 自 sing-box 1.13.0 起提供,仅支持 Linux,并且需要启用 auto_redirect;未指定 outbound 时,只会在 auto_redirect 预匹配中生效,其他场景会跳过。参见sing-box 规则动作文档。

最安全的第一步:把原来的 bypass 临时改成普通 route,并指定已有的 direct 出站。这样可以先区分“基础连接或 DNS 有问题”和“内核绕过条件不满足”。

{
  "route": {
    "rules": [
      {
        "domain_suffix": [
          "intranet.example"
        ],
        "action": "route",
        "outbound": "direct"
      }
    ],
    "final": "proxy",
    "auto_detect_interface": true
  }
}

intranet.example、direct 和 proxy 都是占位值,必须替换为你配置中实际存在的域名和出站标签。这里的 final: proxy 只表示未匹配流量继续交给原来的代理出站,不是完整配置。修改前请备份;如果配置来自订阅,直接改原文件可能在更新时被覆盖,应使用客户端提供的合并或覆盖方式。

action:bypass、direct 与 route_exclude_address 怎么区分

三类绕过写法的区别
写法作用适用边界常见误区
action: route + outbound: direct把匹配连接交给 direct 出站处理。适合多数 TUN、桌面系统和 Android VPNService 场景。把 direct 误认为内核层绕过,或忘记检查 direct 标签是否存在。
action: bypass,不指定 outbound在 Linux auto_redirect 预匹配中,让连接在内核层绕过 sing-box。需要 Linux、sing-box 1.13.0 及以上、auto_route 和 auto_redirect。在 Windows、macOS 或普通 Android VPNService 中照抄。
action: bypass,指定 outbound在非 auto_redirect 或已建立连接中,行为与指定 outbound 的 route 相同。不要把它理解为所有平台的内核绕过。以为写了 bypass 就一定绕过 TUN。
route_exclude_address从 TUN 自动路由中排除指定地址或 CIDR。配合 auto_route 使用;适合少量明确网段。把它当作按域名选择 direct 出站。
route_exclude_address_set按规则集中的 IP CIDR 排除 TUN 路由。官方要求 Linux、auto_route 和 auto_redirect;Android 图形客户端不适合大量此类路由。忽略规则集加载、内核路由和 auto_redirect 条件。

官方 TUN 文档还说明,auto_redirect 仅支持 Linux 且要求先启用 auto_route;预匹配需要内核支持 nfnetlink_queue,OpenWrt 下会自动向 fw4 插入兼容规则。该文档也列出了 iproute2_table_index 默认值 2022、Linux 默认输入标记 0x2023 和输出标记 0x2024,但 Android 默认标记不同,配置也可能被自定义。参见sing-box Tun 文档。

按平台处理:Linux、OpenWrt、Windows、macOS 和 Android

不同平台的 bypass 处理方式
平台推荐做法检查重点
Linux 主机先用 route + direct 验证,再测试 bypass。sing-box 版本、auto_route、auto_redirect、nfqueue、nftables、ip rule 和路由表。
OpenWrt 旁路网关先确认 LAN 到目标能通过 direct 连通,再测试内核绕过。fw4、masquerade、源地址、LAN 客户端默认网关、回程路由和 IPv6 table 2022。
Windows使用 route + direct,不照抄未指定 outbound 的 bypass。规则顺序、DNS、默认网卡绑定和应用是否复用旧连接。
macOS使用 route + direct,必要时设置自动检测网卡。出站绑定、DNS 解析和系统路由,不把 Linux auto_redirect 示例直接迁移。
Android普通 VPNService 使用 route + direct。root 环境的 auto_redirect 要单独核对;它不等同于 bypass 动作获得跨平台支持。

官方 TUN 文档将 auto_redirect 的完整支持分为 Linux,以及 Android 图形客户端的 root 服务或 root shell 场景;但规则动作文档对未指定 outbound 的 bypass 仍明确标注为仅支持 Linux。因此 Android root 能使用部分 auto_redirect 能力,并不代表可以把 bypass 当成普通 Android VPNService 的通用规则。

Linux 的最小排障配置可以使用下面结构,但它不是订阅配置的替代品:

{
  "log": {
    "level": "debug",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "tun",
      "tag": "tun-in",
      "address": [
        "172.19.0.1/30",
        "fdfe:dcba:9876::1/126"
      ],
      "auto_route": true,
      "auto_redirect": true,
      "strict_route": false
    }
  ],
  "outbounds": [
    {
      "type": "direct",
      "tag": "direct"
    }
  ],
  "route": {
    "final": "direct",
    "auto_detect_interface": true
  }
}

这里把 strict_route 设为 false,是为了排障时先排除严格路由对不经过 TUN 的流量、局域网访问或部分系统应用的影响。官方文档说明,strict_route 可能使不支持的网络不可达;在 Windows 上还可能影响某些应用,因此测试完成后应根据原配置恢复。TUN 字段说明和路由配置文档可用于核对字段位置。

这份配置中的 final: direct 会让未匹配流量全部直连,只能作为临时诊断状态。测试结束后恢复原来的代理出站和 final,否则可能误以为代理功能失效。

bypass 不生效、断网或回环:按顺序执行检查

  1. 确认版本和平台。执行
    sing-box version
    如果不是 Linux,或者版本低于 1.13.0,先不要继续追查未指定 outbound 的 bypass,改用 action: route + outbound: direct。
  2. 确认 TUN 前置条件。配置中应能找到 auto_route: true 和 auto_redirect: true。Linux 还要检查内核队列和系统规则。建议分开看命令、正常线索和异常含义:
Linux TUN 路由检查表
命令正常应看到什么异常说明什么
test -e /proc/net/netfilter/nfnetlink_queue && echo nfqueue-present || echo nfqueue-missing输出 nfqueue-present。内核可能没有加载 NFQUEUE,预匹配无法按预期工作。
nft list ruleset | grep -E 'sing-box|nfqueue|queue'能看到 sing-box 或 queue 相关规则。auto_redirect 未生效、规则未插入,或当前系统后端不同。
ip -4 rule show、ip -6 rule show能看到与实际配置对应的 fwmark 和查表规则。规则缺失、标记被改写,或不能按固定示例判断。
ip route show table 2022、ip -6 route show table 2022存在符合当前网络的默认路由和接口。路由指向 TUN、表为空或 IPv6 默认路由错误。

官方文档给出的默认 Linux 输入标记是 0x2023、输出标记是 0x2024,但排查时应先从当前 ip rule show 或 ip -6 rule show 读取实际值,再代入路由查询,不要盲抄固定 mark。

  1. 打开 debug 日志并只复现一次。在现有 log 配置中临时加入或修改为:
{
  "log": {
    "level": "debug",
    "timestamp": true
  }
}

重启 sing-box 后只访问一次目标地址,搜索日志中的 route、bypass、tun、dns 和 outbound。重点看目标是否命中预期规则、是否被前面的规则截断、出站标签是否存在。日志字段的可用值以sing-box 日志文档为准。

  1. 重新建立连接。预匹配发生在连接建立之前:TCP 在连接建立前没有可用的连接数据,UDP 在该阶段只能看到首个数据包;如果探测动作需要更多数据,预匹配会在相应规则处停止。不要用已经打开的浏览器连接判断修改是否生效,关闭应用连接或重启应用后再试。参见sing-box 预匹配文档。
  2. 检查 FakeIP、DNS 和协议探测。官方预匹配文档明确说明,FakeIP 目标需要先执行 resolve,否则连接会被拒绝。UDP 只失败而 TCP 正常时,再检查首个 UDP 包、DNS、QUIC 和 sniff 规则;不要把“域名规则未命中”直接判断为 bypass 故障。协议探测字段和支持的协议见sing-box 协议探测文档。
  3. 单独验证 IPv4 和 IPv6。执行:
ip route get 1.1.1.1
ip -6 route get 2606:4700:4700::1111
ip -6 rule show
ip -6 route show table 2022
ip -6 route get 2606:4700:4700::1111 mark 0x实际标记

最后一行的标记值要替换成你从 ip -6 rule show 读取到的实际值。查询结果如果指向 sing-box 自己的 TUN,而不是上游 WAN 接口,就应先修正 table 2022 的 IPv6 路由或恢复 route + direct 测试,不要继续增加 bypass 规则。

Issue #4645 复现了什么:IPv6 超时时查 table 2022

公开 Issue #4645 的环境是 Linux 路由器 ImmortalWrt 25.12.2、sing-box 1.14.3。报告描述的条件是:IPv6 默认路由带有源地址限定,TUN 的 auto_route 将自身 IPv6 默认路由写入 bypass 使用的 table 2022;带有 fwmark 0x2023 的 IPv6 出站连接随后被送回 TUN,形成黑洞。Issue 中记录的示例规则是 fwmark 0x2023 lookup 2022,并且标记后的 IPv6 查询结果指向 TUN 接口;这些值属于该报告环境,不能替代你本机的 ip -6 rule show 输出。参见sing-box Issue #4645。

IPv6 超时的现象、原因与检查
现象报告中对应的原因先执行什么
IPv4 正常、IPv6 出站失败Issue 报告称 table 2022 的 IPv4 默认路由正常,而 IPv6 默认路由错误指向 TUN。ip -6 route show table 2022
带标记的 IPv6 路由回到 TUN报告示例中 fwmark 0x2023 查询到 sing-box TUN 接口。ip -6 rule show 和带实际 mark 的 ip -6 route get
连接没有明显错误日志Issue 将该复现描述为 silent blackhole。不要只看日志,同时检查内核路由表。
重启时报 route already exists报告还记录了停止后 table 2022 残留路由的次生问题。先保存路由输出,再按你的系统维护流程清理残留项。

这是一份特定 Linux/OpenWrt 环境的公开问题报告,不代表所有 sing-box 版本、系统或网络都会出现同样故障。若你的 IPv6 失败与该条件不符,仍应回到平台、auto_redirect、DNS、规则顺序和上游 IPv6 连通性检查。

OpenWrt 旁路网关:bypass 超时先查 NAT 和回程路由

旁路网关中,内核 bypass 与 route + direct 的路径不同:绕过 TUN 后,数据包可能不再经过 sing-box 的地址处理;如果没有正确的 masquerade,源地址可能仍是 LAN 客户端地址,外部网络的回程就可能不经过旁路网关;如果反向路径过滤认为入接口与源地址不匹配,也可能丢弃返回包。因此“规则命中了但连接超时”不一定是规则语法错误。

在 OpenWrt 网关上先执行只读检查,接口名按实际环境替换:

sysctl net.ipv4.ip_forward
sysctl net.ipv4.conf.all.rp_filter
sysctl net.ipv4.conf.default.rp_filter
nft list table inet fw4
ip route show
ip -6 route show
ip -6 route show table 2022

检查结果按“现象→原因→命令”理解:

旁路网关排查表
现象优先怀疑对应检查
LAN 客户端完全无法转发内核转发未开启或默认网关没有指向旁路网关。sysctl net.ipv4.ip_forward;在 LAN 客户端查看默认网关。
请求发出但返回包丢失没有合适的 masquerade,或回程路径绕开旁路网关。nft list table inet fw4、ip route show。
部分接口访问超时rp_filter 对源地址和入接口判断不一致。sysctl net.ipv4.conf.all.rp_filter 与接口级设置。
仅 IPv6 超时IPv6 table 2022 中的默认路由回到 TUN,或上游 IPv6 回程异常。ip -6 route show table 2022、ip -6 route get。

建议顺序是:第一步关闭 bypass,用 route + direct 验证 LAN 到目标的基础连通性;第二步确认 auto_redirect、fw4 和 nfqueue;第三步只测试一个明确的 IP/CIDR;最后才测试未指定 outbound 的 bypass。不要为了验证而直接清空 nftables 或删除系统路由,先保存命令输出,并且每次只改一个条件。

本站是第三方使用指南站,不是 sing-box 官方站点;配置字段、平台支持和当前界面应以你正在使用的版本及官方文档为准。

常见问题

sing-box bypass 在 Windows、macOS 或 Android 上为什么不生效?

官方规则动作文档将未指定 outbound 的 bypass 标注为仅支持 Linux,并要求启用 auto_redirect。Windows、macOS 和普通 Android VPNService 场景应改用 action: route + outbound: direct;Android root 的 auto_redirect 能力不能等同于 bypass 动作获得跨平台支持。参见规则动作文档。

action:bypass 和 direct 出站有什么区别?

direct 是出站,规则把连接交给它处理;bypass 则是在特定 Linux auto_redirect 预匹配中,让连接在内核层绕过 sing-box。若 bypass 指定了 outbound,在非 auto_redirect 或已建立连接中,其行为与 route 相同,不应把两者视为完全等价。

为什么 bypass 规则写在配置里,却像没有匹配?

未指定 outbound 的 bypass 只在 auto_redirect 预匹配中匹配,非 auto_redirect 连接和已建立连接会被跳过。先确认版本、平台、auto_route 和 auto_redirect,再打开 log.level: debug 重现一次,并检查规则前面是否已有更早的匹配项。

route_exclude_address 和 route_exclude_address_set 应该怎么选?

route_exclude_address 适合直接填写少量需要从 TUN 自动路由中排除的地址或 CIDR;route_exclude_address_set 按规则集中的 IP CIDR 匹配,官方要求 Linux、auto_route 和 auto_redirect。若只是少量固定网段,先使用明确地址更容易核验;若使用规则集,还要检查规则集加载和系统路由结果。

IPv6 出站全部超时,是不是一定要把 mark 改成 0x2023?

不是。官方 TUN 文档将 0x2023 列为 Linux 默认 auto_redirect 输入标记,Android 默认值不同,配置也可能自定义。Issue #4645 的复现环境确实出现了 fwmark 0x2023 lookup 2022,但你仍应先从 ip -6 rule show 读取实际标记,再用 ip -6 route get 验证路由是否回到 TUN。

常见问题

sing-box bypass 在 Windows、macOS 或 Android 上为什么不生效?

官方规则动作文档将未指定 outbound 的 bypass 标注为仅支持 Linux,并要求启用 auto_redirect。Windows、macOS 和普通 Android VPNService 场景应改用 action: route + outbound: direct;Android root 的 auto_redirect 能力不能等同于 bypass 动作获得跨平台支持。

action:bypass 和 direct 出站有什么区别?

direct 是出站,规则把连接交给它处理;bypass 则是在特定 Linux auto_redirect 预匹配中,让连接在内核层绕过 sing-box。若 bypass 指定了 outbound,在非 auto_redirect 或已建立连接中,其行为与 route 相同,不应把两者视为完全等价。

为什么 bypass 规则写在配置里,却像没有匹配?

未指定 outbound 的 bypass 只在 auto_redirect 预匹配中匹配,非 auto_redirect 连接和已建立连接会被跳过。先确认版本、平台、auto_route 和 auto_redirect,再打开 log.level: debug 重现一次,并检查规则前面是否已有更早的匹配项。

route_exclude_address 和 route_exclude_address_set 应该怎么选?

route_exclude_address 适合直接填写少量需要从 TUN 自动路由中排除的地址或 CIDR;route_exclude_address_set 按规则集中的 IP CIDR 匹配,官方要求 Linux、auto_route 和 auto_redirect。若只是少量固定网段,先使用明确地址更容易核验;若使用规则集,还要检查规则集加载和系统路由结果。

IPv6 出站全部超时,是不是一定要把 mark 改成 0x2023?

不是。官方 TUN 文档将 0x2023 列为 Linux 默认 auto_redirect 输入标记,Android 默认值不同,配置也可能自定义。Issue #4645 的复现环境确实出现了 fwmark 0x2023 lookup 2022,但你仍应先从 ip -6 rule show 读取实际标记,再用 ip -6 route get 验证路由是否回到 TUN。

参考资料

  1. sing-box 规则动作
  2. sing-box Tun 配置
  3. sing-box 路由配置
  4. sing-box 日志配置
  5. sing-box Issue #4645:TUN auto_route 与 IPv6 bypass 路由问题