Note
ShellCrash 的非常用端口过滤:一次远程 RStudio 访问故障排查
当 10.20.30.0/24 的 IP 规则已经加载,RStudio Server 仍无法访问时,真正的问题可能在端口过滤,而不是订阅规则。
Note
当 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 服务仍然可以使用,导致问题一开始看起来像是某个单独服务或公网端口故障。
通过路由器 mihomo API 查询规则,可以确认网段规则确实存在:
{
"type": "IPCIDR",
"payload": "10.20.30.0/24",
"proxy": "LAN 专用代理节点"
}
这一步只能证明规则被加载,不能证明请求已经经过这条规则。透明代理排查至少还要继续确认:
ShellCrash 中原来的配置是:
过滤非常用端口:ON
这个选项的目标是减少 P2P 和其他大量非网页流量进入代理。它会对非常用端口进行过滤,而 8866 显然不是典型的网页端口。
修改为:
过滤非常用端口:OFF
之后,RStudio Server 的 10.20.30.26:8866 立即恢复访问。SSH 等其他非标准端口也恢复正常。
因此最终根因不是:
而是:
目标 IP 命中了规则,但目标端口被 ShellCrash 的非常用端口过滤排除。
RustDesk 使用了 Lucky 的反向代理入口。入口端口是一个自定义端口,而不是 RustDesk 后端直接暴露的标准服务端口。
因此要区分两条链路:
公网客户端 → Lucky 的反向代理入口 → NAS 上的 RustDesk
以及:
本机 → 远程服务器的非标准端口
Lucky 的监听端口本身不需要 ShellCrash 去代理。但如果局域网客户端通过公网域名访问自己的反向代理入口,客户端发起的出站连接仍可能受到 ShellCrash 的透明代理和端口过滤影响。
这也是为什么“局域网服务正常”不能直接证明“从本机访问公网域名的路径正常”。
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。