事情起因很 mundane:之前一直用 Cursor Remote SSH 连家里 Fedora 工作站写代码,某天突然连不上了。终端里 ssh jamie@wj.luchador.dev 照样能登录,就是 Cursor 卡在「Connecting…」然后报一堆 channel open failed。
今天终于抽空查。各种 AI 给出的「经典解法」试了一圈,差点以为自己 sshd 配错了。最后在 Cockpit 的 SELinux 页看到拒绝日志,再对照系统更新时间和 ausearch,才把锅扣到 8 月下旬的 selinux-policy 更新上——和 Cursor 本身关系不大。
症状:SSH 能登,Cursor 不能
Cursor 日志里典型路径是:
- SSH 握手成功(几百毫秒)
- 远程
cursor-server安装/启动成功,报告codeListeningOn==42539之类 - 本地通过
ssh -D(SOCKS)去连远程127.0.0.1:42539时失败 - 反复重试后提示:
Failed to connect to Cursor code server.
Ensure that your remote host ssh config has 'AllowTcpForwarding yes' ...
channel 3: open failed: connect failed: open failed
终端 SSH 不需要端口转发,所以 「命令行能连、Cursor 不能连」 本身就把问题范围缩小了:不是认证、不是防火墙挡 22 端口,而是转发链路断了。
AI 经典解法:试了一圈,都不是根因
下面这几条在社区里出现频率极高,我也都验证了——对你这种 Fedora 44 + Enforcing SELinux 的组合,单独做往往不够,甚至会误导。
AllowTcpForwarding
远程查注释行:
sudo grep -i AllowTcpForwarding /etc/ssh/sshd_config
#AllowTcpForwarding yes
注释掉 不等于默认拒绝。实际生效值:
sudo sshd -T | grep -i allowtcpforwarding
# allowtcpforwarding yes
日志里若是 sshd 配置拒绝,通常会写 administratively prohibited;我的是 connect failed——说明 sshd 允许转发请求,但 连目标端口时失败,方向就不在 sshd_config 了。
sshd_forward_ports
Fedora 14 时代的老 boolean,很多文章还在写:
sudo setsebool -P sshd_forward_ports 1
在 Fedora 44 上:
getsebool sshd_forward_ports
# Error getting active value for sshd_forward_ports
策略里已经没这个开关了。 AI 训练语料里它出现太多,容易把人带进死胡同。
本地代理
Mac 上有 Clash 一类代理时,有时会影响 Remote SSH。我这次 ssh -v 里是直连 wj.luchador.dev:22(IPv6),没有 ProxyCommand;且 纯终端 ssh -D 在 Enforcing 下同样失败,所以本地代理不是主因。
Mac 上 ssh -D 自测(决定性)
终端 1:
ssh -N -D 1080 jamie@wj.luchador.dev
终端 2:
nc -zv -X 5 -x 127.0.0.1:1080 127.0.0.1 22
nc -zv -X 5 -x 127.0.0.1:1080 127.0.0.1 5432
Enforcing 下:Broken pipe / channel open failed。
这和 Cursor 用的是同一条机制——Cursor 没坏,转发层坏了。
真正根因:SELinux + 8 月策略更新
setenforce 0 对比
sudo setenforce 0
Mac 上再跑上面的 nc -X:22 和 5432 都 succeeded。
说明:不是 postgres 没监听、不是 Cursor 安装失败,是 SELinux 在 Enforcing 下拦 sshd-session 的 name_connect。
Cockpit 与 AVC 日志
Cockpit → SELinux 策略页里反复出现类似拒绝(端口每次不同,Cursor 动态分配):
SELinux 正在阻止 sshd-session 对 name_connect tcp_socket 进行端口 41035 访问。
ausearch 里能对上整段排查过程:
avc: denied { name_connect } for comm="sshd-session"
dest=22 → ssh_port_t
dest=5432 → postgresql_port_t
dest=41035 → ephemeral_port_t # cursor-server 监听口
scontext=...:sshd_session_t:...
permissive=0 # Enforcing,真拦
早期 ausearch 为空,是因为部分拒绝曾被 dontaudit 静默;后来在 Cockpit / 打开 dontaudit 调试后才看见全貌。
系统更新时间线(和「以前好用、突然不行」对齐)
家里机器上:
2026-08-22 openssh-10.2p1-14.fc44
2026-08-25 selinux-policy-targeted-44.7-1.fc44
OpenSSH 10 起,sshd 拆成 sshd-auth、sshd-session 等组件,日志里进程名变成 sshd-session,SELinux 域是 sshd_session_t。
selinux-policy 44.6 / 44.7(8 月 14 日进 testing,25 日装到机器)changelog 里有一条关键变更:
Remove permissive setting for sshd_auth_t and sshd_session_t
含义是:以前 sshd_session_t 处于 permissive 域——违反策略只记日志、不真拦;更新后同一类操作在 Enforcing 下 直接拒绝。
所以时间线很顺:
| 阶段 | 现象 |
|---|---|
| 更新前 | Cursor Remote SSH 正常(转发违规但被 permissive 放过) |
| 8/22–8/25 更新后 | 同样操作被 SELinux 执行拒绝 → Cursor / ssh -D 挂 |
终端 ssh 登录 |
一直正常(不需要 name_connect 转发) |
不是 Cursor 某版更新单独搞坏了 SSH,而是 Linux 发行版安全策略 + OpenSSH 10 架构变更叠在一起。
修复
Cockpit 对这条 AVC 的建议是启用 boolean nis_enabled(名字像 NIS,实际是策略里一组「允许连非标准端口」的宽松规则,setroubleshoot 常拿它修 name_connect):
sudo setsebool -P nis_enabled 1
getsebool nis_enabled # --> on
或在 Cockpit SELinux 页对相应拒绝点 「采用该解决方案」。
然后确认仍在 Enforcing:
getenforce # Enforcing
Mac 上再测 ssh -D + nc,最后清一次远程 Cursor 残留并重连:
pkill -f cursor-server || true
rm -rf ~/.cursor-server
不建议长期 setenforce 0;nis_enabled 比关整个 SELinux 窄得多。若介意范围太大,可以用 audit2allow 做只针对 sshd_session_t 的本地模块(Cockpit 方案 2)。
排查流程(给以后的自己)
sequenceDiagram
participant Mac as Mac_Cursor_or_ssh_D
participant SSH as SSH_session
participant Remote as Fedora_sshd_session
participant SEL as SELinux
Mac->>SSH: ssh -D 建立隧道
SSH->>Remote: 登录成功
Remote->>Remote: 启动 cursor-server
Mac->>SSH: SOCKS 连 127.0.0.1:动态端口
SSH->>Remote: direct-tcpip 转发
Remote->>SEL: name_connect 本机端口
SEL--xRemote: Enforcing 拒绝
Note over Mac,SEL: channel open failed
简表:
| 检查项 | 正常时应看到 |
|---|---|
sshd -T | grep allowtcpforwarding |
yes |
终端 ssh |
能登录 |
ssh -D + nc -X |
Enforcing 下也应通(修复后) |
ausearch -m avc | grep sshd-session |
修复后无新拒绝 |
getsebool nis_enabled |
on(若采用 Cockpit 方案) |
参考链接(策略更新与社区讨论)
本次直接相关的 Fedora 更新
- selinux-policy 44.7-1.fc44 Changelog(含 Remove permissive setting for sshd_session_t)
- openssh 10.2p1-14.fc44(同时间段更新)
OpenSSH 10 组件拆分(为何日志里是 sshd-session)
同类问题的 Bug / 讨论(agent 转发、X11 等)
- Bug 2502040:ssh agent forwarding blocked by selinux(仍开放)
- Fedora Discussion:Rawhide SELinux breaks SSH agent forwarding
- fedora-selinux PR #3388:Allow sshd-session X11 forwarding(2026-08-27 合并,修的是 X11,不是 TCP 动态转发)
Cursor / VS Code Remote SSH 通用说明(报错文案相同,根因未必相同)
- VS Code Remote 故障排查:Enable TCP Forwarding
- Cursor Forum:Remote SSH breaks / AllowTcpForwarding 提示
- vscode-remote-release Issue #9343:端口转发被禁时的报错不够明显
SELinux boolean 文档(nis_enabled 命名很迷惑)
后记
这次最大的教训:「终端 SSH 能连」不能推出「Remote SSH 能连」;Cursor / VS Code 在底下偷偷用了 ssh -D,碰的是 sshd 转发 + SELinux name_connect 这条更窄的路。
AI 给的 AllowTcpForwarding、sshd_forward_ports 在 2026 年的 Fedora 44 上经常 不是 答案;Cockpit / ausearch + 对照 rpm -qa --last 才把时间线和根因对齐。
发这篇主要是给以后的自己和同样「家里 Fedora + Cursor Remote」的人留个坑位记录:系统更了,策略收紧了,不是你突然不会用 SSH 了。