保持SSH连接长时间存活


如何保持 SSH 连接长时间存活呢?

对于需要管理 Linux 机器的运维人员来说,SSH 连接长时间存活,对于需要长时间执行任务或保持远程连接的用户来说非常重要。常用的方法有以下几种:

使用 Tmux 或 Screen 等终端复用工具:这些工具可以在一个终端中创建多个会话,即使断开连接,会话也会继续运行。使用 nohup 命令:在后台运行命令时,使用 nohup 命令可以忽略挂断信号,防止进程被终止。SSH 隧道:通过 SSH 隧道转发端口,可以保持连接的活跃状态。SSH Keepalive:在客户端和服务器之间定期发送心跳包,以防止连接超时断开。

保持SSH连接长时间存活


SSH 连接基础知识

如果希望主动检测客户端存活,建议手动配置。

基于 OpenSSH 官方文档,在 /etc/ssh/sshd_config 中,如果 没有显式设置 下面三个属性的话,它们会使用 默认值。这三个服务端配置,是保持 SSH 会话的时长的关键。

# TCP协议级别属性
TCPKeepAlive = yes # 默认值

# SSH协议级别属性
ClientAliveInterval = 0 # 默认值

# SSH协议级别属性
ClientAliveCountMax = 3 # 默认值

其中,TCPKeepAlive 表示是否启用 TCP 层的 SO_KEEPALIVE 机制(内核的 TCP 机制),保持 SSH 连接存活。如果网络出现故障(如客户端掉线),SSH 可能不会立即断开,而是等待 TCP 超时。如果网络不稳定,TCP 可能需要 数小时甚至更长时间 才会认为连接丢失。

其中,ClientAliveInterval 表示服务器是否会主动发送 keep-alive 消息。默认值为 0 表示 SSH 服务器不会检查客户端是否还在线,只有在 TCP 连接断开(受 TCPKeepAlive 控制)/客户端主动断开连接/管理员手动终止 SSH 进程 时,才会检测到连接丢失。

其中,ClientAliveCountMax 表示客户端未响应 ClientAliveInterval 发送的消息 3 次后,SSH 连接被终止。而且,仅在默认值为正数时生效。

# 如果这样设置的话
# 超过 60x5=300(5分钟) SSH连接才会被断开
ClientAliveInterval = 60
ClientAliveCountMax = 5

保持SSH连接长时间存活


SSH 连接断开原因

Linux 内核 TCP 层的 Keepalive 机制。

简短来说,导致 SSH 会话连接会断开的原因,这一切都归结为 TCP 超时。TCP 超时指 TCP 连接或网络操作在认为进程失败之前等待响应的持续时间。

保持SSH连接长时间存活

需要注意的是,TCPKeepAlive 作用于 TCP 层,默认启用且不会主动发送探测包。但依赖内核参数,如 net.ipv4.tcp_keepalive_time。而 ClientAliveInterval 作用于 SSH 协议层,默认 不会主动探测 客户端是否存活,除非手动开启。

# TCP连接空闲多少秒后开始发送Keepalive探测包
$ cat /proc/sys/net/ipv4/tcp_keepalive_time
7200 # 默认值(2小时)

# 每次Keepalive探测之间的时间间隔(秒)
$ cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75 # 默认值

# 探测失败多少次后认为连接失效并断开
$ cat /proc/sys/net/ipv4/tcp_keepalive_probes
9 # 默认值

保持SSH连接长时间存活


SSH 连接超时计算

TCPKeepAlive 受 Linux 内核参数影响。

假设如下配置,难道 SSH 的会话真的能够保证 2 给小时不中断吗?

如果 SSH 连接无流量,Linux 需要 2 小时+75×9 = 2 小时11分钟 才会判定其连接超时并将其断开。如果 TCPKeepAlive = no,那么 TCP 层不会发送探测包,SSH 连接可能一直保持,直到网络断开。

# SSHD
$ cat /etc/ssh/sshd_config
TCPKeepAlive yes

# TCP
$ cat /etc/sysctl.conf
tcp_keepalive_time = 7200 # 2小时后才发送第一个Keepalive探测
tcp_keepalive_intvl = 75  # 每隔75秒发送一次探测
tcp_keepalive_probes = 9  # 最多探测9次
$ sudo sysctl -p

保持SSH连接长时间存活


SSH 连接配置方式

服务端和客户端都需要配置。

保持 SSH 会话处于活动状态,需要客户端和服务器端同时配置才生效。

服务端配置:设置 SSH 服务器能主动探测客户端是否存活,并且可以防止 SSH 连接因长时间无操作被断开,比如防火墙/路由器超时。关闭 TCPKeepAlive 选项,让 SSH 连接完全由 ClientAliveInterval 机制管理,避免依赖内核 TCP 机制。

$ cat /etc/ssh/sshd_config
TCPKeepAlive no
ClientAliveInterval 120
ClientAliveCountMax 30

$ sudo systemctl restart sshd.service

客户端配置:如果使用 Windows 的桌面应用也可以在设置中进行配置,来保持 SSH 会话的长久保持。而且执行 ssh 命令的时候也可以使用 -o 参数指定对应配置。

$ ~/.ssh/config
Host *
ServerAliveInterval 120
ServerAliveCountMax 30

$ ssh -o ServerAliveInterval=30 root@host

保持SSH连接长时间存活


SSH 参考连接地址

送人玫瑰,手有余香。


文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !
  目录