![图片[1]-从零搭建 NPM + CrowdSec 极简 WAF:1G 内存 VPS 上的低功耗商业级防御与 Telegram 随身运维中心](https://zwn.cc/wp-content/uploads/2026/10/20261008212737976-npm_crowdsec_cover_1791465520021-tic.webp)
一、 系统架构与性能账本:为什么选择这套组合?
1.1 1GB 内存硬件账本
| 组件 / 进程 | 物理内存占用 | 作用与定位 |
|---|---|---|
| Linux 系统内核 + Docker 守护进程 | 约 180MB ~ 250MB | 操作系统基础底噪 |
| NPM (Nginx + Node.js 核心) | 约 150MB ~ 220MB | 图形化反向代理、SSL 证书自动续签 |
| CrowdSec 核心守护进程 (Go 语言) | 约 50MB ~ 80MB | 高性能日志入侵检测、决策下发 |
| nftables 防火墙阻断器 (Bouncer) | 约 15MB ~ 30MB | 底层内核级丢弃恶意数据包 (DROP) |
| Telegram Sentinel 机器人 (Python) | 约 14MB ~ 18MB | 移动端交互控制台(纯标准库) |
| 系统剩余缓冲内存 (Available RAM) | 约 400MB ~ 500MB | 安全冗余,绝不触发 OOM 崩溃 |
1.2 整体防御架构图
外部流量 (HTTP/HTTPS)
│
▼
┌────────────────────────────────────────────────────────┐
│ Linux 宿主机网络栈 (nftables 防火墙) │
│ ├─ [CAPI 云端 2万黑名单 IP] ──► 内核直接 DROP (零开销) │
│ ├─ [本地决策黑名单 IP] ──► 内核直接 DROP (连接超时) │
│ └─ [正常访客流量] ──► 本地端口 (80/443, host) │
└──────────────────────┬─────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ NPM 容器 (Nginx Proxy Manager) │
│ ├─ SSL 证书卸载与业务转发 ──► 后端站点 / 业务容器 │
│ └─ 流式输出访问日志 ──► /home/docker/npm/data/logs/*│
└──────────────────────┬─────────────────────────────────┘
│ (毫秒级文件轮询监听)
▼
┌────────────────────────────────────────────────────────┐
│ CrowdSec 守护进程 (检测大脑) │
│ ├─ 规则集匹配 (CVE / 嗅探 / 0容忍瞬发触发器) │
│ ├─ 阻断决策下发 ──► 注入宿主机 nftables 集合 │
│ ├─ 威胁情报上报 ──► CrowdSec 云端大屏 (0MB 本地开销) │
│ └─ SQLite 数据库 ──► 毫秒级提供本地取证报文 │
└──────────────────────┬─────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────────────┐
│ Telegram 威胁情报中心 3.0 (口袋 SOC) │
│ ├─ 3×3 九宫格大屏 (系统大屏 / 攻击态势 / 最新拦截) │
│ ├─ 深度威胁分析 (Top 10 黑客榜单 / Top 10 漏洞靶心) │
│ ├─ 刑侦级报文穿透 (调阅原始 HTTP 请求、URL 与指纹 UA) │
│ └─ 交互式处置卡片 (手机端 1 键误杀解封 / 1 键永久加白) │
└────────────────────────────────────────────────────────┘
二、 第一阶段:Nginx Proxy Manager 规范化部署
2.1 准备目录结构
登录 VPS(推荐 Ubuntu 22.04/24.04 或 Debian 11/12),创建专属部署目录:
sudo mkdir -p /home/docker/npm/data
sudo mkdir -p /home/docker/npm/letsencrypt
cd /home/docker/npm
2.2 编写 docker-compose.yml(关键避坑:Host 网络模式)
⚠️ 致命避坑点:若使用默认 Bridge 桥接模式映射端口(如
- 80:80),Docker 底层的docker-proxy与 DNAT 会在数据包进入宿主机防火墙INPUT链之前就强行截胡转发,导致 CrowdSec 注入宿主机的防火墙黑名单被直接绕过!反向代理必须采用network_mode: host!
创建 docker-compose.yml:
sudo cat << 'EOF' > /home/docker/npm/docker-compose.yml
services:
app:
image: 'jc21/nginx-proxy-manager:latest'
container_name: npm
restart: unless-stopped
# 核心:使用 host 网络模式,彻底杜绝防火墙被绕过并保留真实客户端真实 IP
network_mode: host
volumes:
- ./data:/data
- ./letsencrypt:/etc/letsencrypt
environment:
- DISABLE_IPV6=false
EOF
启动 NPM:docker compose up -d
启动完成后,通过浏览器访问 http://<服务器IP>:81 进入后台(默认账号:admin@example.com,密码:changeme),根据引导修改管理员邮箱与强密码,配置好反向代理域名与 SSL 证书。
三、 第二阶段:CrowdSec 引擎与底层防火墙阻断器安装
我们将 CrowdSec 和防火墙阻断器直接原生安装在宿主机上,最直接、最高效地接管 Linux 内核级防火墙。
3.1 安装 CrowdSec 核心引擎
# 导入官方源脚本
curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
# 安装 crowdsec
sudo apt-get update
sudo apt-get install -y crowdsec
3.2 安装 nftables 防火墙阻断器 (Bouncer)
sudo apt-get install -y crowdsec-firewall-bouncer-nftables
# 检查服务状态
sudo systemctl status crowdsec-firewall-bouncer --no-pager
看到 active (running) 说明防火墙“打手”已经就位!
3.3 对接 NPM 日志采集(通配符与官方 Parser 关键点)
NPM 会为每个 Proxy Host 独立生成日志(例如 proxy-host-7_access.log)。我们需要让 CrowdSec 动态监控整个日志目录。
⚠️ 血泪避坑点:采集标签绝不能随性自定义为 type: npm-custom!
CrowdSec 官方针对 NPM 特殊日志格式(IP 包裹在 [Client x.x.x.x])的解析器严格依据 type: nginx-proxy-manager 进行路由匹配。若写错标签,日志会在解析流水线第 1 步被 100% 静默丢弃,导致后续规则永远无法触发!
编辑日志采集配置:
sudo cat << 'EOF' > /etc/crowdsec/acquis.yaml
filenames:
- /home/docker/npm/data/logs/*_access.log
- /home/docker/npm/data/logs/default-host_access.log
- /home/docker/npm/data/logs/fallback_access.log
labels:
type: nginx-proxy-manager # 核心:必须声明为 nginx-proxy-manager
---
filenames:
- /var/log/auth.log
labels:
type: syslog
EOF
重启 CrowdSec 载入日志采集:sudo systemctl restart crowdsec
四、 第三阶段:装配黄金 WAF 规则舰队与 0 容忍秒封规则
4.1 一键装配推荐规则集
更新官方 Hub 索引并批量安装最强防御规则包:
# 更新规则索引
sudo cscli hub update
# 1. 核心底座:必须安装 NPM 专属日志解析器(否则无法提取真实 IP)
sudo cscli collections install crowdsecurity/nginx-proxy-manager
# 2. Web 核心与通用 CVE 漏洞防御
sudo cscli collections install crowdsecurity/base-http-scenarios
sudo cscli collections install crowdsecurity/http-cve
sudo cscli collections install crowdsecurity/http-dos
# 3. 合规爬虫与白名单(防止 Google/Bing/Baidu 蜘蛛被误封)
sudo cscli collections install crowdsecurity/whitelist-good-actors
# 4. 主机级防护(SSH 22 端口防撞库与 Linux 提权审计)
sudo cscli collections install crowdsecurity/sshd
sudo cscli collections install crowdsecurity/linux
# 5. 可选:针对 WordPress 的专项防御(若有 WP 站点推荐安装)
sudo cscli collections install crowdsecurity/wordpress
4.2 配置防报错白名单模板
为了避免解析器加载空文件报错,我们先初始化一个标准的 IP 白名单:
sudo cat << 'EOF' > /etc/crowdsec/parsers/s02-enrich/tg-whitelist.yaml
name: custom/tg-whitelist
description: "Whitelist trusted IPs"
whitelist:
reason: "Admin manual whitelist"
ip:
- "127.0.0.1"
- "::1"
EOF
4.3 打造自研 0 容忍瞬发触发器(秒杀定向扫描器)
💡 核心设计:官方规则为了避免误伤,通常使用“漏桶算法(需要累计命中 5~10 次才封禁)”。但针对如
pearcmd(PHP 包含)、目录穿越、.env探针、phpmyadmin等行为,正常人类绝不可能访问。我们配置type: trigger,实现首发请求当场秒封 4 小时!
创建自定义场景 /etc/crowdsec/scenarios/strict-path-traversal.yaml:
sudo cat << 'EOF' > /etc/crowdsec/scenarios/strict-path-traversal.yaml
type: trigger
name: custom/strict-path-traversal
description: "0-Tolerance Instant Ban for Path Traversal and Sensitive Probing"
filter: "evt.Meta.log_type == 'http_access-log' && evt.Parsed.request != nil && evt.Parsed.request matches '(?i)(/[.]|[.][.]|pearcmd|phpmyadmin|actuator|pma)'"
groupby: "evt.Meta.source_ip"
blackhole: 1m
labels:
service: http
type: exploit
remediation: true
EOF
语法排坑细节:
remediation: true必须严格缩进在labels:内部,写在根节点会引发 Go struct unmarshal 致命崩溃;- 正则使用
/[.]与[.][.]匹配点号,杜绝 YAML 与 Goexpr引擎的双重反斜杠转义冲突(invalid char escape);- 必须包含
groupby: "evt.Meta.source_ip",系统才能准确提取出攻击者 IP 并实施精准拉黑。
执行配置自检并热重载:sudo crowdsec -t && sudo systemctl reload crowdsec
终端显示
configuration is valid即代表规则 100% 编译成功!
五、 第四阶段:云端大屏与原生告警联动
5.1 接入 CrowdSec 官方云端控制台(0MB 本地内存开销)
- 访问并注册 CrowdSec Console (app.crowdsec.net);
- 在控制台左侧点击 Security Engines ➡️ Enroll Engine,复制生成的注册密钥;
- 在 VPS 终端执行接入命令:
sudo cscli console enroll <你的EnrollKey> - 回到网页端点击 Accept 批准。在手机浏览器打开该网址并「添加到主屏幕」,即刻拥有一款精美且零本地开销的全球威胁大屏 PWA。
六、 第五阶段:主机 SSH 哨兵与防刷屏防抖治理
为了防止服务器被未授权登录,我们可以配置 SSH 登录实时推送。
⚠️ 致命刷屏陷阱:使用 FinalShell、VS Code Remote-SSH、Termius 等工具时,其后台每隔 2~5 秒就会偷偷发起一次免密 SSH 连接去采集服务器 CPU/内存状态。如果直接写脚本,Telegram 会被瞬间刷屏千条!必须加入 TTY 终端校验与 10 分钟冷却防抖缓存!
编辑 /etc/ssh/sshrc:
sudo cat << 'EOF' > /etc/ssh/sshrc
#!/bin/sh
# 1. 严格过滤非交互式连接(彻底屏蔽 FinalShell 状态探针与 SFTP 轮询)
[ -z "$SSH_TTY" ] && exit 0
CLIENT_IP=$(echo $SSH_CONNECTION | awk '{print $1}')
LOGIN_USER=$(whoami)
LOGIN_DATE=$(date "+%Y-%m-%d %H:%M:%S")
# 2. 10 分钟 (600秒) 同一 IP 冷却防抖
LOCK_FILE="/tmp/.ssh_alert_${CLIENT_IP}"
NOW=$(date +%s)
COOLDOWN=600
if [ -f "$LOCK_FILE" ]; then
LAST_TIME=$(cat "$LOCK_FILE" 2>/dev/null || echo 0)
DIFF=$((NOW - LAST_TIME))
if [ "$DIFF" -lt "$COOLDOWN" ]; then
exit 0
fi
fi
echo "$NOW" > "$LOCK_FILE"
# 3. 发送告警(替换为您的 Token 与 Chat ID)
BOT_TOKEN="你的_BOT_TOKEN"
CHAT_ID="你的_CHAT_ID"
curl -s -X POST "https://api.telegram.org/bot${BOT_TOKEN}/sendMessage" \
-H "Content-Type: application/json" \
-d "{
\"chat_id\": \"${CHAT_ID}\",
\"text\": \"🚨 <b>【VPS SSH 登录提醒】</b>\n━━━━━━━━━━━━━━━━━━\n• <b>登录用户:</b> <code>$LOGIN_USER</code>\n• <b>来源 IP:</b> <code>$CLIENT_IP</code>\n• <b>登录时间:</b> <code>$LOGIN_DATE</code>\n━━━━━━━━━━━━━━━━━━\n<i>如果非本人操作,请立刻检查服务器!</i>\",
\"parse_mode\": \"HTML\"
}" > /dev/null 2>&1 &
EOF
sudo chmod +x /etc/ssh/sshrc
七、 第六阶段:Telegram 威胁情报中心 3.0(口袋 SOC)
我们全面重构了 Python 机器人,打造 威胁情报中心 3.0:
- 100% 依赖 Python 3 标准库:无任何 pip 依赖,常驻物理内存仅 15MB 左右;
- 原生命令菜单联想:自动注入
setMyCommands,在 TG 聊天框输入/即可弹出全中文操作提示; - 反向游标日志抽样(防 OOM 核心):单站点日志即使膨胀到 28MB+,每次也仅流式读取末尾 512KB 分块做反向聚合,CPU 占用瞬间 < 3%,内存零抖动;
- 刑侦级报文穿透:直接调阅底层 HTTP 请求路径、User-Agent 客户端指纹与归属地;
- 卡片内嵌快捷处置:拦截告警直接携带
[🔓 一键解封]与[🛡️ 永久加白]Inline 按钮。
7.1 编写守护脚本 /usr/local/bin/crowdsec_bot.py
7.2 配置 Systemd 开机自启服务
sudo chmod +x /usr/local/bin/crowdsec_bot.py
sudo cat << 'EOF' > /etc/systemd/system/crowdsec-tg-bot.service
[Unit]
Description=CrowdSec Telegram Threat Intelligence Bot 3.0
After=network.target crowdsec.service
[Service]
Type=simple
User=root
ExecStart=/usr/bin/python3 /usr/local/bin/crowdsec_bot.py
Restart=always
RestartSec=5s
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable --now crowdsec-tg-bot.service
八、 第七阶段:全链路攻防实测与三大避坑锦囊
一切就绪后,我们来执行完整的闭环验证。
8.1 零风险“显微镜”冒烟测试(无需碰公网)
CrowdSec 内置了强大的离线流水线回放工具 cscli explain,可以在本地瞬间完成冒烟验证:
echo '[09/Oct/2026:12:00:00 +0000] - 404 404 - GET http test.com "/.env" [Client 198.51.100.99] [Length 162] [Gzip -] "curl/7.68.0" "-"' | sudo cscli explain --type nginx-proxy-manager -f -
全绿验收标准:
s01-parse中🟢 crowdsecurity/nginx-proxy-manager-logs显示绿色;- 结算显示
├-------- parser success 🟢; - 底部场景显示
🟢 custom/strict-path-traversal命中!
8.2 实弹射击与「Happy Eyeballs」避坑
⚠️ 高危提醒:千万不要用正在连 SSH 的电脑测试!拿起手机,关闭 Wi-Fi,用 4G/5G 蜂窝数据访问:
http://你的域名/.env
验证闭环:
- Telegram 手机端:1 秒内弹出【突发威胁阻断】卡片,附带手机运营商 IP、归属地与解封按钮;
- 手机端访问:刷新页面立刻无限超时转圈(内核级 DROP 生效);
- 一键恢复:在手机 TG 告警卡片上直接点击
[🔓 一键解封此 IP],手机访问瞬间满血复活!
避坑:为什么在电脑上 curl 被封后再次执行还能通?(RFC 8305 双栈回退)
如果你在 Windows 上再次运行 curl -I "https://你的域名/?test=pearcmd",发现居然返回了 200,不要误以为没封住!
- 底层机制:Windows 启用了 RFC 8305「快乐眼球 (Happy Eyeballs)」算法。电脑默认走 IPv6,当 IPv6 被 nftables 丢弃后,系统仅用 250ms 就自动降级回退到了 IPv4 连接!
- 铁证检验:强制指定 IPv6 请求:
curl -6 -I "https://你的域名/?test=pearcmd",此时连接将彻底卡死超时,证明底层封杀万无一失!
8.3 终极排错锦囊:为什么刚部署完没有攻击记录?
如果系统刚上线时一条告警都没有,请参照以下三点排查:
- 查验核心解析率:运行
sudo cscli metrics。- 查看
Acquisition Metrics与Parser Metrics:若Lines read == Lines parsed且Lines unparsed为-(0行),说明解析率 100%。没有告警是因为进入的都是正常用户的 200 请求,零误杀是系统最健康的表现!
- 查看
- CAPI 2万黑名单在内核层无声守护:
cscli metrics中的CAPI (community blocklist: 19.94k IPs)已经为你提前拦截了公网上两万个最臭名昭著的扫描器。这些机器人在握手阶段就被内核直接 DROP,根本进不了 NPM,自然不会产生日志。
- 时区差陷阱:
- NPM 容器内部固定使用 UTC 协调世界时(比北京时间慢 8 小时)。北京时间晚上 19:00 的日志,在日志里记录的是
11:00,检索当天日志时请注意换算时区。
- NPM 容器内部固定使用 UTC 协调世界时(比北京时间慢 8 小时)。北京时间晚上 19:00 的日志,在日志里记录的是
九、 第八阶段:全自动无人值守维护与总结
9.1 规则库每日自动更新
通过 Crontab 定时在每天凌晨 04:30 自动拉取最新的社区恶意特征:sudo crontab -e
追加一行:30 4 * * * /usr/bin/cscli hub update && /usr/bin/cscli hub upgrade && /bin/systemctl reload crowdsec > /dev/null 2>&1
总结与工程价值
回顾整套工程实践,我们用极简优雅的架构实现了惊人的低功耗奇迹:
- 极致轻量:全套组件总物理内存占用牢牢压在 380MB 以内,即使在最廉价的 1GB 内存 VPS 上,仍留有近 500MB 缓冲空间,彻底告别 OOM 宕机恐惧;
- 铜墙铁壁:通过
network_mode: host堵死了 Docker 绕过宿主机 INPUT 链的致命漏洞;结合自研 0 容忍触发器与 CAPI 2 万黑名单,黑客的初次扫描即被立地正法; - 掌中掌控:宏观上通过 CrowdSec Console 查看全球威胁地图,微观上通过 Telegram 九宫格随时体检、一键释放内存、调阅黑客榜单与原始报文取证,真正实现了“轻量省心、人在外面走、安全掌中控”!








![表情[doge]-造物ZAOWU](https://zwn.cc/wp-content/themes/zibll/img/smilies/doge.gif)
![表情[xieyanxiao]-造物ZAOWU](https://zwn.cc/wp-content/themes/zibll/img/smilies/xieyanxiao.gif)
![表情[touxiao]-造物ZAOWU](https://zwn.cc/wp-content/themes/zibll/img/smilies/touxiao.gif)
暂无评论内容