防火墙只能挡端口,挡不住"用合法端口反复试密码"的行为。SSH 的 22 端口你总得开,扫描器就会天天来试。
fail2ban 解决这个问题:它盯着日志,发现某个 IP 在短时间内反复失败,就自动把它加进防火墙黑名单。整个过程全自动,配好后基本不用管。
财富云计算 的云服务器支持安装 fail2ban;做内网服务、游戏服务端可选 NAT 型(无独立公网 IP,价格比独立 IP 机型省一半以上)。
一、fail2ban 能防护什么
| 服务 | 防护内容 |
|---|---|
| SSH | 反复尝试登录 |
| Nginx/Apache | 反复 401 认证失败、扫后台、CC 刷接口 |
| WordPress/Typecho | 后台登录爆破 |
| FTP | 账号爆破 |
| 邮件(Postfix/Dovecot) | 账号爆破 |
| 任意服务 | 只要日志里有失败记录,就能写规则 |
工作原理:
监控日志文件
→ 用正则(filter)匹配失败记录
→ 统计来源 IP 的失败次数
→ 达到阈值(maxretry)就执行动作(ban)
→ 动作通常是加一条 iptables/firewalld 规则封禁
→ 到时间(bantime)自动解封二、安装
# Debian/Ubuntu
apt update
apt install fail2ban -y
# CentOS/Rocky
yum install epel-release -y
yum install fail2ban -y
systemctl enable --now fail2ban
fail2ban-client version三、配置文件结构
/etc/fail2ban/
├── fail2ban.conf # 主配置(一般不动)
├── jail.conf # 默认规则(不要直接改,会被升级覆盖)
├── jail.local # ← 你的自定义配置写这里
├── jail.d/*.conf # 额外的规则文件
├── filter.d/ # 过滤器(匹配日志的正则)
│ ├── sshd.conf
│ ├── nginx-http-auth.conf
│ └── ...
└── action.d/ # 动作(封禁方式)
├── iptables.conf
├── firewallcmd.conf
└── ...关键原则:永远改 jail.local 或 jail.d/ 下的文件,不要改 jail.conf。
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
nano /etc/fail2ban/jail.local四、核心参数
[DEFAULT]
# 不封禁的 IP(白名单),务必加上自己的 IP 和内网
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 10.0.0.0/8 你的公网IP
# 封禁时长(秒),-1 表示永久
bantime = 86400
# 统计窗口(秒):在这个时间内的失败次数
findtime = 600
# 允许的失败次数
maxretry = 3
# 封禁方式(自动检测)
banaction = iptables-multiport
# CentOS 7+ 用:banaction = firewallcmd-ipset
# 后端(自动检测 systemd 或文件)
backend = auto
# 邮件通知(可选)
destemail = you@example.com
sender = fail2ban@example.com
mta = sendmail
action = %(action_)s # 只封禁
# action = %(action_mw)s # 封禁 + 发邮件
# action = %(action_mwl)s # 封禁 + 发邮件 + 附日志参数怎么理解:
findtime=600 + maxretry=3 = "10 分钟内失败 3 次就封"。
五、配置 SSH 防护
[sshd]
enabled = true
port = ssh # 或改成你的实际端口,如 2299
filter = sshd
logpath = /var/log/auth.log # CentOS 是 /var/log/secure
maxretry = 3
findtime = 600
bantime = 86400systemctl restart fail2ban验证
fail2ban-client status
fail2ban-client status sshd输出:
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 47
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 3
|- Total banned: 12
`- Banned IP list: 45.13.xx.xx 103.xx.xx.xx 185.xx.xx.xx手动测试(从另一台机器故意输错密码 3 次),然后看是否被封:
fail2ban-client status sshd
iptables -L -n | grep f2b-sshd六、Nginx 防护
1)HTTP 认证失败
[nginx-http-auth]
enabled = true
filter = nginx-http-auth
port = http,https
logpath = /var/log/nginx/error.log
maxretry = 5
findtime = 600
bantime = 36002)封禁扫描后台的 IP(如 /admin、/wp-login.php、/.env)
先看日志格式,常见的是访问日志里出现大量 404。
创建自定义 filter:
nano /etc/fail2ban/filter.d/nginx-scan.conf[Definition]
failregex = ^<HOST> -.*"(GET|POST|HEAD).*(/\.env|/\.git|/wp-login\.php|/xmlrpc\.php|/admin|/phpmyadmin|/shell\.php).*" (404|403|301|200)
ignoreregex =创建 jail:
nano /etc/fail2ban/jail.d/nginx-scan.conf[nginx-scan]
enabled = true
filter = nginx-scan
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 5
findtime = 300
bantime = 864003)防 CC(请求频率过高)
nano /etc/fail2ban/filter.d/nginx-cc.conf[Definition]
failregex = ^<HOST> -.*"(GET|POST).*" 200
ignoreregex =[nginx-cc]
enabled = true
filter = nginx-cc
port = http,https
logpath = /var/log/nginx/access.log
maxretry = 200 # 阈值放宽,别误伤正常用户
findtime = 60
bantime = 3600防 CC 更推荐用 Nginx 自带的 limit_req(性能更好,不依赖日志分析)。fail2ban 的 CC 防护适合日志量不大的小站。4)封禁恶意爬虫
[Definition]
failregex = ^<HOST> -.*"(GET|POST).*" (4\d\d) .*"(scrapy|python-requests|curl|wget|AhrefsBot|SemrushBot)"七、自定义 filter:给任意服务加防护
步骤:
1)先找到日志里的失败记录
tail -100 /path/to/app.log | grep -i "fail\|error\|invalid"假设有:
2026-10-12 14:23:01 [WARN] Login failed for user admin from 45.13.22.112)写 filter
nano /etc/fail2ban/filter.d/myapp.conf[Definition]
failregex = Login failed for user .* from <HOST>
ignoreregex =<HOST> 是固定占位符,会被替换成 IP 匹配正则。
3)测试正则(很重要)
fail2ban-regex /path/to/app.log /etc/fail2ban/filter.d/myapp.conf输出会显示匹配到多少条、匹配了哪些行。一定要测,正则写错等于没防护。
4)写 jail
nano /etc/fail2ban/jail.d/myapp.conf[myapp]
enabled = true
filter = myapp
port = 8080
logpath = /path/to/app.log
maxretry = 5
findtime = 600
bantime = 72005)重启验证
systemctl restart fail2ban
fail2ban-client status myapp八、常用命令
# 状态
fail2ban-client status # 所有 jail
fail2ban-client status sshd # 单个 jail
# 手动封禁/解封
fail2ban-client set sshd banip 1.2.3.4
fail2ban-client set sshd unbanip 1.2.3.4
fail2ban-client set sshd unbanip --all # 解封所有
# 加白名单(永久)
fail2ban-client set sshd addignoreip 1.2.3.4
# 重载配置
fail2ban-client reload
fail2ban-client reload sshd
# 停止/启动某个 jail
fail2ban-client stop sshd
fail2ban-client start sshd
# 测试 filter 正则
fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf
# 查看日志
tail -f /var/log/fail2ban.log九、动作(action):封禁之外还能做什么
默认动作是封 IP,也可以配置发邮件、调用 API 等。
内置动作:
| 动作 | 行为 |
|---|---|
%(action_)s | 只封禁 |
%(action_mw)s | 封禁 + 发邮件 |
%(action_mwl)s | 封禁 + 发邮件 + 附日志片段 |
%(action_abuseipdb)s | 上报到 AbuseIPDB(需 API key) |
配置邮件通知:
apt install sendmail mailutils -y # 或配 ssmtp/msmtp[DEFAULT]
destemail = you@example.com
sender = fail2ban@example.com
mta = sendmail
[sshd]
action = %(action_mwl)s调用钉钉/企业微信机器人(更实用):
nano /etc/fail2ban/action.d/dingtalk.conf[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST 'https://oapi.dingtalk.com/robot/send?access_token=xxx' \
-H 'Content-Type: application/json' \
-d '{"msgtype":"text","text":{"content":"fail2ban 封禁 IP: <ip> (jail: <name>)"}}'
actionunban =[sshd]
action = iptables-multiport
dingtalk十、持久化与开机自启
systemctl enable fail2banfail2ban 有 SQLite 数据库(/var/lib/fail2ban/fail2ban.sqlite3)记录封禁历史,重启后不会丢失已封 IP 的计时。
清空数据库(规则太多想重置):
systemctl stop fail2ban
rm /var/lib/fail2ban/fail2ban.sqlite3
systemctl start fail2ban十一、调优与注意事项
1)别把自己封在外面
ignoreip = 127.0.0.1/8 ::1 你的常用IP 内网网段万一被封:走云控制台 VNC 登录,执行:
fail2ban-client set sshd unbanip 你的IP
# 或
systemctl stop fail2ban
iptables -L -n --line-numbers | grep f2b
iptables -D f2b-sshd 12)bantime 递增(重复犯事的封更久)
[DEFAULT]
bantime = 3600
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 604800 # 最多封 7 天第一次 1 小时,第二次 2 小时,第三次 4 小时……
3)日志量太大影响性能
fail2ban 要实时读日志,日志量极大的站点会有开销。可以:
- 只启用必要的 jail
- 增大
findtime,减少匹配频率 - 用
journal后端(systemd)代替文件轮询:
[sshd]
backend = systemd4)Docker 容器里的服务
Docker 日志默认不写文件,fail2ban 读不到。解决:
- 让容器把日志写到宿主机某个目录
- 或用
docker logs配合脚本 - 或容器应用本身就是反代后,用 Nginx 的日志来封
5)IPv6
确保 iptables 规则也覆盖 ip6tables:
banaction = iptables-multiport
banaction_allports = iptables-allports现代版本会自动处理。
6)误封正常用户
- 把公司/家庭固定 IP 加白名单
- 防 CC 的
maxretry别设太低(建议 100+/分钟) - 定期看
Banned IP list,发现误封及时调整
十二、完整配置示例(可直接用)
nano /etc/fail2ban/jail.local[DEFAULT]
ignoreip = 127.0.0.1/8 ::1 192.168.0.0/16 10.0.0.0/8
bantime = 86400
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 604800
findtime = 600
maxretry = 3
backend = auto
banaction = iptables-multiport
destemail = you@example.com
sender = fail2ban@localhost
action = %(action_)s
[sshd]
enabled = true
port = 2299
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 600
bantime = 86400
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
bantime = 3600
[nginx-noscript]
enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx/access.log
maxretry = 6
bantime = 86400
[nginx-badbots]
enabled = true
port = http,https
filter = nginx-badbots
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400
[nginx-noproxy]
enabled = true
port = http,https
filter = nginx-noproxy
logpath = /var/log/nginx/access.log
maxretry = 2
bantime = 86400nginx-noscript / nginx-badbots / nginx-noproxy 是 fail2ban 自带的 filter,一般安装后就有,用 ls /etc/fail2ban/filter.d/ | grep nginx 确认。systemctl restart fail2ban
fail2ban-client status十三、fail2ban 不是万能的
它能挡:
- ✅ 密码爆破
- ✅ 明显的扫描行为
- ✅ 高频 CC(辅助)
它挡不住:
- ❌ 分布式 CC(IP 太多,封不过来)→ 用 Nginx limit_req + CDN
- ❌ 应用层漏洞(SQL 注入等)→ 靠程序安全
- ❌ 已经拿到密码的攻击者 → 靠密钥登录 + 强密码
- ❌ 慢速攻击(低频但持续)→ 靠 WAF
正确的安全是分层的:防火墙 + fail2ban + 密钥登录 + 及时打补丁 + 最小权限 + 备份,缺一不可。
服务器上线就该装 fail2ban。财富云计算 的云服务器支持完整管理员权限,可自由安装配置;做内网服务、游戏服务端可选 NAT 型(无独立公网 IP,价格比带独立 IP 机型省一半以上),配合端口映射按需开放,暴露面更小更安全。
相关阅读:
- 《SSH 密钥登录与账号安全配置》
- 《Linux 防火墙配置:ufw / firewalld / iptables》
- 《服务器被入侵应急排查与处置》
- 《网站常见漏洞与基础防护》
延伸阅读
- 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
- 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
- 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
- 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
- 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
- RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
- 短链接服务搭建:Shlink 自托管,链接数据自己掌握
- 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道

[...]fail2ban-client status nginx-limit-req # 看封禁状态被封 1 小时,攻击者换 IP 成本变高,小规模 CC 基本就退了。更多 fail2ban 内容见fail2ban 防暴力破解实战。六、完整配置模板这是一套可直接用的 Nginx 防护配置:http {[...]
2026-10-13 回复
[...]安全组是云服务器的第一道门:配错了,要么玩家连不上、要么全网都能扫到你。这篇把安全组的原理、配法、排查讲透——从默认规则到最小化实践,从游戏服到网站,全部有现成规则表。需要现成的游戏云服务器,可以看看财富云计算:一键开服面板,NAT 型无独立公网 IP,价格比独立 IP 机型省一半以上,主流游戏都能快速部署,安全组模板已内置。一、安全组是什么安全组是云平台提供的虚拟防火墙,在流量到达你的服务器之前[...]
2026-10-15 回复
[...]mail -s "安全周报-$(hostname)-$(date +%F)" admin@example.com < $LOG挂 crontab 每周一凌晨跑,周一早上喝着咖啡看报告。更完整的巡检体系见服务器日常巡检清单与自动化。七、报告出来后的处理优先级发现动作系统二进制被改重装该包(apt install --reinstall),查入侵入口陌生 SUID 文件立刻定[...]
2026-10-15 回复
[...]sudo fail2ban-client status效果:一个 IP 一分钟内 20 个 404 就封一小时;试 3 次已知恶意 UA 封一天。完整配置见fail2ban 防暴力破解实战。三、第二层:Nginx 限流限速针对高频接口(登录、搜索、API):# 定义限流区:每秒 10 个请求,突发 20[...]
2026-10-15 回复
[...]sudo fail2ban-client status sshd # 看封禁名单配置细节见fail2ban 防暴力破解实战。三层防御叠下来:密码长 + 密钥登录 + 高位端口 + fail2ban,暴力破解的成功率趋近于零。六、第五层:双因素认证(2FA)对「 Root 权限 + 重要存档」的机器,上 2FA——即使密码泄露,没有动态码也进不来:# Google Authenticator P[...]
2026-10-18 回复
[...]每次开新服都要重来一遍:装依赖、建用户、配 Swap、设防火墙、装 SteamCMD、配 systemd……同样的步骤抄十遍,总有一次抄错。这篇把这些固化成一套一键环境脚本:新机器跑一遍,十分钟后就是一个随时可以装任何游戏的标准开服环境。本文基于 财富云计算 NAT 型云服务器(无独立公网 IP、价格比独立 IP 机型省一半以上)的 Ubuntu 22.04 环境编写。脚本可直接抄走,按注释改几个[...]
2026-10-18 回复
[...]netsh advfirewall firewall add rule name="GameRange" dir=in action=allow protocol=UDP localport=26901-26903完整的 Windows 环境准备(远程桌面连接、运行库安装、SteamCMD 用法、开机自启、8 个常见坑)见:《Windows 云服务器开服通用前置教程》→ htt[...]
2026-10-18 回复
[...]./discourse-setupapp.yml 里配好域名、SMTP(Discourse 强依赖邮件,注册验证、通知全走邮件,必须先配好发信,见邮件退信与 SPF/DKIM/DMARC 配置)。Discourse 的管理后台是它的精髓:信任等级自动权限、反垃圾评分、敏感词、话题合并——社区做大了,这些工具能省掉两个运营。四、社区运营的三条硬功夫技术只是上半场,社区死活在下半场:冷启动:前 100[...]
2026-10-18 回复
[...]restart: unless-stoppedGhost(Docker + Nginx 反代):官方镜像 + 443 反代,配置方法同Docker 部署网站实战的套路。四、博客的通用功课不管选哪个平台,这些事都逃不掉:备份——写了三年的博客丢过一次就懂了。数据库 + 附件每日自动备份,异地一份,方案见服务器备份与快照策略。HTTPS——现在没有 SSL 的博客,浏览器直接标"不安全",读者信任打对[...]
2026-10-18 回复