-
创建者:
虚拟的现实,上次更新时间:昨天11:47 上午 需要 2 分钟阅读时间
1. 简介
雷池开源版本升级到 9.4.3 后发现调整了防护站点的数量而我配置的二级域名超过了16个,无奈之下考虑了另一个 WAF 方案,通过 NPM 实现反向代理服务,结合 Crowdsec 的安全防护功能实现 WAF 防护。
该方案的难点在于:
- 我想保留 NPM 的官网版本不打算用其它的集成版本,主要原因是 Nginx 版本的升级可以保障
- Crowdsec 也使用官网版本,确保安全策略和组件能同步更新
- 同时我需要实现 WAF 和操作系统的防火墙功能联动对黑名单中的 IP 地址封禁。集成版本中包含了防火墙联动的功能但是独立的版本没有。所以这个组件直接引用第三方的分享版本
核心组件与职责分工:
Nginx Proxy Manager (nginx):负责对外提供 80/443 Web 访问及反向代理,并将访问日志实时写入宿主机卷。
CrowdSec 核心引擎 (crowdsec):以日志分析(Log Processor)模式运行,通过只读挂载实时消费 NPM 的 access.log,并执行内置 WAF 规则及自定义 Bot 拦截策略。
防火墙联动组件 (firewall-bouncer):通过宿主机网络模式与特权模式(network_mode: host, privileged: true),利用 ipset 与 iptables(绑定在 DOCKER-USER 链上),将 CrowdSec 生成的恶意 IP 决策直接在内核层进行 DROP 拦截。
控制台同步(可选):通过 ENROLL_KEY 环境变量实现与 CrowdSec 官方 Cloud Console 的无缝数据同步和看板展示。
2. 配置步骤
配置仍然使用容器的方案,由于需要联动防火墙能力,所以第三方分享的组件采用 host 网络模式直接使用宿主机的网络能力。
2.1. npm-compse-crowdsec.yaml
version: '3.8'
services:
nginx:
image: 'jc21/nginx-proxy-manager:2.16.0'
container_name: nginx
restart: unless-stopped
environment:
- DISABLE_IPV6=true
ports:
- '80:80' # Public HTTP Port
- '443:443' # Public HTTPS Port
- '82:81' # Admin Web Port
# - '21:21' # FTP
networks:
- proxy-net
volumes:
- /data/nginx-proxy/data:/data
- /etc/localtime:/etc/localtime:ro
- /data/nginx-proxy/ssl:/etc/letsencrypt
crowdsec:
image: docker.io/crowdsecurity/crowdsec:v1.8.2
container_name: crowdsec
restart: unless-stopped
ports:
- "127.0.0.1:8080:8080"
environment:
- COLLECTIONS=crowdsecurity/nginx crowdsecurity/http-cve
volumes:
- /data/nginx-proxy/data/logs:/var/log/nginx:ro
- /data/nginx-proxy/crowdsec-db:/var/lib/crowdsec/data
- /data/nginx-proxy/crowdsec-config:/etc/crowdsec
networks:
- proxy-net
firewall-bouncer:
image: ghcr.io/shgew/cs-firewall-bouncer-docker:stable
container_name: crowdsec-firewall-bouncer
restart: unless-stopped
environment:
- API_URL=http://crowdsec:8080
- API_KEY=5PcY+2S+wKTrew8X86DeYtihW1OiKv6lwxPTF8PL9XI
- BOUNCER_ITERATIVE_BAN=true
- DOCKER_LOGS=true
- FIREWALL_BACKEND=iptables # 适配 Photon OS 的 iptables 规则
volumes:
- /data/nginx-proxy/bouncer-config/crowdsec-firewall-bouncer.yaml:/config/crowdsec-firewall-bouncer.yaml:ro
network_mode: host
privileged: true
networks:
proxy-net:
driver: bridge
2.2. 关键日志采集设置
对应的日志采集文件设置为:/data/nginx-proxy/crowdsec-config/acquis.yaml
{"source": "file", "filename": "/var/log/nginx/*access.log", "labels": {"type": "nginx"}}
2.3. 自定义封禁规则
通过自定义封禁规则禁止 bot 的访问。对应的文件地址/data/nginx-proxy/crowdsec-config/scenarios/block-yisouspider.yaml
type: leaky name: custom/bad-user-agent-yisou description: "Detect and ban YisouSpider crawler" filter: "evt.Meta.http_user_agent contains 'YisouSpider'" groupby: "evt.Meta.source_ip" capacity: 2 leakspeed: "10s" blackhole: "24h" duration: "24h" labels: service: http type: bad-bot remediation: true
2.4. 创建 Bouncer 配置目录与文件
/data/nginx-proxy/bouncer-config/crowdsec-firewall-bouncer.yaml
mode: iptables pid_dir: /var/run/ update_frequency: 10s daemonize: false log_mode: stdout log_dir: /var/log/ log_level: info api_url: http://127.0.0.1:8080/ api_key: 5PcY+2S+wKTrew8X86DeYtihW1OiKv6lwxPTF8PL9XI populate_ipset: true iptables_chains: - DOCKER-USER - INPUT
3. 日常运维与快速验证指令
#重启并应用所有服务 docker compose -f /data/nginx-proxy/npm-compose-crowdsec.yml up -d --force-recreate #验证日志解析与规则触发 docker exec -it crowdsec cscli explain --log '[14/Nov/2026:22:33:54 +0800] - - 301 - GET http wiki.waringid.me "/techref/docs/pnpm.html" [Client 123.183.235.43] [Length 166] [Gzip -] [Sent-to 192.168.77.12] "YisouSpider" "-"' --type nginx #检查当前封禁决策列表 docker exec -it crowdsec cscli decisions list docker exec -it crowdsec cscli metrics #安装安全组件 docker exec -it crowdsec cscli collections install crowdsecurity/nginx docker exec -it crowdsec cscli collections install crowdsecurity/http-cve #检查本地引擎是否工作 docker exec -it crowdsec cscli machines list #查看已触发的告警列表 docker exec -it crowdsec cscli alerts list #查看已加载的场景列表 docker exec -it crowdsec cscli scenarios list #生成Bouncer API Key docker exec -it crowdsec cscli bouncers add firewall-bouncer-service #验证防火墙封禁插件(Bouncer)连接 docker exec -it crowdsec cscli bouncers list #查看防火墙 iptables -L DOCKER-USER -v -n docker exec -it crowdsec-firewall-bouncer ipset list crowdsec-blacklists-0 #查看命中情况 iptables -L CROWDSEC_CHAIN -v -n #查看日志 docker logs -f --tail 50 crowdsec-firewall-bouncer #查看是否已启用全球情报共享 grep -i "online_api" /data/nginx-proxy/crowdsec-config/config.yaml docker exec -it crowdsec cscli decisions list


4. 参考
在 CrowdSec 的底层架构设计中,IP 封禁列表(Decisions)是分来源和协议分类管理的。具体的分布情况如下:
crowdsec-blacklists-0:这是本地 CrowdSec 引擎(Local Engine)通过日志检测并触发的 IPv4 黑名单集合(例如自定义的 custom/bad-user-agent-yisou 规则所拉黑的本地爬虫 IP 就存放在这里)。
crowdsec-blacklists-1(及其他后续编号):这是由中央威胁情报(CAPI / CrowdSec Central API)同步过来的全球共享黑名单集合。如果开启了 CAPI 社区情报共享,这里还会包含海量的全球已知恶意 IP。
crowdsec6-blacklists-*:这是对应的 IPv6 黑名单集合(专门用来拦截 IPv6 地址的恶意访问)。
- 无标签

添加评论