小服务器的 SSH 加固:我实际在用的几项设置
新开一台 VPS,不到一个小时,/var/log/auth.log 里就会出现大量来自陌生 IP 的登录尝试。这些大多是自动化扫描,用的是弱口令字典,只要基础配置做好,基本构不成威胁。
网上的 SSH 加固清单往往很长,有些项目对小服务器来说意义不大,反而增加了维护成本。下面只列我在自己几台机器上长期使用的设置,按重要程度排序。
第一步:先确保密钥能登录
后面的修改会关闭密码登录,所以在动配置之前,必须先确认密钥登录是正常的。在本地生成密钥并上传:
$ ssh-keygen -t ed25519 -C "laptop-2026"
$ ssh-copy-id deploy@your-server
然后新开一个终端用密钥登录一次,确认不需要输入服务器密码。原来那个会话先不要关,万一后面配置出错,它就是你的退路。
第二步:修改 sshd 配置
较新的发行版支持在 /etc/ssh/sshd_config.d/ 下放置独立的配置文件,这样升级系统时不会和默认配置冲突。新建 /etc/ssh/sshd_config.d/10-hardening.conf:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
AllowUsers deploy
MaxAuthTries 3
LoginGraceTime 30
X11Forwarding no
逐条解释一下:
PermitRootLogin no:禁止 root 直接登录,需要管理权限时用普通用户加sudo。PasswordAuthentication no和KbdInteractiveAuthentication no:彻底关闭密码类认证。只关前者是不够的,后者在某些配置下仍然允许输入密码。AllowUsers:白名单,只有列出的用户可以通过 SSH 登录。即使系统里因为装软件多出了别的用户,也不会成为入口。MaxAuthTries和LoginGraceTime:减少单个连接可以尝试的次数和占用时间。
改完后先检查语法,再重新加载:
$ sudo sshd -t
$ sudo systemctl reload ssh
sshd -t 没有任何输出就说明配置没问题。重新加载不会断开已有的连接。再开一个新终端测试登录,确认一切正常后,才关掉之前保留的会话。
第三步:限制暴力尝试
关闭密码登录后,暴力破解已经不可能成功,但大量无效连接仍然会刷满日志。我用 fail2ban 做简单的封禁:
$ sudo apt install fail2ban
新建 /etc/fail2ban/jail.d/sshd.local:
[sshd]
enabled = true
backend = systemd
maxretry = 5
findtime = 10m
bantime = 1h
十分钟内失败五次就封禁一小时。重启 fail2ban 后,可以用 sudo fail2ban-client status sshd 查看当前被封的地址。
关于改端口
把 SSH 改到非 22 端口,确实能让日志安静很多,但它不是真正的安全措施,只是减少了噪音。我的做法是:如果机器有云厂商的安全组,就在安全组里限制 22 端口只对自己常用的 IP 开放,效果比改端口好得多;如果没有这个条件,改端口加 fail2ban 也足够了。
小结
对一台个人服务器来说,密钥登录、禁用 root 和密码认证、用户白名单这三项,已经能挡住绝大多数自动化攻击。剩下的精力,不如放在及时更新系统和做好备份上。