把 SSH 从默认的 22 端口改到别的端口,是很多运维教程里的第一条"加固建议"。它确实有用,能挡掉大量无差别扫描和自动爆破,日志会清净很多。但它也是新手最容易把自己锁在门外的操作:改完配置一重启,新端口连不上,旧连接一断,就只能去机房或者求救控制台。
这篇文章给出 RHEL、Rocky、CentOS 与 Debian、Ubuntu 两套完整步骤,覆盖 SELinux 的 semanage port 处理、firewalld 与 ufw 的放行、验证清单和回滚方案。核心原则只有一条:在确认新端口能成功登录之前,绝不关闭当前的连接。全文的操作都围绕这个原则设计。
先搞清楚改端口能解决什么
改端口的真实作用是减少噪音,而不是提升安全性。互联网上大量自动化脚本只扫 22 端口,换到高位端口后,日志里的失败登录从每天几千条降到接近零,这让真正的异常更容易被发现。有运维经验的人会注意到,改端口后日志信噪比的提升,往往比省下的那点 CPU 更有价值。
但它不能防住针对性攻击。攻击者只要做一次全端口扫描,就能发现你的 SSH 端口;端口扫描对现代工具来说成本极低。所以它属于"减少暴露"的低成本措施,不能替代密钥登录、禁止 root 登录、限制来源 IP、fail2ban 这些真正的加固手段。把改端口当成安全的全部,是危险的误解。
| 措施 | 作用 | 是否依赖改端口 |
|---|---|---|
| 改默认端口 | 减少无差别扫描和日志噪音 | — |
| 禁用密码、只用密钥 | 防爆破,效果显著 | 否 |
| 禁止 root 直接登录 | 降低被攻破后的危害 | 否 |
fail2ban |
自动封禁爆破来源 | 否 |
| 防火墙限制来源 IP | 只放行可信出口,效果最强 | 否 |
| 改端口 | 低成本,见效快 | — |
结论是:改端口值得做,但它是组合拳里的一招,不是全部。如果条件允许,限制来源 IP 配合密钥登录的效果远好于单纯改端口。
操作前的三项准备
第一,保留一个已登录的会话。 如果你现在有 SSH 连接,这个窗口在整个操作过程中都不要关。所有验证都在另外开的新窗口里做。这是唯一的保险。
第二,确认带外通道可用。 主流云厂商控制台提供 VNC 或串口终端,它不经过网络,是最后的安全网。动手前先登录一次确认能用,并确认密码或密钥可用。没有带外通道时,风险显著上升,建议改在业务低峰且有应急联系人时操作。
第三,备份配置并记录现状。
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak.$(date +%F-%H%M)
sudo ls -l /etc/ssh/sshd_config*
sudo sshd -T | grep -i '^port'
sudo ss -lntp | grep sshd
记录当前实际监听的端口和配置文件路径,出错时才能快速还原。同时注意 Debian、Ubuntu 的服务名是 ssh,RHEL、Rocky、CentOS 是 sshd,两者不要混用。
另外提一句,Ubuntu 较新版本启用了 socket 激活(systemd socket activation),端口可能由 /lib/systemd/system/ssh.socket 控制,只改 sshd_config 不生效。检查方法:
systemctl status ssh.socket 2>/dev/null
grep -i port /lib/systemd/system/ssh.socket 2>/dev/null
如果 ssh.socket 处于激活状态,需要同时修改 socket 文件里的 ListenStream 并执行 systemctl daemon-reload,否则改完配置后服务仍监听旧端口。这是很多人踩过的坑。
选择端口号
建议选择一万到六万之间、不与其他服务冲突的端口,避开常见服务端口。可以先看看本机已经用了哪些端口,避免撞车:
sudo ss -lntu | awk '{print $5}' | grep -oP ':\K[0-9]+$' | sort -n | uniq
选一个没出现的高位端口,例如 2222 或 58222。注意 2222 虽然常见,但也在自动扫描的常见列表里,若追求更低噪音可选更冷门的数值。无论选哪个,都要确认它不是知名服务端口,可查 /etc/services。
完整操作步骤
以下步骤请按顺序执行,每一步都不要跳过验证。
第一步,备份并编辑配置文件。
sudo cp -a /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo vi /etc/ssh/sshd_config
找到 Port 那一行。默认它可能被注释掉:
#Port 22
建议的做法是先同时保留两个端口,等新端口验证通过后再移除旧的:
Port 22
Port 2222
sshd 支持多行 Port,会同时监听所有列出的端口。这种"双端口过渡"的方式是风险最低的做法,强烈推荐。如果你一定要一步到位,就只写新端口,但务必保证后续验证环节做到位。
第二步,校验配置语法。
sudo sshd -t && echo "语法正常"
这条命令不会启动服务,只做语法检查。如果报错,会给出文件名和行号。语法不通过时绝对不要重启服务。
第三步,处理 SELinux(仅 RHEL 系需要)。
这是 RHEL、Rocky、CentOS 上最容易被忽略、也最容易导致失败的一步。SELinux 默认只允许 sshd 绑定少数几个端口,直接改成新端口后,服务会启动失败并报 Bind to port 2222 failed: Permission denied。
先确认 SELinux 状态:
getenforce
sestatus
如果是 Enforcing 或 Permissive,都需要登记端口:
# 安装管理工具
sudo dnf install -y policycoreutils-python-utils
# 查看当前 ssh 允许的端口
sudo semanage port -l | grep ssh
# 登记新端口
sudo semanage port -a -t ssh_port_t -p tcp 2222
# 再次确认
sudo semanage port -l | grep ssh
如果提示端口已存在,用 -m 修改而不是 -a 添加:
sudo semanage port -m -t ssh_port_t -p tcp 2222
Debian、Ubuntu 默认使用 AppArmor 而非 SELinux,不需要这一步。
第四步,放行防火墙。
# RHEL、Rocky、CentOS(firewalld)
sudo firewall-cmd --permanent --add-port=2222/tcp
sudo firewall-cmd --reload
sudo firewall-cmd --list-ports
# Debian、Ubuntu(ufw)
sudo ufw allow 2222/tcp
sudo ufw reload
sudo ufw status verbose
云服务器还要在控制台的安全组中放行该端口的入方向,这一步经常漏,导致系统防火墙全对但依然连不上。安全组是云平台侧的访问控制,优先级在系统防火墙之前,两者都要通。
第五步,重启服务。
# RHEL、Rocky、CentOS
sudo systemctl restart sshd
# Debian、Ubuntu
sudo systemctl restart ssh
如果之前启用了 socket 激活的 Ubuntu,需要先停用 socket:
sudo systemctl disable --now ssh.socket
sudo systemctl enable --now ssh.service
sudo systemctl daemon-reload
sudo systemctl restart ssh
第六步,确认监听已生效。
sudo ss -lntp | grep sshd
sudo sshd -T | grep -i '^port'
sudo systemctl status sshd --no-pager
必须看到新端口出现在监听列表里,才能进行下一步。
验证新端口(关键一步)
另开一个终端窗口,不要关掉原来的连接,用新端口测试连接:
ssh -p 2222 user@server_ip
如果登录成功,再检查这些细节:
# 确认登录方式正确
ssh -p 2222 user@server_ip 'echo 登录正常; hostname; whoami'
# 确认 scp、sftp 也能用
scp -P 2222 ./test.txt user@server_ip:/tmp/
注意 scp 用大写 -P 指定端口,ssh 用小写 -p,这是个常见的小坑。
如果新端口连不上,立刻回到原连接排查,不要断开。常见原因按顺序查:
sudo ss -lntp | grep sshd # 服务是否真的在听新端口
sudo journalctl -u sshd -n 50 --no-pager # 启动日志有无报错
sudo firewall-cmd --list-ports # 防火墙是否放行
sudo semanage port -l | grep ssh # SELinux 是否登记
nc -vz -w 3 server_ip 2222 # 从外部看端口是否可达
从外部用 nc 测试很重要,它能区分"本机监听正常但外部不通"(安全组或防火墙)和"本机根本没监听"(服务或配置问题)。
只有新端口确认可用之后,才回到配置文件删除旧的 22 端口,然后再次重启服务并验证:
sudo vi /etc/ssh/sshd_config # 删除 Port 22 那一行
sudo sshd -t
sudo systemctl restart sshd
sudo ss -lntp | grep sshd
此时仍然不要断开当前连接,再用一个新窗口连一次,成功后才能放心断开旧会话。
回滚方法
任何时候新端口不可用,立即回滚。回滚的前提是你还留着那个旧连接。
方案一:直接还原配置文件。
sudo cp -a /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
sudo sshd -t
sudo systemctl restart sshd
sudo ss -lntp | grep sshd
方案二:改回 22 端口。 如果备份文件丢失,手工编辑配置,把 Port 改回 22,再重启。
方案三:SELinux 登记回滚。
sudo semanage port -d -t ssh_port_t -p tcp 2222
方案四:带外通道修复。 如果已经断开且无法连接,只能通过云控制台的 VNC 或串口终端登录,按上述步骤还原。所以前面强调的"保留会话 + 确认带外通道"不是形式主义,是真正的保命措施。
风险提示: 不要在改端口的同时修改其他 SSH 参数(比如同时禁用密码登录、禁止 root 登录、限制来源 IP)。一次只改一处,出问题才好定位。多项加固分开做,每次验证通过再继续。
顺手完成的配套加固
新端口稳定后,可以考虑在同一个配置文件里完成其余加固,但建议逐项修改、逐项验证。
# /etc/ssh/sshd_config
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
PermitEmptyPasswords no
MaxAuthTries 3
LoginGraceTime 30
ClientAliveInterval 300
ClientAliveCountMax 2
AllowUsers ops
每项的含义:禁止 root 直接登录需要你先有可用的普通用户和 sudo 权限;禁用密码登录必须先确认密钥登录已验证可用;AllowUsers 一旦启用,名单外用户会被拒绝,务必把自己列进去。
改完同样要 sshd -t 校验,并在新窗口验证成功后才断开旧连接。这个流程适用于所有 SSH 配置变更,不只是改端口。
常见问题
改完端口服务起不来,sshd -t 也没报错,为什么?
大概率是 SELinux 没登记新端口。看 journalctl -u sshd 里有没有 Permission denied 或 Failed to bind。用 semanage port -a -t ssh_port_t -p tcp 新端口 登记后重启。临时验证可以用 setenforce 0 关闭 SELinux 再试,确认是这个原因后记得恢复为 Enforcing。
为什么本机 ss -lntp 能看到端口,外面还是连不上?
从外到内依次是云安全组、系统防火墙、服务监听。本机看到监听只说明第三层正常。用 nc -vz -w 3 你的公网IP 端口 从另一台机器测试,同时检查控制台安全组的入方向规则。
同时保留 22 和新端口会不安全吗?
短期过渡是安全的,而且推荐这么做。真正的风险是忘记收尾,长期留着 22。建议在新端口验证通过后立刻移除旧端口,并在日历上做个标记。
Ubuntu 改完配置端口没变怎么办?
新版本 Ubuntu 可能启用了 ssh.socket,端口由 socket 单元控制。检查 systemctl status ssh.socket,停用 socket 并启用 service,或者同时修改 socket 文件里的 ListenStream 后 systemctl daemon-reload。
能不能用防火墙做端口转发,不用改 sshd 配置?
可以,用 firewall-cmd --add-forward-port 或 iptables 的 NAT 规则把外部端口转发到内部 22。这样 sshd 不用改,回滚简单。但它只是把暴露点换了个位置,安全性提升有限,且多一层故障点,一般不作为首选。
总结
- 改端口前必须保留现有会话、确认带外通道可用、备份配置文件,三者缺一不可。
- 采用"双端口过渡"策略:先让 sshd 同时监听 22 和新端口,验证通过后再移除旧端口。
- RHEL 系必须执行
semanage port -a -t ssh_port_t -p tcp 新端口,否则服务会因 SELinux 拒绝绑定而启动失败。 - firewalld、ufw 与云安全组三层都要放行,验证时用外部
nc测试,能快速区分是服务问题还是访问控制问题。 - 新端口连续验证成功(登录、scp、重启后自启都正常)之前,绝对不要断开旧连接;改端口只是降噪手段,真正的加固是密钥登录、禁 root、限来源和
fail2ban。
企业QQ咨询




