努力
加油

ECS实例中如何通过安全组或防火墙限制某IP的请求次数?

在阿里云 ECS(弹性计算服务)中,想要实现“限制某 IP 的请求次数”(即防刷、限流或封禁恶意 IP),单纯靠安全组(Security Group)是做不到的。

核心结论先行:

  1. 安全组:只能做“白名单/黑名单”式的访问控制(允许或拒绝特定端口的流量),无法统计次数,也无法基于频率进行拦截。
  2. 正确方案:需要结合 云防火墙(Cloud Firewall)、Web 应用防火墙(WAF) 或者 操作系统内部脚本(如 iptables + fail2ban / nginx limit_req) 来实现。

下面分场景详细说明如何落地:


方案一:使用阿里云云防火墙(推荐,最接近原生体验)

如果你购买了阿里云的云防火墙(包括基础版或企业版),这是最直接的方式,无需修改服务器配置,直接在控制台操作。

操作步骤:

  1. 登录阿里云控制台,进入【云防火墙】页面。
  2. 找到【访问控制】->【IP 黑白名单】或【入侵防御】模块。
  3. 针对单个 IP 封禁:
    • 如果某个 IP 已经确认是恶意攻击,直接添加为黑名单。这会立即阻断该 IP 的所有入站流量(可指定端口)。
  4. 针对频率限制(防刷):
    • 云防火墙的高级功能支持访问频率控制。你可以设置规则:例如“来自同一源 IP 对同一目的端口(如 80/443)的请求,每秒超过 N 次则丢弃”。
    • 注意:此功能通常在企业版或更高版本中提供,具体需参考当前产品文档。

优点:集中管理,不影响业务代码,日志清晰。
缺点:需要额外购买云防火墙服务。


方案二:使用 Web 应用防火墙 WAF(适合 HTTP/HTTPS 业务)

如果你的服务是 Web 服务(网站、API),WAF 是最佳选择。它专门处理应用层攻击,天然支持频率限制。

操作步骤:

  1. 将域名 CNAME 到 WAF 地址,或将 ECS 的公网 IP 接入 WAF。
  2. 在 WAF 控制台配置防护策略。
  3. 开启频率控制(Rate Limiting):
    • 可以设置按 IP 维度限制:例如“每个 IP 每分钟最多请求 100 次”。
    • 超出阈值后,WAF 会直接返回 403 或 5xx 错误,请求根本不会到达你的 ECS 实例。

优点:精准到 URL 路径,支持验证码挑战,抗 CC 攻击能力强。
缺点:仅适用于 HTTP/HTTPS 协议,TCP 底层服务不适用。


方案三:操作系统内部实现(iptables + fail2ban / nginx)

如果你没有购买额外的云安全产品,只能在 ECS 内部通过软件实现。这是成本最低但维护成本最高的方式。

子方案 A:Nginx 层面限制(最简单有效)

如果你的 Web 服务由 Nginx 反向XX,可以直接在 nginx.conf 中配置。

http {
    # 定义一个名为 'one_per_second' 的共享内存区域
    limit_req_zone $binary_remote_addr zone=one_per_second:10m rate=1r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            # 应用限制:允许突发 5 个请求,之后每秒只允许 1 个
            limit_req zone=one_per_second burst=5 nodelay;

            proxy_pass http://backend;
        }
    }
}
  • $binary_remote_addr:代表客户端 IP。
  • rate=1r/s:每秒允许 1 个请求。
  • burst=5:允许短时间突发 5 个请求,超过后直接返回 503。

优点:配置简单,无需重启系统,精准到 Web 层。
缺点:只能保护 Nginx 暴露的服务,无法保护 SSH(22)、数据库等非 Web 端口。

子方案 B:iptables + fail2ban(系统级通用防护)

适用于所有 TCP/UDP 服务,包括 SSH、FTP、自定义端口等。

  1. 安装 fail2ban:

    yum install fail2ban  # CentOS/RHEL
    apt install fail2ban  # Ubuntu/Debian
  2. 配置 jail.local:
    编辑 /etc/fail2ban/jail.local,添加如下规则:

    [DEFAULT]
    bantime = 3600          # 封禁时间,单位秒
    findtime = 60           # 检测时间窗口,单位秒
    maxretry = 5            # 最大重试次数
    
    [sshd]                  # 针对 SSH 服务
    enabled = true
    port = ssh
    filter = sshd
    logpath = /var/log/secure
    
    [custom-service]        # 针对自定义服务(假设日志中有 "Failed password" 关键字)
    enabled = true
    port = 8080             # 替换为你的端口
    filter = custom-filter
    logpath = /var/log/myapp.log
  3. 启动服务:

    systemctl enable fail2ban
    systemctl start fail2ban

fail2ban 会监控日志文件,当检测到某个 IP 在 findtime 内触发 maxretry 次失败行为时,自动调用 iptables 添加 DROP 规则封禁该 IP。

优点:系统级防护,覆盖所有端口,自动化程度高。
缺点:依赖日志解析,对非标准日志格式支持较差;高并发下可能有一定性能开销。


方案四:负载均衡 SLB + 安全组组合(架构层)

如果你的 ECS 前面挂了 SLB(应用型负载均衡 ALB/NLB),可以利用 SLB 的健康检查和后端服务器组策略间接实现。

但更直接的是:

  1. 在 SLB 上启用 WAF 集成 或 DDoS 防护。
  2. 在 SLB 的安全组中,只允许 SLB 的内网 IP 段访问 ECS 的特定端口(如 80/443),从而隐藏 ECS 真实 IP。
  3. 再将频率限制逻辑放在 SLB 后的 Nginx 或应用中。

总结与建议

场景 推荐方案 理由
Web/API 服务 WAF 专业抗 CC,配置灵活,无需改代码
全端口防护 + 有预算 云防火墙 集中管控,可视化强,支持频率限制
无预算 + Web 服务 Nginx limit_req 零成本,配置简单,效果立竿见影
无预算 + 多服务/SSH fail2ban + iptables 系统级通用防护,适合运维人员

关键提醒:

  • 不要试图用安全组做频率限制:安全组是无状态包过滤,只判断“是否允许”,不记录“历史次数”。
  • 防止误封:在生产环境实施频率限制时,务必先设置较大的 burst 值或较长的 bantime,并通过监控观察正常用户的访问模式,避免将合法用户(如移动网络 NAT 出口 IP 相同的情况)误封。
  • IPv6 支持:如果你的服务启用了 IPv6,确保上述工具(尤其是 fail2ban 和 iptables)也配置了 IPv6 规则(ip6tables)。

根据你的实际业务类型和预算,选择最适合的方案即可。对于大多数国内互联网业务,WAF + Nginx 双层防护是最常见且有效的组合。