把 SSH 端口从 22 改掉:能解决什么,不能解决什么
把 SSH 从 22 端口挪走能大幅降低攻击量,同时几乎不提供任何防护。如何在不把自己关在门外的前提下完成,包括大多数教程会漏掉的两个步骤。
诚实的结论
把 SSH 从 22 挪走,会让您的登录失败量在一夜之间下降大约 90%。它同时也不是一项安全控制措施,而把它当成安全措施,正是那些自以为「已经搞定了」的管理员把服务器丢掉的方式。
两句话都成立,因为它们回答的是不同的问题。量的下降是真实的、可测量的、有用的。而面对任何愿意花三十秒去看一眼的人,防护效果接近于零。
值得做吗?通常值得——作为降噪手段,与真正的防御并列,而绝不是取代它。
它确实能挡住什么
绝大部分 SSH 攻击流量来自非定向扫描器,它们只做一件事:在大片 IP 段上连接 22 端口,对任何应答的机器尝试凭据。它们不做端口扫描,因为在全网范围内检查一个端口,成本比检查 65535 个低好几个数量级,而 22 端口上的机器已经多到够它们忙。
换到 52200,您就彻底脱离了这个群体。曲线断崖式下跌,认证日志不再每隔几小时就轮转,在里面找到一条真实事件重新变得可能。
最后这一点常被低估。可读的日志在事故处置时价值真金白银,而每天三千条失败记录的时候,您手上并没有这样一份日志。
它挡不住什么
任何扫描全端口范围的人,几分钟内就能找到您。SSH 是明文自报家门的——版本 banner 是服务发送的第一样东西——所以一台遍历所有端口并读取 banner 的扫描器,第一次就能正确标注出您的服务。
Shodan 和 Censys 正是持续在做这件事,并把结果发布成可检索的索引。您那个非标准的 SSH 端口就在里面,任何人都能查到,而这只需要几天。
所以,面对非定向的机器人,改端口有效;面对专门选中您的人,它只让对方多花几分钟。而对于弱密码、泄露的密钥、未打补丁的 sshd,或同一主机上的脆弱应用,它什么也做不了。
此外还有一个实打实的副作用:冷门端口会弄坏一些东西。允许出站 22 的企业防火墙会拦下出站 52200,而您会从一位无法部署的同事那里得知这件事。
如何改端口而不把自己关在门外
有两个步骤是大多数教程会漏掉的,而在现代发行版上它们都会把您关在门外:RHEL 系上的 SELinux 端口标记,以及较新 Debian 和 Ubuntu 上的 systemd socket 激活——在那里 sshd 已经不再自己监听。
全程保持当前会话打开,并按顺序执行:
NEWPORT=52200
# 1. 先放行防火墙——在 sshd 挪动之前
sudo ufw allow ${NEWPORT}/tcp # 使用 ufw 的 Debian/Ubuntu
sudo firewall-cmd --permanent --add-port=${NEWPORT}/tcp && sudo firewall-cmd --reload # RHEL 系
# 2. SELinux:为端口打标记,否则 sshd 会拒绝绑定(RHEL 系)
sudo semanage port -a -t ssh_port_t -p tcp ${NEWPORT} || \
sudo semanage port -m -t ssh_port_t -p tcp ${NEWPORT}
# 3. 告诉 sshd。暂时保留 22——两个端口,确保您不会被切断
printf 'Port 22\nPort %s\n' "$NEWPORT" | sudo tee /etc/ssh/sshd_config.d/20-port.conf
sudo sshd -t # 任何重载之前先做语法检查
# 4. socket 激活:在较新的 Debian/Ubuntu 上 sshd 不会自己绑定
systemctl is-enabled ssh.socket 2>/dev/null && \
echo 'ssh.socket 已启用——需要在那里覆盖 ListenStream,见下方提示'
sudo systemctl reload ssh # RHEL 系为 'sshd'完成迁移
现在在第二个终端上用新端口验证——ssh -p 52200 user@server——然后再动其他任何东西。只有在这一步成功之后,才从配置中移除 Port 22、再次重载,并关闭旧的防火墙规则。
接着更新所有保存了旧端口的地方:~/.ssh/config 条目、部署脚本、CI runner、Ansible 清单、监控检查项、备份任务,以及团队文档。一次弄坏了夜间备份的端口变更,比不改端口更糟。
在确认新端口能从您网络之外访问之前,不要移除 22 端口。在局域网内两者都能用,而人们恰恰是这样说服自己「没问题」的。
该与什么搭配
改端口降低的是噪音。仍然需要有东西来处理那些抵达的尝试——而改完端口之后,抵达的尝试恰恰来自专门找您的人,也正是您真正需要在意的那部分。
SSH Protector 从 sshd 的有效配置中识别真实的 SSH 端口,而不是想当然认为是 22,因此已经迁移过的服务器无需任何配置即受保护,而且如果端口再次变更,规则会自动重建。
改端口,是为了拿到一份可读的日志。保留防御,是为了应对无论如何都会找到您的流量。
FAQ
- 该把 SSH 改到哪个端口?
- 1024 以上任何空闲端口都行——52200、47820,能用就行。低于 1024 的端口需要 root 权限才能绑定,这对 sshd 不是问题,但会限制选择。避开 2222,那是所有人在 22 之后第一个会试的;确定之前请用 ss -tlnp 确认没有程序在监听。
- 改了 sshd_config,SSH 为什么还在监听 22?
- 在 Ubuntu 22.10 及更新版本、Debian 12 及更新版本上,ssh.socket 可能处于启用状态,此时监听套接字归 systemd 所有,Port 指令会被忽略。用 systemctl is-enabled ssh.socket 检查;如果已启用,请在 socket 单元中覆盖 ListenStream——先写一行空的 ListenStream= 以清除继承来的默认值。
- 改 SSH 端口需要配置 SELinux 吗?
- 在 SELinux 处于 enforcing 的 RHEL、CentOS、AlmaLinux、Rocky 和 Fedora 上,需要——sshd 会拒绝绑定到未打标记的端口。请在重载之前运行 semanage port -a -t ssh_port_t -p tcp <端口>。跳过这一步是 RHEL 系上端口变更失败最常见的原因,而且它是在您已经重载之后才失败的。
- 非标准的 SSH 端口真的更安全吗?
- 与 22 端口完全一样安全,只是背景噪音少得多。端口不是访问控制手段:SSH 以明文发送版本 banner,任何全范围扫描器第一次就能识别出该服务,而 Shodan 会持续索引非标准 SSH 端口。安全性来自于「谁在处理这些尝试」,而不是「它们从哪里进来」。
