小服务器的 SSH 加固:我实际在用的几项设置

2026-06-20 · 安全

新开一台 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 和密码认证、用户白名单这三项,已经能挡住绝大多数自动化攻击。剩下的精力,不如放在及时更新系统和做好备份上。