公网 Linux 服务器必然被 SSH 爆破扫描,两个工具/文件构成"看清它 → 掐断它"的闭环:btmp 是"谁试过开门"的流水账(看得见),fail2ban 是"试太多次自动锁门"的门禁(治得了)。

btmp:登录失败流水账

btmp 是 Linux 登录失败记录文件(/var/log/btmp),由 sshd/PAM 在每次认证失败时追加一条二进制记录。配套工具:

sudo lastb                  # 读 btmp,按时间倒序列出失败登录
sudo lastb -F               # 带完整时间戳(分析时间分布必需)
sudo lastb | wc -l          # 总失败次数
du -sh /var/log/btmp*       # 文件大小(logrotate 轮转出 btmp.1)

对应的成功登录在 auth.log 里:grep "Accepted" /var/log/auth.log。

要点与坑:

  • lastb 必须 root(文件权限 600)
  • btmp 主要记录到达密码认证阶段的失败;纯密钥认证失败多走 auth.log,btmp 里未必有——所以 btmp 计数偏低不代表没被扫
  • btmp 只增不缩,长期被打会积累到几十 MB;轮转后旧文件可删
  • lastb 输出列:用户名 端口 IP 星期 月 日 时间 年;用 grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" 提取 IP 最稳

fail2ban:自动封禁门禁

fail2ban 的机制是日志匹配 → 计数 → 防火墙封禁,三步循环:

auth.log/sshd 日志 ──failregex 匹配"Failed password"──→ jail 计数器
        计数器在 findtime 窗口内达到 maxretry ──→ iptables/nftables DROP 该 IP bantime 秒

核心概念:

  • jail:一个监控单元 = 一份日志 + 一套正则 + 一组阈值。SSH jail 最常用,nginx/auth-api 等都有现成 filter
  • 三个参数:maxretry(允许失败次数)、findtime(计数窗口)、bantime(封禁时长);可配递增封禁(bantime.increment = true,再犯翻倍)
  • 封禁动作:默认写 iptables DROP 规则,sudo fail2ban-client status sshd 看当前被封 IP 列表
  • 白名单:ignoreip = 127.0.0.1/8 ::1 自己的常用 IP——务必先加自己,否则改密码输错几次把自己锁外面

tx 服务器实测 (2026-08)

一个月 48,721 次失败的分析结论,代表典型的"僵尸网络滴灌"画像:

  • 91.5% 来自两个 IP(51.222.47.156 / 51.89.42.211,均为 OVH 机房):各约 2,230 次/天,每 5~6 秒一发,24 小时不停,持续整月
  • 长尾 711 个 IP,大头是腾讯云国际段(43.153.x 等)——被黑的云主机
  • 目标用户名:root 97%,其次 ubuntu/admin/test,词表含 wallet/bitcoin(挖矿僵尸网络特征)
  • 时间分布无规律,不挑凌晨;高峰日破 1 万,是主攻 IP 临时加码

为什么永不放弃:sshd 若开着 permitrootlogin yes + passwordauthentication yes,就是僵尸字典的头号目标。真实防线是三层,从根上做:

  1. PasswordAuthentication no(只留密钥)——性价比最高,直接让密码爆破失去意义
  2. PermitRootLogin no
  3. fail2ban 兜底掐掉滴灌噪音

分析用的完整命令链:

sudo lastb -F | grep -oE "[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" | sort | uniq -c | sort -rn | head -15  # top IP
sudo lastb -F | grep -E "^[a-zA-Z]" | awk '{print $1}' | sort | uniq -c | sort -rn | head        # 目标用户名
sudo lastb -F | grep -E "^[a-zA-Z]" | grep -oE "(Mon|Tue|Wed|Thu|Fri|Sat|Sun) [A-Z][a-z]{2} +[0-9]{1,2}" | sort | uniq -c | sort -k3 -n  # 按天分布
grep -h "Accepted" /var/log/auth.log* | grep -oE "from [0-9.]+" | sort | uniq -c | sort -rn      # 成功登录来源核对
sshd -T | grep -E "passwordauthentication|permitrootlogin"                                       # 实际生效的认证策略

相关概念

  • SSH 协议
  • 部署配置:tx 服务器启用 fail2ban 时,ignoreip 先写自己常连的出口;参见 htpasswd 共用文件需取格式交集 的同类"入口防护"思路

本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/Network