
我们的网站近段时间频繁出现异常请求暴增,尤其是在凌晨时段。经日志分析,源头大多来自全球代理池、高匿名VPS,集中进行端口扫描、弱口令爆破与目录探测。一开始我尝试通过 Fail2Ban 和防火墙手动封禁 IP,但效果有限且响应不及时。最终我在香港服务器上构建了一套“动态防爆破联动机制”,实现了端口级封锁、高频行为感知、黑名单共享与自动联动防御。以下是完整的实操流程。
一、架构目标与整体策略
我的核心目标有三点:
- 自动阻断:对SSH、RDP、HTTP等端口的爆破行为秒级封禁。
- 行为联动:高频访问(例如1分钟超过500次请求)的IP实时加入黑名单。
- 横向扩展:支持多台香港服务器之间共享恶意IP库,联防联控。
基于这些需求,我采用如下技术架构:
- 入侵感知层:基于 iptables + xt_recent、Fail2Ban 和自定义Nginx日志规则。
- 黑名单协同层:通过 Redis 或 ELK 聚合高频IP,结合 Python 脚本动态同步。
- 执行阻断层:集成 firewalld 与 ipset 实现秒级封禁 & 快速回收。
架构图如下:
[Agent服务器] ─┐
├─> 日志分析器(Fail2Ban/Nginx日志) ─┐
[Web服务器] ───┘ │
▼
[黑名单汇总 Redis/ELK]
│
封禁执行器(ipset / firewalld)
二、端口爆破防御实战配置
1. SSH 爆破防护(Fail2Ban)
我在香港CentOS服务器上启用了Fail2Ban专用于SSH:
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/secure
maxretry = 3
findtime = 600
bantime = 86400
action = firewallcmd-ipset[name=sshban, port=ssh, protocol=tcp]
然后添加 IPSet 支持:
firewall-cmd --permanent --new-ipset=sshban --type=hash:ip
firewall-cmd --permanent --zone=public --add-source=ipset:sshban
firewall-cmd --reload
这样,一旦某个IP连续失败登录3次以上,就会被封禁24小时。
2. Nginx 异常请求检测(高频访问)
在 Nginx 日志中添加 req_id 和真实 IP 记录字段:
log_format abuse '$remote_addr [$time_local] "$request" '
'status=$status body=$body_bytes_sent '
'ua="$http_user_agent" ref="$http_referer"';
access_log /var/log/nginx/access.log abuse;
配合一个简单的 Python 脚本进行分析:
from collections import defaultdict
import time, re
def detect_abuse(log_path):
ip_count = defaultdict(int)
now = time.time()
with open(log_path) as f:
for line in f:
m = re.search(r'(\d+\.\d+\.\d+\.\d+)', line)
if m:
ip = m.group(1)
ip_count[ip] += 1
for ip, count in ip_count.items():
if count > 500:
add_to_ipset(ip)
def add_to_ipset(ip):
cmd = f"ipset add httpban {ip} -exist"
os.system(cmd)
我将该脚本通过 cron 每分钟运行一次,实现动态封锁访问量异常的 IP。
三、高频IP联动黑名单机制
1. Redis 黑名单池构建
所有被Fail2Ban、Nginx检测封禁的IP会统一写入 Redis,格式如下:
SET banned_ip:1.2.3.4 "{\"source\": \"nginx\", \"reason\": \"high freq\", \"ttl\": 86400}"
并使用过期机制实现自动解封。
2. 多服务器联动同步
我用一个轻量级同步脚本实现 Redis 中黑名单同步到所有服务器:
#!/bin/bash
IPSET_NAME=httpban
redis-cli --scan --pattern 'banned_ip:*' | while read key; do
ip=${key#banned_ip:}
ipset add $IPSET_NAME $ip -exist
done
可通过 crontab 每分钟拉取:
* * * * * /opt/scripts/redis_blacklist_sync.sh
也可升级为基于 [Redis Pub/Sub] 的实时推送。
四、横向防御拓展建议
1. xt_recent 限制同IP频繁连接:
iptables -A INPUT -p tcp --dport 80 -m recent --name portscan --set
iptables -A INPUT -p tcp --dport 80 -m recent --name portscan --update --seconds 60 --hitcount 100 -j DROP
此方式可以在连接层快速阻断高频扫描器。
2. WAF联动(如使用 openresty + lua)
在 Nginx 中引入 Lua 实现共享黑名单逻辑:
local ip = ngx.var.remote_addr
local redis = require "resty.redis"
local red = redis:new()
red:connect("127.0.0.1", 6379)
local res = red:get("banned_ip:" .. ip)
if res and res ~= ngx.null then
ngx.exit(403)
end
适合对接 Redis 动态 IP 库,尤其在有多台香港服务器协作的环境中。
五、效果验证与实战经验
部署之后,我监测到以下变化:
- SSH爆破尝试从每天3000+下降至个位数。
- 高频IP响应时间从平均20分钟缩短为60秒内自动拉黑。
- 整体业务稳定性提升,误封率控制在万分之一以下。
经验总结:
- Fail2Ban适合处理稳定日志格式的暴力行为;
- Nginx日志分析 + IPSet 是应对Web探测的利器;
- Redis 作为黑名单中心节点,可平滑扩展到多机环境;
- IPSet 封禁速度快于 iptables,适合高频联动策略。
在面对恶意扫描和端口爆破时,光靠人工响应远远不够。通过 Fail2Ban、Nginx 行为感知、Redis黑名单同步与 ipset 快速封锁,我在香港服务器上构建了一套高效、自适应的联动防御体系。如果你也在运营重要的API或对外服务,不妨从这些思路出发,搭建自己的智能防爆破机制。











