改了SSH端口,退出重连,然后就没有然后了——连接超时,服务器进不去,业务全停,人在机房外面,心在服务器里面。这应该是Linux运维里最让人血压飙升的场景之一。这种事情几乎每个运维都遇到过。改SSH端口本意是提高安全性、减少暴力破解扫描,结果防火墙没放行、SELinux没调、或者干脆配置文件写错了,导致自己把自己关在门外。更尴尬的是,很多云服务器连VNC或者带外管理都没有,一旦SSH断了,连恢复的入口都没有。
两种情况:有VNC/IPMI等带外管理怎么救,纯远程无带外管理怎么救。命令复制粘贴就能用,但建议你先看懂再操作。
先别慌,搞清楚是什么原因。在动手恢复之前,先判断一下连不上的具体原因。这决定了你用哪种方式恢复,也决定了修复的优先级。
SSH连不上的报错主要有这几种:
Connection timed out(连接超时):最常见的情况。SSH服务本身是正常启动的,但是网络层面过不去。大概率是防火墙没放行新端口,或者云安全组没加规则。这种属于网络层阻断,TCP握手都没完成。
Connection refused(连接被拒绝):端口是通的,但是SSH服务没在监听这个端口。可能配置文件里的端口号写错了,或者SSH服务压根没起来。这种属于应用层问题,端口没打开。
Connection reset(连接重置):端口能通,SSH服务也在,但是协议握手阶段出了问题。一般跟加密算法、密钥认证配置有关,或者SELinux拦截了。
Permission denied(权限拒绝):能连上SSH,但认证失败。这种情况跟端口没关系,是账号密码或密钥的问题,不在本文讨论范围内。
对于修改端口导致的问题,前两种占九成以上。搞清楚报错类型,恢复的时候更有针对性。
方案一:有带外管理(VNC/IPMI/iDRAC)
这是最理想的恢复方式。只要你能通过云控制台的VNC或者物理服务器的IPMI/KVM连接到服务器的控制台,就等于有了一张物理键盘和屏幕。哪怕SSH服务完全挂了,你都能像坐在服务器面前一样操作。
步骤1:通过VNC/KVM登录控制台
登录云服务商的控制台,找到“远程连接”或“VNC”入口。阿里云叫“管理终端”,腾讯云叫“VNC登录”,AWS叫“EC2 Instance Connect”配合串口控制台。只要能敲命令,就进入了恢复流程。
连上之后,用root账号或者有sudo权限的用户登录。
步骤2:检查SSH服务状态和端口监听
systemctl status sshd
看服务状态是active还是failed。如果是failed,查看错误日志:
journalctl -u sshd -n 20
然后检查端口监听情况,确认sshd实际在监听哪个端口:
ss -tlnp | grep sshd
# 或者
netstat -tlnp | grep sshd
如果看到 0.0.0.0:2222 或者类似的新端口,说明配置其实是生效的,只是你之前连的是22,防火墙没开新端口。如果看到 0.0.0.0:22,说明修改没生效,配置文件可能写错了。
步骤3:检查并修复防火墙
这是修改端口后连不上的头号元凶。VNC进去之后,执行:
iptables -L -n -v | grep 你的新端口
如果没有任何输出,说明防火墙压根没放行这个端口。执行添加规则:
iptables -I INPUT -p tcp --dport 你的新端口 -j ACCEPT
然后保存规则,不同发行版保存命令不同:
# CentOS 7/8 用firewalld的话
firewall-cmd --add-port=新端口/tcp --permanent
firewall-cmd --reload
# 或者直接用iptables-save(看你的系统用哪个服务)
service iptables save
# Ubuntu/Debian用ufw的话
ufw allow 新端口/tcp
如果用的是云服务商的安全组,VNC里面改不了,需要去云控制台网页上操作。这个后面细说。
步骤4:检查SELinux
如果你用的是CentOS/RHEL系列,SELinux可能会阻止sshd绑定非标准端口。
查看SELinux状态:
getenforce
如果返回Enforcing,检查SELinux是否允许sshd使用新端口:
semanage port -l | grep ssh
正常情况下会看到 ssh_port_t 关联的是22端口。新端口不在列表里的话,添加授权:
semanage port -a -t ssh_port_t -p tcp 你的新端口
如果semanage命令找不到,先安装 policycoreutils-python 包。
不想折腾SELinux的话,临时关闭测试:
setenforce 0
如果能连上了,说明确实是SELinux的问题。永久解决就是用semanage命令添加端口,不建议永久关闭SELinux。
步骤5:验证新端口能通
VNC里确认服务监听、防火墙放行、SELinux没问题之后,在VNC控制台里用localhost测试一下:
ssh -p 新端口 root@127.0.0.1
这个测试走的是本地回环,不经过外网防火墙。如果能连上,说明sshd本身配置正确。如果本地都连不上,那就是sshd配置有问题。
方案二:纯远程无带外管理
如果你买的是廉价VPS,没有VNC,没有IPMI,连控制台都没给,唯一的入口就是SSH本身。这时候把自己锁在外面了,常规手段完全没法恢复。但也不是完全没救,以下几种方式能帮你从门外翻进去。
救援模式 / 恢复模式
大部分主流云服务商都提供“救援模式”或“恢复模式”,英文叫Rescue Mode或Recovery Mode。
操作逻辑是这样的:
1.在云控制台把服务器关机。
2.在控制台里选择“进入救援模式”或“从ISO引导”之类的选项。
3.启动后会进入一个临时的Linux环境(通常是基于内存的系统),你原来的系统盘会被挂载到一个目录下,比如 /mnt。
4.在这个临时环境里,挂载原来的系统盘,chroot进去,然后修改SSH配置或防火墙。
# 先看一下原来的系统盘是哪个设备
fdisk -l
# 一般是 /dev/sda1 或 /dev/vda1,挂载它
mkdir /mnt/root
mount /dev/vda1 /mnt/root
# 如果/boot独立分区或者有其他子分区也要挂载
mount --bind /dev /mnt/root/dev
mount --bind /proc /mnt/root/proc
mount --bind /sys /mnt/root/sys
# chroot进去
chroot /mnt/root /bin/bash
进到chroot环境之后,你就有了完整的操作权限,可以修改sshd_config、调整防火墙、关闭SELinux,然后退出chroot,重启服务器,用新端口重新连接。
云服务商的控制台“执行命令”功能
用法很简单:在网页控制台选择“执行命令”或“远程命令”,输入以下内容:
#!/bin/bash
# 恢复SSH端口到22
sed -i 's/^Port .*/Port 22/' /etc/ssh/sshd_config
systemctl restart sshd
或者临时添加防火墙放行规则:
#!/bin/bash
iptables -I INPUT -p tcp --dport 新端口 -j ACCEPT
命令执行完,再用新端口尝试连接。这个方式比救援模式更快,不需要关机重启,适合紧急恢复。
快照/镜像回滚
如果你的服务商支持创建快照或自定义镜像,而且你在修改端口之前刚好拍了快照,那直接回滚到快照时间点是最快的恢复方式。但代价是会丢失快照之后产生的数据,不到万不得已不建议用。
端口改完了,怎么避免下次再翻车?
聊完恢复方案,顺便说说怎么改SSH端口才能避免把自己关外面。养成这个习惯,以后基本不会遇到上面说的那些紧急情况。
第一步:不要直接改配置文件
先添加新端口监听,保留22端口:
# 在 /etc/ssh/sshd_config 里,增加一行
Port 22
Port 新端口
第二步:测试新端口
另外开一个SSH会话,用新端口连接。连上之后确认一切正常,比如 ls 能正常执行、sudo能用。
第三步:确认新端口稳定运行几天
等新端口稳定跑个两三天,确认没有任何问题,再回过头去注释掉 Port 22 这一行,彻底关闭22端口。
第四步:防火墙先配置再重启
对于firewalld或ufw,先添加新端口的放行规则,再reload防火墙,而不是先reload再加规则。如果顺序搞反了,你就把自己封在外面了。
对于云安全组,规则修改是实时生效的。务必在修改sshd_config之前,先把安全组里加上新端口的入方向规则。这个顺序极其重要,因为安全组一旦没放行,你SSH改完端口退出的那一刻就失联了。
第五步:改配置后重载而不是重启
修改sshd_config之后,用 systemctl reload sshd 而不是 restart。reload会平滑加载新配置,不会中断现有的SSH会话。万一配置写错了,当前会话还在,你可以再改回来。如果用的是 restart,所有会话会被强制断开,配置写错的话直接失联。
总结:修改SSH端口本身是个好习惯,能显著减少被暴力破解的骚扰。但凡事都有代价,端口改完把自己锁外面就是代价之一。按上面说的四步流程来操作,翻车的概率接近于零。万一真的翻车了,上面两种方案总有一款能把你救回来。
相关内容
