CrowdSec 协同封禁实战:把单机 fail2ban 升级成社区情报(2026)

fail2ban 只能封"攻击过你这台机器"的 IP,而 CrowdSec 能在恶意 IP 碰到你之前就把它丢掉——因为它背后是上万台真实服务器实时汇出来的社区黑名单。 我在一台 Ubuntu 22.04 上翻过 fail2ban 的封禁记录:榜单前几名是熟面孔,同一批 IP 隔三差五回来撞门,封了放、放了封。问题在于 fail2ban 的视野只有本机日志,攻击者扫你之前在别的机器上干了什么,它一无所知。CrowdSec 换了个思路:每台节点的攻击告警匿名上传,汇成社区情报再同步回每个节点,等于把"全网被这批 IP 打过"的经验直接拿来用。这篇记录我从零部署的完整过程:架构、安装、场景、firewall bouncer、验证,以及两个真会踩的坑。

CrowdSec 协同封禁原理

fail2ban 不是够用了吗?

单机 fail2ban 的问题不是不好用,而是视野只有一台机器。攻击者撞你的 SSH 密码字典之前,大概率刚在别的机器上撞过同一套字典——那批"惯犯"的名单其实已经存在,只是你拿不到。把两边放一起看:

维度 fail2ban CrowdSec
情报来源 本机日志 本机日志 + 社区黑名单
封禁时机 攻击发生后 部分在攻击发生前
检测规则 每种日志一个 filter 正则 解析器 + 场景,社区维护
资源占用 Python,轻 Go 单二进制,也很轻
控制台 无 官方 Web 控制台免费

CrowdSec 是 Go 编译的单二进制,agent 常驻内存几十 MB,1G 小机完全无压力。它不是 fail2ban 的替代品那么简单——封禁这件事从"单机自保"变成了"共享情报网"的一个节点。fail2ban 的基础加固流程仍然值得先做一遍(见SSH 安全加固五步),CrowdSec 是在那之上加的一层。

CrowdSec 部署步骤总览

架构是怎么回事?

两个角色拆开理解就清楚了。agent 负责"看":读日志、跑场景(scenario)、发现恶意行为后产生告警(alert)和处置决定(decision);bouncer 负责"打":订阅本地 API 的 decision,把封禁落到 nftables、iptables 或 Nginx 这些执行层。agent 和 bouncer 之间走本地 REST API,都跑在同一台机器上也互不干扰。

注册进社区之后多了一条外联:你产生的攻击 IP 匿名上传给社区,社区把其他所有节点上报的高频恶意 IP 下发给你。你贡献一条,换回上万条,这就是"协同封禁"的全部含义。

怎么安装?

Ubuntu 22.04 用官方 deb 仓库,2026 年当前版本 1.6+:

$ curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
$ sudo apt install -y crowdsec
$ cscli version

装完服务自动启动,本机 agent 也自动注册:

$ sudo systemctl status crowdsec
$ sudo cscli machines list

collections 怎么选?

解析器(parser)和场景(scenario)都从 hub 装,collection 是打包好的一组 parser + scenario。跑 SSH 的机器装 sshd,有 Nginx 反代的加上 nginx:

$ sudo cscli collections install crowdsecurity/sshd
$ sudo cscli collections install crowdsecurity/nginx
$ sudo cscli hub update && sudo cscli hub upgrade

装完 sudo cscli scenarios list 能看到 ssh-bf(爆破)、http-probing(目录探测)这类场景,每个场景就是一条"什么行为模式算恶意"的判断规则,全部由社区维护、hub upgrade 即可更新,不用自己写正则。

步骤 1:安装与装场景

调优时有个好用的命令:cscli explain,丢一条真实日志进去,它会告诉你这条日志被哪个解析器解析、命中了哪个场景。拿它验证"我的日志格式到底有没有被认出来",比翻文档快得多。

bouncer 怎么接?

这一步最容易漏。只装 agent 的机器会一直"只见告警不见封禁",因为 agent 只负责产生决定,动手的是 bouncer:

$ sudo cscli bouncers add fw-bouncer     # 记下生成的 key
$ sudo apt install -y crowdsec-firewall-bouncer-nftables

安装过程会交互式询问 bouncer key 和后端,Ubuntu 22.04 默认 nftables,选它即可。装完检查两处:

$ sudo systemctl status crowdsec-firewall-bouncer
$ sudo nft list ruleset | grep -i crowdsec | head

nftables 里出现 crowdsec 专属链,说明执行层就位了。bouncer 每十几秒从本地 API 拉一次 decision,把名单写进内核。

步骤 2:装 firewall bouncer

部署完怎么验证?

别干等真攻击,自己制造一条 decision 最快:

$ sudo cscli decisions add --ip 203.0.113.66 --duration 5m --reason "test"
$ sudo cscli decisions list

再从 203.0.113.66 那台机器 telnet 你的端口,会发现包直接被丢——nftables 层面的封禁不回任何响应。真实告警这样看:

$ sudo cscli alerts list          # 最近的告警
$ sudo cscli decisions list       # 当前生效的封禁
$ sudo cscli metrics              # 解析与命中统计

metrics 里重点看 parsers 的解析成功率和各场景的命中次数,解析率低说明日志格式没被认出来,该装对应 collection。

步骤 3:制造与查看封禁

社区黑名单是怎么工作的?

enroll 到官方控制台(免费)之后,协同机制才开始完整转起来:你的告警被匿名化(只留 IP 和行为标签)上传,社区把"多台节点独立报告过同一恶意行为"的 IP 以社区决策(origin 为 CAPI)的形式同步回你本机,bouncer 一并执行。这些社区决策不占你本地告警,单独查看:

$ sudo cscli console enroll 你的token
$ sudo cscli decisions list --origin CAPI

浏览器打开控制台,能看到这台机器的告警曲线、封禁来源分布、场景命中排行,多台机器统一在一个面板里看,比逐台 ssh 上去翻日志省心得多。

步骤 4:enroll 与社区情报

两个真会踩的坑

我一开始以为装完 crowdsec 主包封禁就自动生效了,后来发现告警一直涨、nft list ruleset 里却一条 crowdsec 链都没有——排查了半小时才反应过来 bouncer 是独立组件,没装它,agent 就是个"只报警不动手"的监控探头。这是新手最高频的困惑,判断方法就一条:sudo cscli bouncers list 里你的 bouncer 的 last pull 时间是否在持续刷新,停在几小时前就是没在工作。

白名单自己的 IP。 办公室或家里出口 IP 相对固定的话,第一时间加白,否则一次误触发把自己锁在外面,还得从 VPS 控制台进去救。最直接的方式是编辑 /etc/crowdsec/parsers/s02-enrich/whitelists.yaml,把你自己的网段和内网段(192.168.0.0/16、10.0.0.0/8)加进去,改完 sudo systemctl reload crowdsec。加了白名单之后,社区决策也不会作用于这些来源。

还有一个小坑顺带提:如果你的服务器在 Docker 上跑了一堆服务,Docker 自己写 iptables 规则的方式可能和 firewall bouncer 的链有交集,相关背景在UFW + Docker 那篇里分析过,配完记得从外部验证封禁真的生效。

迁移节奏建议

不用一刀切。先装 CrowdSec 和 fail2ban 并行跑几天,观察 cscli alerts list 的命中是否符合预期、白名单是否配全,确认无误后再停掉 fail2ban 的 sshd jail。两套同时跑资源占用可以忽略,换来的是切换期间没有规则真空。真被入侵过一次的机器,则建议按入侵排查四步先清理干净再上 CrowdSec,否则历史后门会一直触发告警把水搅浑。

常见问题

Q:CrowdSec 和 fail2ban 能同时跑吗?
能,两套各自独立读日志、独立封禁,互不冲突。建议先并行观察几天 CrowdSec 的告警是否合理,确认白名单配全后再关掉 fail2ban 的 jail,避免切换期间出现规则真空。

Q:社区黑名单会不会把正常用户误封进来?
进入社区黑名单需要"多台机器独立报告同一恶意行为",单机单次误报很难攒够权重。如果某些来源特别重要(办公网、监控探针),用 whitelists 显式排除最保险,比事后解封省心。

Q:小内存 VPS 跑得动吗?
能。Go 编译的单二进制,agent 常驻内存几十 MB,firewall bouncer 更轻。我在 1G 内存的机器上实测 agent 加 bouncer 全开,占用可以忽略,比 fail2ban 的 Python 进程还省。

Q:Nginx 层的攻击也想拦,用什么 bouncer?
装 crowdsec-nginx-bouncer,它在 Nginx 层直接拦 HTTP 请求,能处理"不该封 IP、只想拦特定请求"的场景;firewall bouncer 管网络层。两者可以并存,分别负责两层。

相关阅读

上一篇 Cloudflare Workers + D1:给静态博客加一个免费评论与访问计数服务(2026)