735 字
4 分钟
SSH断开服务即挂问题排查与解决

SSH 断开服务即挂问题排查#

装了个 CLIProxyAPI,SSH 连上去的时候服务好好的,一断开 SSH 就炸了。这个问题很典型,原因其实很简单。

问题现象#

  • SSH 登录时,服务运行正常
  • 关闭 SSH 后,服务停止
  • 再次 SSH 登录,服务又 “活” 了(其实是重启了)

根本原因#

查看安装脚本发现,它把服务安装为了 Systemd 用户服务 (User Service)

Terminal window
# 服务文件放在用户目录下
local systemd_dir="$HOME/.config/systemd/user"
# 使用 --user 参数管理
systemctl --user daemon-reload
systemctl --user start cliproxyapi.service

问题在于:systemd 用户实例绑定在用户会话上。SSH 登录时会启动用户实例,SSH 断开时会销毁该实例,连带杀掉所有用户服务。

Linux 默认行为就是 “人走茶凉”。

解决方案#

立即修复#

运行一条命令开启 “逗留模式 (Linger)”:

Terminal window
loginctl enable-linger $(whoami)
无需 sudo

这个命令不需要 root 权限,它会在 /var/lib/systemd/linger/ 下创建一个以用户名命名的空文件。

验证修复#

运行后断开 SSH,等几分钟再连上去检查:

Terminal window
systemctl --user status cliproxyapi

如果显示 active (running) 且运行时间超过你断开 SSH 的时长,说明成功了。

确保开机自启#

虽然 linger 是永久的,但还要确保服务本身设置了开机自启:

Terminal window
# 检查是否已启用
systemctl --user is-enabled cliproxyapi
# 如果没启用,执行
systemctl --user enable cliproxyapi

彻底根治(修改安装脚本)#

如果想让安装脚本自动处理这个问题,在 create_systemd_service 函数末尾加上:

Terminal window
create_systemd_service() {
# ... 原有代码 ...
systemctl --user daemon-reload
# 新增:开启 Linger 模式
if command -v loginctl >/dev/null 2>&1; then
log_info "Enabling linger for current user..."
loginctl enable-linger "$USER" || loginctl enable-linger "$(whoami)" || true
fi
log_success "Systemd service file created"
}

其他可能原因#

如果上面的方法无效,检查以下几点:

1. SSH 隧道误用#

如果你是通过 ssh -L 8080:localhost:8080 这种端口转发访问的服务,断开 SSH 后隧道自然消失。这不是服务挂了,是访问路径断了。

解决: 让服务监听 0.0.0.0 而不是 127.0.0.1,直接通过服务器IP访问。

2. 服务绑定在 Localhost#

检查服务配置,确保监听地址是 0.0.0.0

# 错误
listen: 127.0.0.1:8080
# 正确
listen: 0.0.0.0:8080

3. StandardOutput 配置错误#

检查服务文件,确保没有奇怪的 TTY 绑定:

[Service]
# 错误示例
StandardOutput=tty
# 正确配置
StandardOutput=journal

排查命令速查#

Terminal window
# 查看服务状态
systemctl --user status 服务名
# 查看日志
journalctl --user -u 服务名 -e
# 查看 linger 状态
ls /var/lib/systemd/linger/
# 查看当前用户实例
loginctl show-user $(whoami)
# 列出所有用户服务
systemctl --user list-units --type=service

总结#

问题解决
SSH 断开服务停止loginctl enable-linger 用户名
重启后不自动启动systemctl --user enable 服务名
外部无法访问检查监听地址是否为 0.0.0.0
SSH 隧道断开直接访问服务器IP而非 localhost

参考链接#

SSH断开服务即挂问题排查与解决
https://im.awsl.app/posts/system-ops/038-ssh-disconnect-fix/
作者
uu
发布于
2026-01-22
许可协议
CC0 1.0