Bug 描述
在 Merlin 路由器(RT-AX86U Pro)上使用 ShellCrash 1.9.4 + SingBoxR 内核 1.13.2 配置 Tailscale 时,Tailscale 后台 Subnet routes 显示 "invalid Prefix",无法 approve,导致只能走 DERP 中继。
复现步骤
- 启用 Tailscale(
crash → 7 → 6),开启 Subnet 通告
- 重启 ShellCrash
- 在 Tailscale 后台查看设备的 Edit route settings
- Subnet routes 显示 "invalid Prefix",点 Approve 报错 "Failed to update route settings"
根因分析
sb_endpoints.sh 通过 fw_getlanip.sh 的 getlanip 函数获取本机路由表,生成 advertise_routes。
路由表中点对点路由(WireGuard、PPPoE)不带 CIDR 前缀:
$ ip route show scope link
10.6.0.2 dev wgs1 ← 裸 IP,无 /32
10.6.0.3 dev wgs1 ← 裸 IP,无 /32
x.x.x.x dev ppp0 ← 裸 IP,无 /32
192.168.50.0/24 dev br0 ← 正常 CIDR
sb_endpoints.sh 直接将 $host_ipv4 拼入 JSON:
"advertise_routes": ["10.6.0.2", "10.6.0.3", "x.x.x.x", "192.168.50.0/24"]
sing-box 的 Tailscale endpoint 要求 advertise_routes 使用 netip.ParsePrefix() 解析,必须是 CIDR 格式,裸 IP 会导致解析失败。
建议修复
在 sb_endpoints.sh 中 getlanip 调用之后、advertise_routes 赋值之前,给裸 IP 补上 /32。
注意:Merlin 的 BusyBox sed 不支持 \+ 语法,需使用 awk:
. "$CRASHDIR"/starts/fw_getlanip.sh && getlanip
# 给没有 CIDR 前缀的裸 IP 补 /32
host_ipv4=$(echo $host_ipv4 | awk '{for(i=1;i<=NF;i++){if($i !~ /\//){$i=$i"/32"}} print}')
advertise_routes=$(echo "$host_ipv4"|sed 's/[[:space:]]\+/", "/g; s/^/"/; s/$/"/')
修复后:
"advertise_routes": ["10.6.0.2/32", "10.6.0.3/32", "x.x.x.x/32", "192.168.50.0/24"]
环境信息
- 路由器:Asus RT-AX86U Pro (Merlin)
- ShellCrash 版本:1.9.4release
- 内核:SingBoxR 1.13.2
- 受影响文件:
libs/sb_endpoints.sh、starts/fw_getlanip.sh
Bug 描述
在 Merlin 路由器(RT-AX86U Pro)上使用 ShellCrash 1.9.4 + SingBoxR 内核 1.13.2 配置 Tailscale 时,Tailscale 后台 Subnet routes 显示 "invalid Prefix",无法 approve,导致只能走 DERP 中继。
复现步骤
crash → 7 → 6),开启 Subnet 通告根因分析
sb_endpoints.sh通过fw_getlanip.sh的getlanip函数获取本机路由表,生成advertise_routes。路由表中点对点路由(WireGuard、PPPoE)不带 CIDR 前缀:
sb_endpoints.sh直接将$host_ipv4拼入 JSON:sing-box 的 Tailscale endpoint 要求
advertise_routes使用netip.ParsePrefix()解析,必须是 CIDR 格式,裸 IP 会导致解析失败。建议修复
在
sb_endpoints.sh中getlanip调用之后、advertise_routes赋值之前,给裸 IP 补上/32。注意:Merlin 的 BusyBox sed 不支持
\+语法,需使用 awk:修复后:
环境信息
libs/sb_endpoints.sh、starts/fw_getlanip.sh