返回首页

1.8GB 内存的 VPS,被扫了 600 次后,我给它装了套全自动反导系统

1.8GB 内存的 VPS,被扫了 600 次后,我给它装了套全自动反导系统

大家好,我是老张。

事情是这样的——我有一台阿里云 VPS,1.8GB 内存,上面跑着博客、数据库、Nginx,还挂了一套 Prometheus 监控。

某天闲着没事翻了翻 Nginx 日志,好家伙,差点以为自己开了个蜜罐。

今天聊一个老张亲身实践的运维小项目——从日志分析到全自动封禁,给个人博客搞一套企业级安全防线。全免费,1.8GB 内存也跑得动。


📊 先看攻击者有多嚣张

跑了两条命令:

# 谁在敲门
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head

# 敲的是哪扇门
grep -E '\.env|\.git|wp-admin|\.php' access.log | awk '{print $1,$7}' | sort | uniq -c | sort -rn

结果直接给我看傻了:

攻击类型次数
PHP 漏洞扫描(ops.php、mac.php 等已知后门)529 次
WordPress 漏洞(wp-admin、wp-config)64 次
工具探测(phpmyadmin、adminer、xmlrpc)4 次
文件泄露(.env、.git)被安全规则拦截

头号选手 20.104.96.117——微软 Azure 的 IP,一个人扫了 520 次,系统化地挨个试 PHP 后门和 WordPress 漏洞。

这帮人不是盯上我了,是全网撒网,谁的 80/443 端口开着就扫谁。


🛡️ 第一道防线:Nginx 堵门

上来先把 Nginx 调到战斗状态。

性能 + 安全基线

server_tokens off;                          # 不告诉你版本
ssl_protocols TLSv1.2 TLSv1.3;             # 老 TLS 关掉
access_log ... buffer=32k flush=5s;         # 缓冲写日志,省 IO
open_file_cache max=1000 inactive=20s;      # 缓存文件句柄

恶意请求直接 444

444 是什么? Nginx 自定义状态码,连接直接断开,连个错误页面都不给。扫你的人看到的就是黑洞。

# 拦截已知恶意路径
location ~* \.(env|git|svn|hg|sql|bak)$ { return 444; }
location ~* /(wp-admin|phpmyadmin|adminer|xmlrpc) { return 444; }

# 拦截扫描器 User-Agent
if ($http_user_agent ~* (nmap|sqlmap|nikto|nessus|acunetix)) {
    return 444;
}

三层限速

# 登录接口——5 次/分钟
limit_req_zone $binary_remote_addr zone=blog_login:10m rate=5r/m;

# API——30 次/秒
limit_req_zone $binary_remote_addr zone=blog_api:10m rate=30r/s;

# 普通请求——60 次/秒
limit_req_zone $binary_remote_addr zone=blog_general:10m rate=60r/s;

设计逻辑很简单:静态规则堵已知特征 → 动态限速防暴力 → 剩下漏网的交给下一环。


📡 第二道防线:Prometheus 当眼睛

Nginx 拦住了一部分,但攻击者还会换着花样来。得有人盯着。

用 Python 写了个轻量指标导出器,60 秒扫一次 access.log,统计各种攻击模式:

nginx_scan_total{type="scan_php_exploit"} 529
nginx_scan_total{type="scan_wordpress"} 64
nginx_top_ip{ip="20.104.96.117"} 520       # 就这个老六

暴露到 Prometheus 后,配上告警规则:

# 扫描速率超标 → 告警
- alert: HighScanActivity
  expr: rate(nginx_scan_total[5m]) > 5

# 单 IP 请求超 100 持续 5 分钟 → 拉黑
- alert: SuspiciousTopIP
  expr: nginx_top_ip > 100
  for: 5m

🔄 第三道防线:自动封禁流水线

这是最爽的部分——告警出来以后不用我动手。

攻击者 → Nginx → 日志 → Python 导出器(9916)
                          ↓
                     Prometheus(9091)
                          ↓ 触发告警
                     Alertmanager(9093)
                          ↓ webhook
                     自动封禁服务(9917)
                          ↓ nginx -t && reload
                     blocked_ips.conf

Alertmanager 接到 SuspiciousTopIP 告警后,直接 POST 到自动封禁服务:

# 1. 提取 IP
# 2. 内网 IP 自动跳过(127.x / 10.x / 192.168.x)
# 3. 写入 blocked_ips.conf,已有则去重
# 4. nginx -t 校验(防止手滑配错炸站)
# 5. systemctl reload nginx
# 6. 写封禁日志

一句话:扫描器上一秒还在拼命请求,下一秒直接撞墙。

验证一下:

curl -X POST :9917/alert -d '{"alerts":[{"labels":{"ip":"8.136.189.162"}}]}'
# {"blocked": ["8.136.189.162"]}

cat /etc/nginx/blocked_ips.conf
# deny 20.104.96.117;
# deny 172.170.251.50;
# deny 8.136.189.162;

💡 踩过的坑

1. prometheus-nginxlog-exporter 版本坑 ——v1.11.0 不支持无配置自动生成指标,还得写 HCL。干脆自己写 Python 方案,多占 25MB 内存,换来完全可控。

2. logrotate 和监控要配合好 ——导出器每次打开当前 access.log,不依赖文件指针,日志切割不受影响。


🎯 效果

维度之前之后
恶意请求Nginx 正常处理444 直接断连
高频 IP无感知,随便扫超过阈值自动封禁
安全态势一片黑,不知道被扫Prometheus 面板一目了然
响应速度人工发现→手动封告警→封禁→reload,秒级

🚀 还能加什么

  • Alertmanager 接飞书通知(封了谁告诉你一声)
  • Grafana 面板展示攻击态势
  • 接入 AbuseIPDB 交叉验证(别误伤好人)
  • 封禁自动过期(7 天解封,防止 IP 回收后误伤)

💬 聊聊你的

你的服务器被扫过吗?用了什么方案?

是上 Cloudflare WAF 一键解决,还是像老张这样自己搓一套?

评论区聊聊,有踩坑经验的一起交流。


1.8GB 的 VPS 也能有企业级防护。核心就五个字:堵门、限速、盯、报、打

A

Admin

用文字记录生活与思考。

评论 (0)
暂无评论,来抢沙发吧
1.8GB 内存的 VPS,被扫了 600 次后,我给它装了套全自动反导系统 | 山外云的Vlog