理解 SSH 改端口不生效的问题及解决方案


问题表现

  • 修改 /etc/ssh/sshd_config 中的 Port 例如 Port 3212
  • 重启 SSH 服务:sudo systemctl restart sshd
  • 使用 sudo ss -tnlp | grep sshd 发现 SSH 依然监听 22 端口。
  • 服务器上存在 ssh.socket 单元,systemctl status ssh.socket 显示该服务处于活跃状态。

根本原因

现代 systemd 系统采用了 socket 激活机制(socket activation) 来管理 SSH 服务。具体来说:

  • ssh.socket 单元会提前监听 TCP 端口(默认 22),而不是由 sshd 自己监听。
  • 当有连接请求时,systemd 触发启动 sshd 进程来处理连接。
  • 这样即使你修改了 sshd 的配置文件,ssh.socket 仍然在监听默认的 22 端口,导致端口修改无效。

ssh.socket 的优点

  • 按需启动 sshd,节省系统资源。
  • 快速响应连接请求。
  • 方便 systemd 集中管理和日志审计。
  • 提升服务稳定性和自动恢复能力。

解决方案

方法一:禁用 ssh.socket,使用传统 sshd 监听端口

1
2
3
sudo systemctl disable ssh.socket
sudo systemctl stop ssh.socket
sudo systemctl restart ssh.service

方法二:修改 ssh.socket 配置监听新端口

  • 编辑 ssh.socket 文件(路径一般为 /usr/lib/systemd/system/ssh.socket 或 /etc/systemd/system/ssh.socket)。
  • 修改 [Socket] 部分的 ListenStream=22 为你想要的端口,比如 ListenStream=3212。
  • 重新加载 systemd 配置:
1
2
3
sudo systemctl daemon-reload
sudo systemctl restart ssh.socket
sudo systemctl restart ssh.service

额外提示

  • 使用 ssh.socket 是 systemd 的现代管理方式,适合资源有限或连接不频繁的服务器。
  • 直接禁用 ssh.socket 更适合需要自定义 SSH 端口的场景,操作更简单。
  • 修改端口后,别忘了开放防火墙相应端口。