在阿里云 ECS 环境下,防止特定 IP 频繁访问(即防刷、防暴力破解或限制并发连接数),通常有“网络层拦截”和“应用层限流”两个维度的解决方案。根据你对延迟敏感度、配置复杂度以及是否需要保留日志的需求,可以选择以下几种主流做法:
1. 最推荐:使用云盾安全组 + 自动封禁策略(基础防护)
这是最简单且无需修改代码的方式,适合应对明显的恶意扫描或低频暴力破解。
- 操作逻辑:
- 进入 ECS 控制台 -> 实例详情页 -> 安全组。
- 编辑入方向规则,默认允许所有 IP 访问(或仅允许特定网段)。
- 关键点:阿里云本身没有直接的“IP 频率封禁”功能,但你可以结合 云监控 或 堡垒机 的告警来手动封禁。
- 更优解:如果流量较大,建议直接使用 WAF(Web 应用防火墙) 或 DDoS 高防。WAF 内置了 CC 攻击防护规则,可以针对 URL 路径设置 IP 频率限制(例如:单个 IP 每秒最多请求 10 次),超出后直接返回 403 或验证码。
适用场景:网站被 CC 攻击、API 接口被爬取。
优点:阿里云原生支持,配置简单,自带威胁情报库。
缺点:需要额外费用(WAF/高防按量付费或包年包月)。
2. 低成本方案:Nginx + fail2ban / iptables(服务器内部实现)
如果你不想购买 WAF,可以在 ECS 内部通过软件实现动态封禁。这是技术圈最常用的方式。
方案 A:Nginx 日志分析 + fail2ban(经典组合)
fail2ban 是一个守护进程,它会监控系统日志文件(如 /var/log/nginx/access.log),当检测到某个 IP 在短时间内失败次数过多时,自动调用 iptables 或 firewalld 将其加入黑名单。
步骤简述:
-
安装 fail2ban:
yum install fail2ban -y # CentOS/RHEL apt install fail2ban -y # Ubuntu/Debian -
配置 Nginx 过滤规则:
创建或编辑/etc/fail2ban/jail.local,添加如下内容:[nginx-limit-req] enabled = true port = http,https filter = nginx-limit-req logpath = /var/log/nginx/access.log maxretry = 5 # 允许最大重试次数 bantime = 3600 # 封禁时间(秒),这里设为1小时 findtime = 60 # 时间窗口(秒),60秒内触发则封禁 -
创建过滤器定义:
在/etc/fail2ban/filter.d/nginx-limit-req.conf中写入匹配规则(需根据你的 Nginx 错误日志格式调整):[Definition] failregex = ^ .* "GET .* HTTP/.*" (499|500) .*$ ^ .* "POST .* HTTP/.*" (499|500) .*$ ignoreregex = -
重启服务:
systemctl restart fail2ban systemctl enable fail2ban
注意:此方法依赖日志解析,有一定延迟(取决于日志刷新频率),且对高并发场景下 CPU 开销略大。
方案 B:Nginx 原生限流 + 动态 IP 管理
利用 Nginx 的 limit_req_zone 模块进行软限流,配合脚本定期清理被封 IP。
http {
# 定义限流区域:10MB内存存储,每分钟每个IP不超过10个请求
limit_req_zone $binary_remote_addr zone=one:10m rate=10r/m;
server {
location / {
limit_req zone=one burst=5 nodelay;
# 超过限制返回 403
limit_req_status 403;
}
}
}
如果需要完全封禁而非仅返回 403,可结合 Lua 模块(OpenResty)或外部脚本调用 iptables。
3. 高级方案:使用 Redis + 滑动窗口算法(应用层限流)
如果你的业务是 API 服务,且对精度要求极高(比如精确到每秒 5 次),建议在应用代码层面实现。
核心思路:
- 客户端每次请求时,后端从 Redis 获取该 IP 的计数器。
- 使用 Redis 的
INCR命令增加计数,并设置过期时间(如 60 秒)。 - 如果计数 > 阈值,则拒绝请求。
- 同时,将高频 IP 加入一个“临时黑名单”集合,设置较短 TTL(如 5 分钟),后续请求直接由网关或应用层拦截。
伪代码示例(Python/Flask):
import redis
from flask import request, jsonify
redis_client = redis.Redis(host='localhost', port=6379, db=0)
def check_rate_limit(ip):
key = f"rate_limit:{ip}"
current_count = redis_client.incr(key)
if current_count == 1:
redis_client.expire(key, 60) # 首次请求,设置60秒过期
if current_count > 10: # 每60秒最多10次
# 可选:将IP加入黑名单
redis_client.sadd("blacklist", ip)
redis_client.expire("blacklist", 300) # 黑名单持续5分钟
return False
return True
@app.route('/api/data')
def get_data():
ip = request.remote_addr
if not check_rate_limit(ip):
return jsonify({"error": "Too Many Requests"}), 429
# 正常处理逻辑...
优点:精准控制,可自定义复杂策略(如不同用户等级不同限额)。
缺点:需要开发维护,Redis 成为单点故障风险(需集群部署)。
4. 阿里云专属工具:云盾·安骑士 / 云安全中心
如果你已经购买了阿里云 云安全中心(免费版功能有限,专业版/企业版功能更强):
- 入侵检测:云安全中心会自动识别暴力破解 SSH、RDP 等行为,并可在控制台一键封禁 IP。
- 主机安全策略:部分版本支持基于行为的异常登录阻断。
建议:对于普通开发者,开启云安全中心的“暴力破解防护”是最省心的选择,它会自动在服务器端拦截常见攻击源。
总结与建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 小型个人站/博客 | Nginx limit_req + fail2ban |
免费、轻量、易于维护 |
| 中型电商/API 服务 | 阿里云 WAF | 原生集成、抗 CC 能力强、无需运维服务器防火墙规则 |
| 大型高并发系统 | OpenResty/Lua 限流 + Redis 黑名单 | 高性能、细粒度控制、可扩展 |
| 仅需防 SSH/RDP 爆破 | 云安全中心 + 安全组白名单 | 最安全,避免暴露端口给公网 |
注意事项:
- 误封风险:使用 IP 封禁时,务必考虑 CDN 回源 IP 或负载均衡器(SLB)的真实 IP 问题。如果在 SLB 后直接封禁 SLB 的 IP,会导致合法用户无法访问。正确做法是:
- 在 SLB 前加 WAF。
- 或在 Nginx 中启用
X-Forwarded-For头来获取真实 IP。
- IPv6 支持:确保你的防火墙规则(iptables/firewalld)同时支持 IPv4 和 IPv6,否则可能被绕过。
- 合规性提醒:请勿对非恶意的正常用户实施无差别封禁,避免因限流策略过于激进导致用户体验下降或投诉。
如需进一步帮助,可提供你的具体业务类型(如 Web 网站、API 接口、SSH 远程管理等),我可以给出更详细的配置片段。
云技术博客