使用 CrowdSec 防护 Nginx 恶意扫描与 SSH 爆破

发布于 最后更新 阅读 19
评论已关闭
# 使用 CrowdSec 防护 Nginx 恶意扫描与 SSH 爆破

本文记录一次在 Linux VPS 上部署 CrowdSec 的过程,目标是防护常见的 SSH 暴力破解、Nginx 恶意扫描、HTTP CVE 探测和部分异常请求行为。

环境大致如下:

```text
系统:Ubuntu / Debian 系
Web 服务:Nginx
防火墙:UFW + iptables
安全工具:CrowdSec
Bouncer:crowdsec-firewall-bouncer-iptables

1. CrowdSec 是什么?

CrowdSec 可以理解为一个现代化的 Fail2ban。

它的核心工作流程是:

读取日志
↓
解析日志
↓
识别攻击行为
↓
产生封禁决策 decision
↓
交给 bouncer 执行封禁

例如:

SSH 多次登录失败
Nginx 被扫描 /.env
访问 /.git/config
探测 /wp-login.php
尝试访问 phpMyAdmin
HTTP DoS 行为
常见 CVE 探测

CrowdSec 本身负责“判断谁是攻击者”,但真正执行封禁的是 bouncer。

常见组件包括:

crowdsec                         主程序,负责分析日志
cscli                            命令行管理工具
crowdsec-firewall-bouncer        防火墙封禁组件
crowdsec-nginx-bouncer           Nginx 层封禁组件,可选
collections                      规则包,例如 nginx、http-cve、http-dos

本文采用的是更通用、更稳妥的方式:

CrowdSec + firewall bouncer + iptables

2. 为什么没有使用 crowdsec-nginx-bouncer?

一开始尝试安装 Nginx bouncer:

sudo apt install nginx lua5.1 libnginx-mod-http-lua luarocks gettext-base lua-cjson
sudo apt install crowdsec-nginx-bouncer

但遇到了错误:

Package 'libnginx-mod-http-lua' has no installation candidate

crowdsec-nginx-bouncer : Depends: libnginx-mod-http-lua but it is not installable

这通常说明当前系统源里没有可安装的 Nginx Lua 模块,常见原因包括:

系统版本较旧
Nginx 不是从系统官方源安装
使用了 nginx.org 官方源
apt 源不完整
模块包与当前 Nginx 版本不匹配

所以这里不继续折腾 Nginx bouncer,而是使用 firewall bouncer。

这种方案同样可以实现:

CrowdSec 分析 Nginx access.log
↓
识别恶意扫描 IP
↓
通过 iptables 封禁该 IP

对普通 VPS 来说已经足够实用。


3. 安装 CrowdSec

添加 CrowdSec 官方仓库并安装:

curl -s https://install.crowdsec.net | sudo sh
sudo apt update
sudo apt install crowdsec

启动 CrowdSec:

sudo systemctl enable --now crowdsec

查看状态:

sudo systemctl status crowdsec

查看版本:

sudo cscli version

4. 查看当前 CrowdSec 是否在工作

执行:

sudo cscli metrics

如果刚安装完,可能只能看到类似:

Acquisition Metrics

Source                    Lines read   Lines parsed   Lines unparsed
file:/var/log/auth.log    14           -              14
file:/var/log/kern.log    7            -              7
file:/var/log/syslog      7            -              7

这说明 CrowdSec 当前只读取了系统日志,还没有读取 Nginx 日志。

如果你想防护 Nginx 恶意扫描,就必须把 Nginx access log 接入 CrowdSec。


5. 安装 Nginx 防护规则

安装 Nginx collection:

sudo cscli collections install crowdsecurity/nginx

建议再安装 HTTP CVE 和 HTTP DoS 相关规则:

sudo cscli collections install crowdsecurity/http-cve
sudo cscli collections install crowdsecurity/http-dos

查看已安装的 collection:

sudo cscli collections list

查看场景规则:

sudo cscli scenarios list

查看解析器:

sudo cscli parsers list

6. 配置 CrowdSec 读取 Nginx 日志

先确认 Nginx 日志存在:

ls -lh /var/log/nginx/

常见日志路径为:

/var/log/nginx/access.log
/var/log/nginx/error.log

创建 CrowdSec 的 Nginx 日志采集配置:

sudo tee /etc/crowdsec/acquis.d/nginx.yaml > /dev/null <<'EOF'
filenames:
  - /var/log/nginx/access.log
  - /var/log/nginx/error.log
labels:
  type: nginx
EOF

重启 CrowdSec:

sudo systemctl restart crowdsec

再次查看 metrics:

sudo cscli metrics

正常情况下,Acquisition Metrics 里应该出现:

file:/var/log/nginx/access.log
file:/var/log/nginx/error.log

如果没有出现,排查这几个点:

Nginx 日志路径是否正确
Nginx 是否真的在写 access.log
CrowdSec 是否有权限读取日志
nginx.yaml 的缩进是否正确
是否重启了 crowdsec 服务

7. 使用 UFW 和 iptables 时怎么选 bouncer?

我的服务器已经启用了 UFW,并且底层是 iptables。

UFW 和 CrowdSec 并不冲突:

UFW:管理基础端口开放,例如 22、80、443
CrowdSec:分析日志,判断恶意 IP
firewall bouncer:把恶意 IP 写入 iptables 进行封禁

查看 UFW 状态:

sudo ufw status verbose

查看 iptables 版本:

sudo iptables -V

如果确认使用 iptables,可以安装 iptables 版 bouncer:

sudo apt install crowdsec-firewall-bouncer-iptables

启动:

sudo systemctl enable --now crowdsec-firewall-bouncer

查看状态:

sudo systemctl status crowdsec-firewall-bouncer

查看 bouncer 是否注册成功:

sudo cscli bouncers list

8. UFW 规则仍然照常使用

例如:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status numbered

不建议用 UFW 手动维护 CrowdSec 的动态封禁 IP。

正确分工是:

UFW:固定开放端口
CrowdSec bouncer:动态封禁恶意 IP

9. 测试 CrowdSec 是否能产生封禁决策

手动添加一个测试封禁 IP。

这里使用文档测试网段 IP,不要随便封自己的真实 IP:

sudo cscli decisions add --ip 203.0.113.123 --duration 10m --reason "manual test"

查看封禁决策:

sudo cscli decisions list

正常会看到类似:

203.0.113.123    ban    manual test

这一步说明 CrowdSec 已经产生了 decision。


10. 测试 iptables bouncer 是否真正执行封禁

查看 iptables 规则:

sudo iptables -S | grep -i crowdsec

或者:

sudo iptables -L -n -v | grep -i crowdsec

如果 bouncer 使用 ipset,也可以查看:

sudo ipset list | grep -A 20 -i crowdsec

正常情况下,应该能看到类似:

CROWDSEC_CHAIN
crowdsec-blacklists
203.0.113.123

如果能在 iptables 或 ipset 中看到测试 IP,就说明 bouncer 已经正常接管防火墙封禁。

删除测试封禁:

sudo cscli decisions delete --ip 203.0.113.123

再次确认:

sudo cscli decisions list
sudo iptables -S | grep 203.0.113.123
sudo ipset list | grep 203.0.113.123

没有输出就说明测试封禁已经删除。


11. 谨慎测试封禁自己的公网 IP

如果要做真实连通性测试,可以临时封自己的 IP。

先查看当前 SSH 来源 IP:

echo $SSH_CLIENT

输出的第一个 IP 通常就是你的公网 IP。

然后开一个新的 SSH 窗口保持备用,不要关闭当前连接。

执行:

sudo cscli decisions add --ip 你的公网IP --duration 1m --reason "self test"

然后尝试新开一个 SSH 连接或访问网站,应该会被拦截。

测试完成后可以等待 1 分钟自动恢复,或者立即解封:

sudo cscli decisions delete --ip 你的公网IP

注意:

不要关闭当前 SSH 窗口
不要设置太长封禁时间
不要在没有其他登录方式的情况下测试

12. 测试 Nginx 恶意扫描检测

如果已经接入了 Nginx 日志,可以模拟一些常见扫描路径:

curl -I http://你的域名/.env
curl -I http://你的域名/.git/config
curl -I http://你的域名/wp-login.php
curl -I http://你的域名/phpmyadmin

然后查看告警:

sudo cscli alerts list

查看封禁决策:

sudo cscli decisions list

查看 CrowdSec 处理日志情况:

sudo cscli metrics

实时查看 CrowdSec 日志:

sudo journalctl -u crowdsec -f

注意:CrowdSec 不一定因为一次请求就立刻封禁。它通常会根据规则,在一定时间窗口内检测多次可疑行为后才触发封禁。


13. 常用管理命令

查看 CrowdSec 服务状态:

sudo systemctl status crowdsec

查看 firewall bouncer 状态:

sudo systemctl status crowdsec-firewall-bouncer

查看 CrowdSec 指标:

sudo cscli metrics

查看 bouncer:

sudo cscli bouncers list

查看告警:

sudo cscli alerts list

查看封禁列表:

sudo cscli decisions list

手动封禁 IP:

sudo cscli decisions add --ip 1.2.3.4 --duration 1h --reason "manual ban"

手动解封 IP:

sudo cscli decisions delete --ip 1.2.3.4

更新 Hub:

sudo cscli hub update
sudo cscli hub upgrade
sudo systemctl restart crowdsec

查看 CrowdSec 日志:

sudo journalctl -u crowdsec -f

查看 bouncer 日志:

sudo journalctl -u crowdsec-firewall-bouncer -f

14. 如果服务器在 Cloudflare 或反向代理后面

如果 Nginx access.log 记录的是 Cloudflare IP 或反代 IP,而不是真实访客 IP,那么 CrowdSec 可能会误判,甚至封禁 Cloudflare 节点。

需要先让 Nginx 记录真实 IP。

以 Cloudflare 为例,可以在 Nginx 中配置:

set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;

real_ip_header CF-Connecting-IP;
real_ip_recursive on;

然后查看 access log:

sudo tail -f /var/log/nginx/access.log

确认日志里出现的是真实用户 IP 后,再让 CrowdSec 分析 Nginx 日志。


15. 建议配合 Nginx 限速

CrowdSec 是“发现攻击后封禁”,Nginx 限速可以在请求进入时就做压制。

在 Nginx 的 http {} 中添加:

limit_req_zone $binary_remote_addr zone=global_limit:10m rate=10r/s;

在站点的 server {}location / {} 中添加:

limit_req zone=global_limit burst=30 nodelay;

检查配置:

sudo nginx -t

重载 Nginx:

sudo systemctl reload nginx

这样可以进一步降低高频请求、恶意扫描、简单 DoS 对服务器的影响。


16. 最小可用部署命令汇总

如果是 Ubuntu/Debian + Nginx + UFW + iptables,可以参考下面这组命令:

curl -s https://install.crowdsec.net | sudo sh
sudo apt update
sudo apt install -y crowdsec

sudo systemctl enable --now crowdsec

sudo cscli collections install crowdsecurity/nginx
sudo cscli collections install crowdsecurity/http-cve
sudo cscli collections install crowdsecurity/http-dos

sudo tee /etc/crowdsec/acquis.d/nginx.yaml > /dev/null <<'EOF'
filenames:
  - /var/log/nginx/access.log
  - /var/log/nginx/error.log
labels:
  type: nginx
EOF

sudo systemctl restart crowdsec

sudo apt install -y crowdsec-firewall-bouncer-iptables
sudo systemctl enable --now crowdsec-firewall-bouncer

sudo cscli metrics
sudo cscli bouncers list
sudo cscli decisions list

17. 测试命令汇总

sudo cscli bouncers list

sudo cscli decisions add --ip 203.0.113.123 --duration 10m --reason "manual test"

sudo cscli decisions list

sudo iptables -S | grep -i crowdsec

sudo ipset list | grep -A 20 -i crowdsec

sudo cscli decisions delete --ip 203.0.113.123

sudo cscli decisions list

18. 本次部署结论

最终采用的方案是:

UFW + iptables
CrowdSec 主程序
crowdsecurity/nginx collection
crowdsecurity/http-cve collection
crowdsecurity/http-dos collection
crowdsec-firewall-bouncer-iptables

没有使用:

crowdsec-nginx-bouncer

原因是系统中缺少可安装的:

libnginx-mod-http-lua

而使用 firewall bouncer 已经可以完成大部分公网 VPS 的防护需求。

最终效果:

SSH 爆破:可检测并封禁
Nginx 恶意扫描:可检测并封禁
HTTP CVE 探测:可检测并封禁
部分 HTTP DoS 行为:可检测并封禁
UFW 端口管理:继续正常使用
iptables 动态封禁:由 CrowdSec bouncer 负责

19. 推荐部署顺序

更稳妥的部署顺序是:

第一步:安装 CrowdSec
第二步:安装 nginx / http-cve / http-dos collections
第三步:配置 Nginx access.log 采集
第四步:安装 crowdsec-firewall-bouncer-iptables
第五步:测试手动 decision 是否能进入 iptables
第六步:观察 cscli metrics、alerts、decisions
第七步:再考虑是否加入 Nginx 限速或其他 WAF

这样配置比较清晰,也方便排查问题。


20. 一句话总结

CrowdSec 不是传统意义上的防火墙,而是一个日志分析和攻击识别引擎。
真正执行封禁的是 bouncer。

在普通 VPS 上,比较推荐的组合是:

UFW 管端口
CrowdSec 看日志
firewall bouncer 封 IP
Nginx limit_req 做限速

这套组合简单、稳定、容易回滚,适合用来防 SSH 爆破和 Nginx 恶意扫描。

 

相关推荐

评论功能已关闭