SSH安全加固实战:从密钥登录到fail2ban防爆破


导读:每一台暴露公网的VPS,22端口每天都在被扫描和爆破。本站之前的文章都在讲怎么把服务跑起来,这篇讲怎么把门锁好:换密钥登录、关密码认证、用fail2ban自动封禁爆破IP、再辅以端口改造和安全组白名单。全程给出可直接照抄的配置,也把"改配置把自己锁在门外"的经典翻车现场提前拆解。读完这篇,你的SSH将从"默认裸奔"变成"有审计、有自动反击的堡垒"。

一、先看风险面:你的22端口正在被打

不信邪的可以先看两眼日志:

lastb | head -20
lastb | wc -l

lastb读的是/var/log/btmp,记录的全是失败的登录尝试。一台新开几天的VPS,这里通常已经有成千上万条记录,用户名从root、admin到oracle、test无所不有——全是字典爆破脚本在敲门。再看实时战场:

journalctl -u ssh -n 50 --no-pager
grep 'Failed password' /var/log/auth.log | wc -l

Debian系用auth.log,RHEL系是/var/log/secure,内容大同小异。看完这两条命令的输出,你对"SSH加固不是可选项"这件事不会再有疑问。

二、第一步:换密钥登录,告别密码

密码的问题不是不够长,是它总在被猜。密钥登录把"证明你是你"从"猜对一个字符串"变成"持有私钥文件",爆破直接失效。本机生成一对密钥:

ssh-keygen -t ed25519 -C "vps-admin"

一路回车即可,passphrase可留空也可设置——设置的话私钥被盗也无法直接使用,代价是每次用要输一次口令。然后把公钥装到服务器上:

ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10

没有ssh-copy-id的Windows环境,手工等价操作是往服务器的/root/.ssh/authorized_keys里追加公钥内容。三个权限是硬性要求,权限不对sshd会直接忽略你的密钥:

chmod 700 /root/.ssh
chmod 600 /root/.ssh/authorized_keys

此时先别退出当前会话,新开一个终端验证:能免密码登进去,才进行下一步。这条"保留旧会话、新开终端验证"的纪律,贯穿整个SSH加固过程。

三、关闭密码登录的正确顺序

确认密钥登录可用后,编辑/etc/ssh/sshd_config:

PermitRootLogin prohibit-password
PasswordAuthentication no

prohibit-password的意思是root还能登录,但只允许密钥方式;如果你想彻底禁掉root直连,用no并另外建一个普通用户加sudo。改完先做语法检查再重载:

sshd -t
systemctl reload sshd

reload不断开现有连接,比restart温和。这里有个新手高频翻车点:云镜像里Ubuntu的配置可能被/etc/ssh/sshd_config.d/目录下的片段覆盖,你在主配置里改了PasswordAuthentication no,结果50-cloud-init.conf里一句yes又给你改回去了。排查方法:

sshd -T | grep -i password

sshd -T输出的是最终生效的完整配置,以它为准,不要以文件里的文字为准。

四、改端口:聊胜于无的偏方

把Port 22改成Port 22xxx,能躲开绝大多数无差别扫描脚本,代价是每次连接要多敲几个字符。属于"防脚本不防黑客"的措施,值不值得做见仁见智。要做的话记住三件事:改完sshd -T | grep port确认生效;防火墙和安全组里放行新端口——云厂商安全组不放行,改完端口当场失联;SELinux系统(RHEL系)还要semanage port -a -t ssh_port_t -p tcp 22xxx授权。改端口和关密码两件事,永远分开两次做,不要一次改两个变量。

五、fail2ban:让爆破IP自动进小黑屋

端口改了,盯着的扫描器还是会有。fail2ban监控SSH日志,同一IP在时间窗口内失败次数超限,就调用防火墙把它封掉。安装:

apt install fail2ban

Debian系建议新建/etc/fail2ban/jail.local覆盖默认值,不要直接改jail.conf——升级时会被覆盖:

[sshd]
enabled = true
port = 22
maxretry = 5
findtime = 600
bantime = 3600

这组参数的含义:10分钟内失败5次的IP,封禁1小时。想狠一点,bantime改成86400或者-1(永久)。启动并设开机自启:

systemctl enable --now fail2ban

日常用两条命令巡检:fail2ban-client status sshd看当前被封的IP列表和累计攻击次数,fail2ban-client set sshd unbanip 1.2.3.4解封误伤的自己人。你的办公室IP被误封是这个小工具最常见的事故,解封命令记牢。

六、再加一道锁:安全组白名单

云厂商的安全组/防火墙是VPS外面的一层闸门,连操作系统都摸不到,自然也没有被绕过的可能。最实用的玩法是白名单模式:22端口只放行你的固定出口IP。家用宽带IP会变的同学,退一步可以只放行你所在城市的运营商段,或者配合WireGuard类组网方案——SSH只监听内网地址,先入网再登机器。本站后续的网络篇会展开组网方案,这里先记住原则:网络层的访问控制永远优先于应用层的认证,能不给全世界看的端口,就不要给全世界看。

七、日常巡检:怎么知道有没有人敲门

加固完成不等于一劳永逸,养成三条习惯:每周看一眼lastb的量级,突增说明被针对性盯上;fail2ban-client status sshd里的Total failed数字持续上涨属于正常背景噪音,但"当前封禁列表"里出现同一网段大量IP,值得把整个网段拉黑;定期复查sshd -T的关键项,防止某次手滑或某个自动化脚本把配置改回去。把这三条塞进本站cron篇讲过的定时任务里,每周生成一份巡检报告发到邮箱,SSH安全就从"一次性工程"变成了"持续运营"。

八、常见翻车现场与自救

翻车一号:改配置后退出会话,发现密钥登不上、密码也登不上。自救路径:云厂商控制台的VNC/串口终端不依赖SSH,登进去改回配置即可。这就是为什么云控制台凭证要保管好——它是最后的救命通道。翻车二号:fail2ban把自己的IP封了。用VNC进去执行解封命令。翻车三号:改了端口忘了放行安全组。同样走VNC。规律很清晰:所有SSH层的锁死,最后都靠带外通道救回来。动手前确认VNC可用,是比任何配置参数都重要的前置检查。

结语

SSH加固的完整链路是:密钥登录解决"不被猜中",关闭密码解决"字典失效",fail2ban解决"自动反击",安全组白名单解决"根本不给机会",VNC带外通道解决"自己翻车也能回来"。五层措施各管一段,凑成一个闭环。配合本站systemd篇和cron篇的习惯,把巡检自动化,你的VPS在扫描器眼里就是一块难啃又无趣的骨头——多数攻击者会直接去啃下一台。


手机扫码阅读

微信或手机浏览器扫一扫,随时随地随心阅读与分享

VPS网络加速实录:开启BBR拥塞控制的正确姿势

Docker镜像获取全攻略:加速、离线迁移、自建Registry一条龙

评 论
更换验证码