Note

ShellCrash 的非常用端口过滤:一次远程 RStudio 访问故障排查

当 10.20.30.0/24 的 IP 规则已经加载,RStudio Server 仍无法访问时,真正的问题可能在端口过滤,而不是订阅规则。

目录
目录

最近排查了一次很典型的透明代理问题:远程服务器所在的网段已经写进 mihomo 规则,但服务器上的 RStudio Server 仍然访问不了。最后真正起作用的修改并不是重新下载订阅,而是关闭 ShellCrash 的“过滤非常用端口”。

这次经历值得记录,因为它说明了一个容易被忽略的事实:

IP 规则已经加载,不代表这个 IP 上的所有端口都一定进入了透明代理。

问题是怎么表现的

远程服务器位于一个独立网段:

10.20.30.0/24

其中一台服务器运行着:

SSH:22
RStudio Server:8866

路由器上的 mihomo 规则已经包含:

IP-CIDR 10.20.30.0/24 → LAN 专用代理节点

但是本机访问服务器时,SSH 连接超时,RStudio Server 的 8866 端口也无法打开。与此同时,局域网中的 Lucky 反向代理和 RustDesk 服务仍然可以使用,导致问题一开始看起来像是某个单独服务或公网端口故障。

先确认 IP 规则是否存在

通过路由器 mihomo API 查询规则,可以确认网段规则确实存在:

{
  "type": "IPCIDR",
  "payload": "10.20.30.0/24",
  "proxy": "LAN 专用代理节点"
}

这一步只能证明规则被加载,不能证明请求已经经过这条规则。透明代理排查至少还要继续确认:

  1. 本机路由把流量交给了谁;
  2. 路由器防火墙是否将流量重定向给 mihomo;
  3. 目标端口是否被端口过滤功能排除。

关键线索:端口过滤

ShellCrash 中原来的配置是:

过滤非常用端口:ON

这个选项的目标是减少 P2P 和其他大量非网页流量进入代理。它会对非常用端口进行过滤,而 8866 显然不是典型的网页端口。

修改为:

过滤非常用端口:OFF

之后,RStudio Server 的 10.20.30.26:8866 立即恢复访问。SSH 等其他非标准端口也恢复正常。

因此最终根因不是:

  • 订阅规则没有更新;
  • 远程服务器宕机;
  • RStudio Server 没有启动;
  • 服务商封锁了端口;
  • Lucky 的反向代理整体故障。

而是:

目标 IP 命中了规则,但目标端口被 ShellCrash 的非常用端口过滤排除。

RustDesk 和 Lucky 为什么容易造成误判

RustDesk 使用了 Lucky 的反向代理入口。入口端口是一个自定义端口,而不是 RustDesk 后端直接暴露的标准服务端口。

因此要区分两条链路:

公网客户端 → Lucky 的反向代理入口 → NAS 上的 RustDesk

以及:

本机 → 远程服务器的非标准端口

Lucky 的监听端口本身不需要 ShellCrash 去代理。但如果局域网客户端通过公网域名访问自己的反向代理入口,客户端发起的出站连接仍可能受到 ShellCrash 的透明代理和端口过滤影响。

这也是为什么“局域网服务正常”不能直接证明“从本机访问公网域名的路径正常”。

fake-ip 提示应该怎么理解

ShellCrash 菜单中还有一条提示:

MIX模式下,所有fake-ip来源的非常用端口流量不会被过滤

它的含义是:在 MIX 模式下,来自 fake-ip 的非常用端口流量有特殊例外。

但这次访问远程服务器时使用的是实际 IP 地址,不是 fake-ip;RustDesk 报错中也出现过实际公网 IP。因此 fake-ip 例外并没有覆盖这次连接。

不要把下面两种情况混在一起:

域名 → fake-ip → 非常用端口

和:

直接访问实际 IP → 非常用端口

它们可能走不同的透明代理处理路径。

最终配置

本次采用的配置是:

过滤非常用端口:OFF

同时确认远程网段不在 ShellCrash 的“自定义保留地址 IPv4 网段”中:

10.20.30.0/24

应当从保留地址列表中删除;mihomo 中的 IP-CIDR 代理规则则继续保留:

IP-CIDR 10.20.30.0/24 → LAN 专用代理节点

最终逻辑是:

保留地址列表:不包含 10.20.30.0/24
代理规则:包含 10.20.30.0/24
非常用端口过滤:OFF

要不要重新打开过滤

如果只需要代理少量固定端口,并且 ShellCrash 的白名单明确表示“允许这些端口进入透明代理”,可以考虑:

过滤非常用端口:ON
端口白名单:22 8866 51114

但必须先确认白名单语义。有些配置中的白名单表示“绕过代理”,有些表示“允许处理”,含义正好相反。

如果经常使用整个远程网段,或者以后还会增加新的 RStudio、Jupyter、SSH、API 和远程桌面端口,关闭过滤更稳妥。否则每新增一个端口,都可能再次出现“IP 规则存在但服务无法访问”的问题。

排查时保留的验证方法

验证 SSH 时,先排除本机 SSH 配置对结果的干扰:

ssh -F /dev/null -o ConnectTimeout=10 -p 22 user@10.20.30.26

验证 RStudio:

curl -v --connect-timeout 10 http://10.20.30.26:8866/

验证公网反向代理入口:

curl -v --connect-timeout 5 --max-time 10 http://example.com:51114/

HTTP 返回 400、401、404 或 JSON,都说明 TCP 端口已经连通;timeout 和 Connection refused 才说明连接链路或监听存在问题。

结论

这次故障的排查顺序最终可以归纳为:

先确认 IP 规则是否加载
再确认透明代理是否实际接管
最后检查端口过滤是否排除了目标端口

对于访问远程科研服务器的环境,22、8866、自建 API 和反向代理端口都很常见。ShellCrash 的“过滤非常用端口”虽然可以降低 P2P 流量对代理资源的消耗,但也可能让非标准端口无法沿着预期的代理路径访问。

在需要访问整个远程网段的场景下,稳定性优先时,保持该选项关闭通常比维护一份不断增长的端口白名单更可靠。

建议阅读

讨论

评论使用 GitHub Discussions。首次加载需要访问 GitHub。