本系列:SSH 安全加固实战(共 5 篇) ① 为什么你的 SSH 正在裸奔 → ② 先读懂配置文件再动手 → ③ 用密钥认证告别密码 → ④ 限制谁能登录、从哪里登录 → ⑤ 防暴力破解与安全审计(本篇,终篇)
前四篇把"门"层层收窄:密钥认证堵死了密码爆破,白名单与防火墙限制谁能进、从哪进。最后一篇做主动拦截和持续运维——用 fail2ban 自动封禁恶意来源、看懂日志做审计,最后给出一份贯穿全系列的自测清单,让你能一键检查自己到底加固到几成。
用 fail2ban 自动封禁爆破来源
fail2ban 会监控登录日志,一旦某个 IP 短时间内连续失败多次,就自动调用防火墙把它封掉一段时间。这是对"扫描爆破"最直接的反制。
安装
# Debian / Ubuntu
sudo apt update && sudo apt install -y fail2ban
# RHEL / CentOS / Rocky
sudo yum install -y fail2ban # 或用 dnf
配置
fail2ban 的主配置是 /etc/fail2ban/jail.conf,但我们不要改它,而是新建本地覆盖文件,避免升级被覆盖:
sudo cp /etc/fail2ban/jail.local /etc/fail2ban/jail.local 2>/dev/null
# 若上面报错说明文件不存在,直接新建:
sudo vim /etc/fail2ban/jail.local
写入最小可用配置,为 SSH 开启默认 jail:
[DEFAULT]
bantime = 1h # 封禁时长,可写成 10m / 1h / 1d
findtime = 10m # 统计窗口
maxretry = 5 # 窗口内失败 5 次即封禁
[sshd]
enabled = true
backend = systemd # 用 systemd 日志;传统 syslog 发行版可省去或改 auto
提示框:
backend = systemd适用于使用 journald 的较新发行版(Ubuntu 18.04+、RHEL 7+)。老系统(纯 syslog)通常不写这行或设为auto让 fail2ban 自动判断。拿不准就删掉该行用默认。
启用并查看状态:
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
status 输出的 Banned IP list 若出现 IP,说明 fail2ban 已开始工作。可以用下面命令手动解除误封的 IP:
sudo fail2ban-client set sshd unbanip 你的IP
提示框:别把自己封了。 若你在用 fail2ban 的同时又频繁输错密码、或防火墙白名单没覆盖自己,容易误封。封了也别慌:多数云控制台可"重开实例"或通过带外 VNC 登录后
fail2ban-client set sshd unbanip解封。生产上建议先把自己的固定 IP 加入白名单(fail2ban 的ignoreip)再启用。
在 jail.local 的 [DEFAULT] 段加:
ignoreip = 127.0.0.1/8 ::1 你的固定IP
日志审计:看清攻击长什么样
加固不是设完就完,要会"看日志"判断是否仍在被攻击、有没有异常登录。
查看失败登录(爆破痕迹):
# Debian / Ubuntu
sudo grep 'Failed password' /var/log/auth.log | tail -30
# RHEL / CentOS / Rocky
sudo grep 'Failed password' /var/log/secure | tail -30
# 使用 systemd 的发行版通用写法
sudo journalctl -u ssh -u sshd --since "1 hour ago" | grep -iE 'failed|invalid|break-in'
看成功登录(谁在登、从哪登):
sudo grep 'Accepted' /var/log/auth.log | tail -30 # Debian/Ubuntu
sudo grep 'Accepted' /var/log/secure | tail -30 # RHEL 系
提示框:日志路径与格式因发行版而异——auth.log(Debian/Ubuntu)vs secure(RHEL),见第 1 篇提示。用
journalctl是较新发行版的统一入口。
想一眼看到"最频繁的来源 IP",可统计:
sudo grep 'Failed password' /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -nr | head -20
提示框:字段位置会随日志格式和发行版变化,
awk取列未必通用,仅作演示思路。生产更稳的做法是看 fail2ban 的 banned 列表、或用lastb(若启用 btmp)看爆破来源。
查看最近登录记录:last(看 /var/log/wtmp)和 lastb(看失败的 /var/log/btmp):
last | head -20 # 最近成功登录
sudo lastb | head # 最近失败尝试(爆破来源)
审计要点:
- 有大量来自陌生 IP 的
Failed password→ 正常,公网常态;fail2ban 会拦截。若持续暴涨再排查是否配置未生效。 - 出现你不认识的
Accepted→ 立刻核查是否有人入侵(改密、踢掉会话、查进程)。可w查看当前在线用户。 - 关注异常时段的登录、非白名单账号的
Accepted、可疑的反弹 shell 进程。
长期维护:安全不是一劳永逸
- 及时升级 OpenSSH:
sudo apt upgrade openssh-server或sudo yum update openssh-server,修复 CVE。 - 关注安全公告:留意发行版安全通告中的
openssh条目,重大漏洞时第一时间升级。 - 定期轮换密钥:长期使用的密钥可定期换新(删旧公钥、生成新 key、清理
authorized_keys里的陈旧公钥)。 - 只开最小端口、最小账号:随时间推移新增的服务/账号记得及时清理,别让入口悄悄变宽。
- 做好备份与逃生通道:无论怎么加固,都保留一个带外管理入口(云控制台/VNC/串口)作为兜底。
全系列最终自测清单
把五篇的成果汇总成一份可复检清单,建议定期跑一遍:
认证与账号
- 仅使用密钥登录,
PasswordAuthentication no(第 3 篇) - 私钥设了 passphrase 且保管妥当,公钥权限正确(700 / 600)(第 3 篇)
-
PermitRootLogin no(或prohibit-password),日常用普通账号 + sudo(第 2、4 篇) - 配置了
AllowUsers/AllowGroups白名单(第 4 篇)
会话与资源
-
LoginGraceTime、MaxAuthTries、MaxStartups已限制(第 4 篇) -
ClientAliveInterval/ClientAliveCountMax已清理空闲会话(第 4 篇)
网络层
- 防火墙仅放行可信来源 IP 到 SSH 端口(ufw / firewalld)(第 4 篇)
- (可选)已改非默认端口并写入
~/.ssh/config(第 4 篇)
主动防御与维护
- fail2ban 已启用,
ssh-agentjail 生效,ignoreip含自己(本篇) - 会看认证日志判断异常(
auth.log/secure/journalctl)(本篇) - OpenSSH 保持最新,密钥定期轮换,保留带外逃生通道(本篇)
全系列回顾
至此,从"为什么 SSH 会裸奔"到"如何系统加固",五篇层层推进:
- 认知:SSH 是唯一远程入口,默认不设防,公网被爆破是常态。
- 基础:读懂
sshd_config,学会安全改配置不锁死自己。 - 核心:ed25519 密钥认证,彻底告别密码登录。
- 纵深:账号白名单 + 会话限制 + 防火墙来源白名单 + 禁用 root 直登。
- 收尾:fail2ban 主动封禁 + 日志审计 + 长期维护自测。
安全没有终点,是一个持续收紧、验证、维护的过程。愿你的服务器大门从此清净。
我们下个系列再见。