未来星球 未来星球
  • 首页
  • 新闻资讯
  • 技术教程
  • 软件工具
  • 知识百科
  • 生活实用
  • 个人随笔
  • 生命外星人
首页 › 技术教程 › fail2ban 挡住 SSH 爆破:4 份配置,和 6 个坑
  • 0
  • 0

fail2ban 挡住 SSH 爆破:4 份配置,和 6 个坑

admin
12 小时前
4 views
fail2ban 挡住 SSH 爆破:4 份配置,和 6 个坑-未来星球

一台挂在公网上的服务器,最容易被撞的不是应用漏洞,是 22 端口。日志里每天几千条 failed password,来自几十个国家的 IP,试的都是 root、admin、test 这类账号。

多数人的第一反应是改端口。改完能安静几天,然后又被扫到。改端口只是把噪音调低,不是把门锁上。真正要做的是让「猜错三次」这件事本身产生代价。这篇文章给一份在 Ubuntu 24.04 上验证过的 fail2ban 配置,四个 jail 文件,六个必然踩到的坑。

一、先确定后端,这一步错了后面全白做

fail2ban 的工作原理是持续读日志、按正则匹配失败记录、超过阈值就调用防火墙封 IP。这里第一个岔路口是「它从哪里读日志」。

Ubuntu 24.04 的最小安装默认不再预装 rsyslog,`/var/log/auth.log` 可能根本不存在。此时若沿用旧教程里的默认配置,jail 会因为找不到文件启动失败,但 `systemctl status fail2ban` 依然显示 active——因为主进程活着,只是没在盯任何日志。「服务在跑」和「服务在干活」是两件事,这一条后面还会出现。

所以第一步不是装,是先确认这个文件在不在:

ls -l /var/log/auth.log
systemctl is-active systemd-journald
fail2ban-client --version

如果 auth.log 不存在,就别去装 rsyslog 补它,直接用 `backend = systemd` 从 journal 读。这是 Ubuntu 22.04 之后更稳的路径,也不会被 logrotate 影响。少一个文件依赖,就少一个半夜失效的可能。

本文的配置在 fail2ban 1.1.0 上验证,发行版仓库里的 1.0.2 读同一份 jail 配置,语法一致,差别主要在默认的 banaction。

二、四份配置,各管一件事

不要在 /etc/fail2ban/jail.conf 里改。那个文件属于软件包,升级时会被覆盖,你的规则会连同注释一起消失。正确做法是只写 `jail.local` 和 `jail.d/*.local`,后者覆盖前者,前者覆盖 conf。

四份文件的分工是:全局默认值、SSH 专用规则、nginx 的自定义过滤器、累犯加重。把「默认值」和「单条规则」分开写,是为了以后加 jail 时不用重复抄参数。

三、全局默认值:jail.local

[DEFAULT]
# 从 journal 读,不依赖 /var/log/auth.log
backend = systemd

# 白名单:本机、内网、你的固定出口 IP
# 一定要写,且 IPv6 的 ::1 不能漏
ignoreip = 127.0.0.1/8 ::1 10.0.0.0/8 192.168.0.0/16

# 5 分钟内错 4 次,封 1 小时
bantime  = 1h
findtime = 5m
maxretry = 4

# Ubuntu 24.04 默认 nftables;老系统改成 iptables-multiport
banaction = nftables-multiport
banaction_allports = nftables-allports

# 累犯递增:第二次封 2 小时,第三次 4 小时,上限 1 周
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 1w

# 封禁时把来源记进数据库,便于事后统计
dbfile = /var/lib/fail2ban/fail2ban.sqlite3
dbpurgeage = 30d

`findtime` 与 `maxretry` 的关系是这篇配置里唯一需要按业务调的数字。findtime 越短,越容易被慢速爆破绕过;太长,又会让正常输错密码的人被误封。5 分钟 4 次是家用和小型站点的常见平衡点。

`bantime.increment` 是 1.0 之后才稳定的功能,值得开。它会按同一 IP 的历史封禁次数自动延长时长,等于对反复来的扫描器收递增的过路费。对一次性扫描器无所谓,对持续盯你半个月的爬虫很有效。

四、SSH 规则:jail.d/sshd.local

[sshd]
enabled  = true
port     = ssh
filter   = sshd
# journal 模式下不用写 logpath
maxretry = 3
bantime  = 6h
findtime = 10m

# 只封 SSH 端口,不要 allports
action   = nftables-multiport[name=sshd, port="ssh", protocol=tcp]

SSH 这里把阈值压到 3 次、时长拉到 6 小时,理由是 SSH 的合法用户很少在 10 分钟里连错 3 次。而 `action` 里显式写端口,是为了避免默认全端口封禁把同一台机器上的网站也一起关掉。封 IP 的时候要封到端口,封到人会把无关服务一起带走。

五、nginx 的 404 过滤器:自己写一个

自带的 nginx-http-auth 只管密码错误,管不了「一天扫两万次 /wp-login.php」这种。要挡它,得自己写一个匹配 404 的过滤器。

# /etc/fail2ban/filter.d/nginx-404.conf
[Definition]
failregex = ^<HOST> - .*"(GET|POST|HEAD) [^"]*" 404
ignoreregex = \.(jpg|png|css|js|ico|woff2)$

过滤器只负责识别,什么时候封由 jail 决定,配套的 jail 写在 jail.d/nginx.local:

[nginx-404]
enabled  = true
port     = http,https
filter   = nginx-404
logpath  = /var/log/nginx/access.log
maxretry = 30
findtime = 2m
bantime  = 2h

阈值放到 30 次是有意的。正常浏览器访问不会在两分钟里产生 30 个 404,但一个健康检查脚本配置错了会。宁可让扫描器多扫两分钟,也不要让监控把自己封掉。

注意 `failregex` 里的 `<HOST>` 是 fail2ban 的占位符,不是正则的一部分。写过滤器的常见错误是把它当成命名捕获组自己补括号,结果整条规则匹配不到任何东西,而且不会有任何报错。

六、累犯:jail.d/recidive.local

[recidive]
enabled  = true
filter   = recidive
logpath  = /var/log/fail2ban.log
maxretry = 3
findtime = 1d
bantime  = 1w
action   = nftables-allports[name=recidive]

这条规则的输入不是 SSH 日志,是 fail2ban 自己的日志。同一个 IP 一天内被三个不同 jail 封过,就升级成一周全端口封禁。它对付的不是扫描,是「换着花样试」的那类对手。

整套配置落在磁盘上就是四个文件,加上一个自建 filter:

/etc/fail2ban/
├── jail.conf                 # 软件包自带,不要改
├── jail.local                # 全局默认值
├── jail.d/
│   ├── sshd.local            # SSH 规则
│   ├── nginx.local           # 404 规则
│   └── recidive.local        # 累犯加重
└── filter.d/
    └── nginx-404.conf        # 自建过滤器

七、验收:三件事,缺一不算成功

配置写完必须验证,而且不能只看服务状态。

  1. 列出所有 jail,确认四个都在,且每个都有 `Currently banned` 这一行。
  2. 用一台外部机器(手机热点即可)故意输错三次密码,然后在服务器上查该 IP 是否进了封禁列表。
  3. 在服务器上看防火墙规则里确实多了一条针对该 IP 的 drop。
fail2ban-client status
fail2ban-client status sshd
fail2ban-client banned
nft list ruleset | grep -A2 f2b

第三件事最容易被跳过。fail2ban 显示「已封禁」只代表它认为自己发出了指令,防火墙有没有接受是另一回事。只看 fail2ban 自己的状态,等于让被告给自己作证。

验收通过后再观察一天的 fail2ban.log,看有没有自己的 IP 出现在里面。

八、六个必然会踩到的坑

坑一:backend 用了 auto,日志文件不存在。表现是服务 active、jail 也 enabled,但永远不封人。`fail2ban-client status sshd` 的 `Total failed` 一直是 0。原因就是上面说的,Ubuntu 24.04 没有 auth.log。改成 `backend = systemd` 立刻恢复。

坑二:nginx 在反代后面,日志里的 IP 全是 127.0.0.1。这会让规则要么完全失效,要么把反向代理自己封掉。要先把真实 IP 恢复出来,nginx 里需要 `set_real_ip_from` 加 `real_ip_header X-Forwarded-For`,重启后再看日志第一列。日志第一列不是真实客户端 IP 时,任何基于日志的封禁都是在封错人。

坑三:把自己封了。三种常见情形:ignoreip 只写了 `127.0.0.1` 没写 `::1`;家里宽带是动态 IP,重启光猫后换了地址;通过跳板机操作,跳板机不在白名单里。表现是 SSH 直接超时,控制台能进。补救用云厂商的 VNC 或串口,登录后 `fail2ban-client unban` 加地址。

坑四:Docker 环境下封不住。容器内的 iptables 规则不进宿主机的转发链,封禁看起来生效,实际流量照进。要在宿主机上配 `DOCKER-USER` 链,或者干脆把 fail2ban 装在宿主机、只监控宿主机的 nginx。这是最容易让人误判「已经防住了」的一种。

坑五:logrotate 之后规则悄悄失效。用 `backend = auto` 或 `file` 时,日志被切割后文件名还在但 inode 变了,fail2ban 握着的还是旧句柄,读不到新内容。要么切 journal,要么在 logrotate 配置里加一段 postrotate 调 `fail2ban-client reload nginx-404`。这类故障没有报错,只有「最近怎么没人被封了」。

坑六:recidive 和 bantime.increment 重复计量。两个机制都在按历史次数加码,叠加后可能出现一次误封直接变成一周。战术上没问题,但如果你的出口 IP 会漂移,代价就很实际。家用环境建议只留 `bantime.increment`,recidive 留给有固定机房的场景。

写在最后

fail2ban 不提升任何安全性上限,它只是把「无限次尝试」改成「有限次尝试」。真正挡住入侵的是密钥登录、关掉密码认证、最小权限,这些是门锁;fail2ban 是门口那盏一直亮着的灯。

但灯有用。它让成本从「零」变成「要换 IP」,而绝大多数自动化扫描不会为了一台普通服务器去换 IP 池。安全措施的价值常常不在强度,在筛选。

顺便说一句,这套配置最值得抄的不是数字,是那个验收方式:不看服务状态,看防火墙规则。能被证据推翻的检查,才叫检查。


你的服务器日志里,重复出现的那个 IP,是扫描器还是你自己的备用线路?

0

盲道为什么是两种凸起:1965年,和一条被走错的直道

上一篇

洗衣机甩干时满地跑:6 项措施,按投入时间排的一份清单

下一篇

评论 (0)

登录后可发布~
立即登录
暂无评论

admin

当生活给你的全是不如意,那你一定要相信自己的兴趣!
249
文章
0
评论
-11
喜欢
2026 年 11 月
一 二 三 四 五 六 日
 1
2345678
9101112131415
16171819202122
23242526272829
30  
« 10 月    

近期评论

聚合文章

从图片里抠出文字:4 个 OCR 工具的边界,3 种选错的信号
当眼镜一直开着:三代人的记忆,和一个不太好接受的推论
第九行星:11年,和一组不肯聚拢的轨道
修一双鞋,鞋跟换了两次,和一块磨偏的橡胶
AI新闻日报–2026年11月14日:57%,和644亿美元
洗衣机甩干时满地跑:6 项措施,按投入时间排的一份清单
fail2ban 挡住 SSH 爆破:4 份配置,和 6 个坑
盲道为什么是两种凸起:1965年,和一条被走错的直道

猜你喜欢

Uptime Kuma 监控五个站点:3份配置,和4个必然踩到的坑

Uptime Kuma 监控五个站点:3份配置,和4个必然踩到的坑

admin
17 0 0
用 systemd 定时器替代 cron:3 份配置,4 个必踩的坑

用 systemd 定时器替代 cron:3 份配置,4 个必踩的坑

admin
21 0 0
用 WireGuard 组建家庭内网:三台设备、一份可复现的配置

用 WireGuard 组建家庭内网:三台设备、一份可复现的配置

admin
37 0 0
用 Ansible 管两台服务器:3 份配置,4 个必踩的坑

用 Ansible 管两台服务器:3 份配置,4 个必踩的坑

admin
18 0 0

关于我们

你是否对浩瀚的宇宙充满好奇?你是否渴望掌握未来科技的力量?现在,机会来了!“未来星球”将带你进入奇妙世界,开启你的科技探险之旅! 这是一个充满想象和创造力的博客!

分类导航

首页 新闻资讯 技术教程 软件工具 知识百科 生活实用 个人随笔 生命外星人

友情链接

未来星球AI工具【网络版】 未来星球 pycharm官方站【中国】
Copyright © 2026 未来星球. Designed by nicetheme. 蒙ICP备2026002569号-1
  • 请到 [后台->外观->菜单] 中设置菜单
  • AI未来
  • 生活百科
  • 档案
  • 外星人
  • 未来星球

admin

当生活给你的全是不如意,那你一定要相信自己的兴趣!
249
文章
0
评论
-11
喜欢