加载失败
该讨论源自对“SSH Secret Menu”(实为 OpenSSH 客户端的转义/escape 菜单)和 man ssh 提示的反应,评论从发现 ~. 这类逃生序列出发延伸到 man 页可读性争议、ssh_config 中的高级选项(例如 ProxyCommand/ProxyJump、ControlMaster)、网络导致的连接中断(CGNAT、IPv6 临时地址)及对策(ServerAliveInterval、内核 tcp_keepalive、VPN/Tailscale、Mosh)。许多回复给出具体命令、内核参数和配置片段,并讨论在不同 shell 或 OpenSSH 版本下的兼容性细节;同时有人指出实战示例常散落在博客、Stack Overflow 或公开 dotfiles,而非统一且易读的官方文档。
很多人对发现 OpenSSH 的交互式逃生菜单感到惊讶并带有怀旧情绪:常见的 ~. 用于在挂起的 SSH 会话中关闭连接,~~ 可发送字面 ~,这些技巧在拨号和不稳定网络时代很常见。大量评论说自己多年习惯通过关终端或杀进程来收尾挂起连接,看到 ~. 后觉得「学到了新东西但也怀旧」。有人把它与早年的 rsh/telnet(例如 telnet 的 Ctrl-])和 uucp 等老工具作对比,认为这种小技巧现在成了复古的“秘密菜单”。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7]
评论里对 man pages 的质量有明显分歧:有人觉得很多 man 页十分简略、像 fortune cookie,甚至仅指向 info 页面或重复 --help;也有人强调不少 man 页包含极有价值的细节(举例 jq 的 man 页)。多人承认几乎没人全读 man 页,更多人靠 Google、Stack Overflow 或 LLM 来查用例;同时也有人提醒存在 apropos/man -k 这样的索引工具,可以帮助发现命令。另有观点指出 SSH 的有些“秘密”其实写在 man ssh_config 里(比如 ProxyCommand),只是实战用例常散落在博客和 dotfiles,而非直观示例。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8]
评论讨论了 ssh 配置里多种代理/跳板策略:ProxyJump(-J)是较新的简写,方便做通过 bastion 的常见跳转,而 ProxyCommand 更灵活,能运行任意命令来用 stdin/stdout 模拟 TCP 链接,从而支持串口、Bluetooth RFCOMM、vsock(虚拟机无网络时的通信)等非典型传输。实际案例还包括用 spipe 隧道、systemd 提供的 vsock 支持,以及在某些场景用 ProxyCommand 做自定义链路的做法;ControlMaster 则用于连接复用,使“新”会话瞬时建立但可能在转发/端口管理上带来复杂性。评论里也指出一些实用操作,例如用 -KD portnum 关闭转发端口,以及在使用 ControlMaster 时遇到的端口和隧道生命周期问题。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9] [来源10]
很多人把挂起或断开的 SSH 会话归因于中间网络设备,尤其是运营商级 CGNAT(Carrier Grade NAT)会把 TCP 空闲超时设得很短,例如移动运营商常见的 5 分钟,而内核默认 TCP keepalive 是 2 小时。评论给出具体对策:通过 VPN 或 Tailscale(基于 WireGuard 的点对点网络)绕开 CGNAT、在客户端配置 ServerAliveInterval(例如 Host * ServerAliveInterval 25)或修改内核参数来频繁发送 keepalive(示例 net.ipv4.tcp_keepalive_time=240、tcp_keepalive_intvl=60、tcp_keepalive_probes=120),并指出这是对 keepalive 语义的“挤用”但实用。另有关于 IPv6 的讨论:临时地址旋转会断开连接,提出了 Linux 特定的补丁但被 upstream 拒绝(可移植性问题),以及推荐用 Mosh 来自动重连并在低带宽场景表现更好。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8]
评论中提供了大量关于 escape 序列的行为细节:转义字符 ~ 只有在换行后或会话起始位置作为时间上第一个字符时才触发,输入过程中回退(backspace)并不会改变已经发送的输入字节,这就是为什么屏幕上看似被删掉的字符仍然生效。实务中会遇到 shell 或终端拦截(例如 fish),导致直接输入 ~. 无效,常见解决办法是先按 ENTER 或用 cat 读入一个交互式输入再试;OpenSSH 还有 EnableEscapeCommandline、EscapeChar 等配置可以控制或禁用这些行为,且这些序列只在分配 PTY 的交互式会话生效(非交互管道需加 -t 强制)。这些兼容性细节解释了为何不同环境下相同行为会表现不同。
[来源1] [来源2] [来源3] [来源4] [来源5] [来源6] [来源7] [来源8] [来源9] [来源10]
man / man page: Unix/Linux 的命令手册页,通过 man 命令查看,包含语法、选项和(有时)示例;不同程序的 man 页质量差异很大,有的简略有的详尽。
apropos / man -k: 用于按关键字搜索本地 man 页索引的命令(man -k 等同 apropos),帮助发现相关命令或主题。
SSH escape sequences: OpenSSH 客户端在交互式 PTY 会话中实现的一组转义命令(如 ~. 关闭连接、~~ 发送字面 ~、~C 进入命令行),这些序列仅在 ~ 是行首或会话首字符时生效。
ProxyCommand: ssh_config 中的选项,可指定任意命令作为连接中介,该命令通过 stdin/stdout 转发数据,允许通过非标准传输(如串口、Bluetooth RFCOMM、vsock)或自定义隧道建立连接。
ProxyJump: ssh_config 中的 -J/ProxyJump,为通过一个或多个跳板主机中继连接提供便捷写法,本质上是常见的 ProxyCommand 用例的简化形式,但只以 SSH 作为中介。
ControlMaster: OpenSSH 的连接复用功能,允许多个 SSH 会话共享同一后端 TCP 连接以加速新会话并避免重复认证,但可能带来端口转发和隧道生命周期管理的复杂性。
CGNAT (Carrier Grade NAT): 运营商级共享 IPv4 NAT,会对公网地址进行集中 NAT 翻译并常设置较短的 TCP 空闲超时,导致长时间空闲的 SSH 连接被中间设备丢弃。
ServerAliveInterval / tcp_keepalive: ServerAliveInterval 是 OpenSSH 客户端配置项,用于周期性向服务器发送保活消息;内核层面的 net.ipv4.tcp_keepalive_* 参数控制 TCP keepalive 的时间与频率,常被用于对抗 NAT 导致的连接超时。
Mosh: Mosh(mobile shell)是一个面向不稳定网络和漫游场景的远程 shell 替代方案,支持断线重连、低带宽下更好响应并减少带宽消耗。
Tailscale: 基于 WireGuard 的点对点 VPN / 私有网络服务,简化设备间的直接互联,常被用来绕过运营商 NAT 干扰并替代部分 SSH 隧道需求。
EscapeChar (OpenSSH 配置项): OpenSSH 配置中用于指定交互式转义字符或禁用该功能的选项(例如设置为 none 可以禁用 ~ 菜单行为)。