nginx 如何配置防止慢速攻击 [特殊字符][特殊字符][特殊字符]

慢速攻击是一类用很少带宽就能长期占用服务器连接/资源的攻击方式。攻击者通过非常慢地发送请求头或请求体,或极慢地读取服务器响应,让每个连接都“挂着不结束”,从而耗尽 Web 服务器(或上游应用、数据库、代理)的并发与缓冲资源。

典型类型主要有以下几个方面:

  • Slowloris(慢请求头):客户端以极低速率分片发送 HTTP 头部,始终不把头部发完,服务器就一直等待。
  • Slow POST / RUDY(慢请求体):先宣称要上传较大的 Content-Length,然后以极慢速率发送请求体,服务器为其保留缓冲与上游连接。
  • Slow Read(慢读取响应):客户端窗口/读取速率极低,迫使服务器缓冲并保持连接很久(尤其响应较大时)。
  • HTTP/2 变种:滥用单连接多流(streams)和窗口控制:开很多流但每流都很慢,放大资源占用。

传统 DDoS 依靠高带宽与高包速直接压垮网络/设备,而慢速攻击用极低带宽长期占用连接,更隐蔽,常被误认为是网络状况差的正常用户。

现场通常会看到活跃连接(尤其 reading)持续攀升,但总体带宽并不高。

error_log 中频繁出现 client timed out、client sent invalid header while reading client request headers 等信息。

上游服务看似空闲却体验发卡,Nginx 的 429/502/504 增多,访问日志还能发现同一 IP 维持大量长期未完成的请求或异常长的响应时间。

  • 429 表示“请求过多被限流”,通常稍后或按 Retry-After 重试即可。
  • 502 表示“网关收到上游无效响应或连不上上游”,多见于上游挂掉、拒连或协议不匹配。
  • 504 表示“等待上游超时”,通常是上游处理太慢一直没回。

如何防护

核心目标就是尽快关闭拖延发送请求头/请求体或极慢读取响应的连接,限制单 IP 的并发与速率,避免慢连接占满 worker 的 worker_connections 与上游资源。

  • 收紧超时:client_header_timeout、client_body_timeout、send_timeout、keepalive_timeout。
  • 超时立刻复位:reset_timedout_connection on; 减少 TIME_WAIT/ 资源滞留。
  • 限并发/限速:limit_conn、limit_req(必要时返回 429 并带 Retry-After)。
  • HTTP/2 参数:降低 http2_max_concurrent_streams,设置 http2_recv_timeout/http2_idle_timeout。
  • 反向代理场景:proxy_request_buffering on; 先把请求缓冲到 Nginx,避免慢上传占住上游。
  • 分路径/分人群:对登录、搜索等接口更严;对可信源/健康检查放宽或白名单。
  • 边缘清洗:结合 CDN/WAF 的连接层/应用层限速更稳。

一些相关的配置可以参考下面的 Nginx 配置:

worker_processes auto;

events {
    worker_connections  4096;
    multi_accept        on;
}

http {
    # 1) 关键超时(防慢头/慢体/慢读)
    client_header_timeout  5s;   # 等头部时间
    client_body_timeout    10s;  # 等请求体每个读周期的时间
    send_timeout           10s;  # 发送响应给客户端每个写周期的时间
    keepalive_timeout      10s;  # keep-alive 连接空闲时间
    keepalive_requests     100;  # 单连接最大请求数,防长时间占用

    # 2) 连接超时直接复位(释放资源更快)
    reset_timedout_connection on;

    # 3) 并发限制(每 IP)
    #    10m 可容纳 ~160k 键(基于 $binary_remote_addr)
    limit_conn_zone $binary_remote_addr zone=perip:10m;

    # 4) 速率限制(每 IP),按需调大/调小 rate
    limit_req_zone  $binary_remote_addr zone=req_perip:10m rate=10r/s;

    # 5) HTTP/2 专项(若开启了 http2)
    http2_max_concurrent_streams 64; # 降并发流数
    http2_recv_timeout           5s; # 接收客户端帧超时
    http2_idle_timeout          10s; # HTTP/2 空闲超时

    # 6) 合理的头部缓冲(避免过大内存占用;默认已够用,按需微调)
    large_client_header_buffers 4 8k;

    server {
        listen 443 ssl http2;
        server_name example.com;

        # 并发/速率在 server 层生效
        limit_conn       perip 20;        # 每 IP 并发连接上限
        limit_conn_status 429;

        limit_req        zone=req_perip burst=20 nodelay;  # 短突发
        limit_req_status 429;

        # 限制请求体大小(配合 body_timeout 可更快淘汰异常大/慢上传)
        client_max_body_size 10m;

        # 【反向代理站点强烈推荐】先把完整请求缓冲到 Nginx
        # 避免上游被慢上传拖住连接
        location / {
            proxy_pass http://app_backend;
            proxy_request_buffering on;

            proxy_connect_timeout  3s;
            proxy_send_timeout    10s;  # 向上游发送(写)超时
            proxy_read_timeout    30s;  # 自上游读取(读)超时
        }

        # 对静态资源可放宽速率限制以提升体验(示例)
        location ~* \.(?:css|js|png|jpg|jpeg|gif|webp|ico|svg)$ {
            root /var/www/html;
            access_log off;
            expires 30d;
        }

        # 自定义 429 页面(可选)
        error_page 429 /429.html;
        location = /429.html { internal; return 429 "Too Many Requests\n"; }
    }
}

除此之外,还有一些数值上的建议:

  1. 高频 API 可将 rate 调小、burst 适度放大;页面类流量可相反。
  2. 对上传较多的业务,将 client_body_timeout 与 proxy_request_buffering on; 组合尤为关键。
  3. 如果公网复杂、遭遇中等强度慢攻:client_header_timeout 2-3s、client_body_timeout 5-8s、send_timeout 8-10s 往往更稳。

考虑到移动网络或跨境访问确实可能很慢,限流需要在防护与容错间取平衡。可以适度调大 burst,并返回合理的 Retry-After,让偶发拥塞得以通过。把严格策略仅应用在登录、搜索等敏感接口,对静态资源和页面流量适当放宽。对可信来源(如办公网、监控、合作方)设置白名单或更高配额,尽量减少误杀。

之于上面的理解,我们可以针对不同慢速攻击的做不同的优化了:

  • Slowloris(慢头部):用 client_header_timeout 严控请求头收齐时间,配合较短的 keepalive_timeout 降低长连驻留,并用 limit_conn 限制每 IP 并发;一旦超时,借助 reset_timedout_connection on; 立即复位断开。
  • RUDY / Slow POST(慢体):设置较短的 client_body_timeout,并开启 proxy_request_buffering on; 先在 Nginx 缓冲请求体,慢上传直接在边缘被淘汰且不上游;必要时配合 client_max_body_size 约束体积。
  • Slow Read(客户端读超慢):通过 send_timeout 限制客户端读取过慢的连接,触发即复位释放缓冲;若是 SSE/长轮询等合法长连,为对应路径单独放宽 send_timeout,避免误伤。

总结

慢速攻击是用极低带宽长期占用服务器连接/缓冲的攻击:攻击者故意慢发请求头/请求体或慢读响应,让连接一直不结束,耗尽并发与内存。

常见形态有 Slowloris(慢头部)、RUDY/Slow POST(慢请求体)与 Slow Read(慢读响应),在 HTTP/2 下还能通过多流+窗口控制放大影响。

典型症状是活跃连接(尤其 reading)持续升高但总体带宽不高,日志频繁出现超时/异常头部,且 429/502/504 增多、同一 IP 大量长时间未完成请求。

防护要点是收紧超时(client_header/body/send/keepalive)、开启 reset_timedout_connection、用 limit_conn/limit_req 控制每 IP 并发与速率,反向代理时启用 proxy_request_buffering on; 并调优 HTTP/2;同时对敏感路径更严、对可信来源适度放宽或白名单以减少误杀。

<think> 我们分析给定的access.log内容,并结合引用资料中关于攻击检测的指标(如错误日志中的408/429状态码、访问日志中单IP高频请求等)进行判断 注意:提供的日志样本只有5条记录,时间戳集中在同一秒(08:17:01),但IP地址有3个(120.77.139.23, 120.77.139.21, 120.77.139.24) 根据引用[1]:在访问日志中,我们可以统计单IP的请求频率和连接数,若某IP频繁出现408(请求超时)或429(太多请求),则可能是攻击源。 然而,在给定的日志中: 1. 所有请求的状态码都是200(成功),没有错误码(如408,429,404,500等) 2. 请求时间非常集中(同一秒内),但请求数量只有5个,且来自3个不同IP(每个IP最多2个请求),这个频率并不算高 因此,仅从这5条日志无法判断nginx是否频繁被攻击。 但我们可以根据引用[1]和[3]中提到的一些攻击特征,结合日志分析的一般方法给出进一步排查建议: 1. **检查错误日志(error.log)**:根据引用[1],关注408(请求超时,防御Slow headers/body生效)和429(限流生效)状态码。如果这些错误码频繁出现,则说明有攻击行为被防御机制拦截。 2. **分析访问日志(access.log)中的异常模式**: - **单IP高频请求**:在短时间内(如1秒)同一个IP发起大量请求(如几十或上百个),特别是对同一个URL的重复请求。 - **异常User-Agent**:如爬虫、扫描器等非常规浏览器标识。 - **异常请求路径**:如尝试访问不存在的路径(返回404)、敏感路径(如/admin, /login)等。 3. **检查日志中是否有攻击特征**: - **慢速攻击Slowloris)**:这种攻击会保持连接长时间不释放,在日志中可能表现为大量请求处理时间过长(如果配置了$request_time)或状态码408。 - **CC攻击**:大量并发请求,导致服务器资源耗尽,在日志中表现为短时间内来自同一IP或不同IP的大量请求(特别是动态请求)。 4. **检查是否有爬虫恶意爬取**:根据引用[4],爬虫可能会规律性地翻页,在日志中表现为连续的数字页码请求(如/page/1, /page/2, ...)。在给定的日志中,请求的URL参数有规律性(如itemIds=0108,0102,...),但这是正常业务参数,不是翻页参数。引用[4]提到翻页页码索引的特征,但当前日志中没有翻页参数。 5. **其他攻击特征**:如SQL注入(URL中包含单引号、select等关键词)、目录遍历(路径中包含../)等,在当前日志中未发现。 结论:仅从提供的5条日志记录来看,没有明显攻击迹象。但需要更全面的日志数据(如一段时间内的日志)才能准确判断。 建议的排查步骤: 步骤1:检查错误日志(/var/log/nginx/error.log)中是否有大量408、429等错误码记录。 步骤2:分析访问日志中的请求频率: - 使用命令统计每个IP的请求数(按小时或分钟统计): ```bash awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr ``` 如果发现某个IP在短时间内请求数异常高(如每分钟几百次),则可能是攻击源。 步骤3:检查是否有大量非200状态码的请求(如404、403): ```bash awk '$9 != 200 {print $9, $7}' /var/log/nginx/access.log | sort | uniq -c | sort -nr ``` 步骤4:检查是否有异常User-Agent(如不含'Mozilla'、'Chrome'等常见浏览器标识的请求): ```bash awk -F\" '{print $6}' access.log | sort | uniq -c | sort -nr ``` 步骤5:如果配置了访问频率限制(如limit_req模块),则429状态码会增多,这是防御生效的表现。 步骤6:如果怀疑有慢速攻击,可以检查连接持续时间(需要日志中记录$request_time): ```bash awk '{print $1, $NF}' access.log | sort -k2 -nr ``` 找出处理时间特别长的请求。 根据引用[1]中的调优建议,如果确认有攻击,可以: - 配置连接超时(如client_header_timeout, client_body_timeout)来防御慢速攻击 - 配置限流(limit_req, limit_conn)来防御高频请求 因此,基于当前提供的日志,我们无法得出“nginx频繁被攻击”的结论,需要进一步排查。 </think>基于您提供的 Nginx `access.log` 内容,结合引用资料中的安全分析原则,以下是判断 Nginx 是否频繁遭受攻击的综合分析: --- ### 一、当前日志中的**安全风险特征** #### 1. **高密度集中请求(潜在 CC/DDoS 迹象)**[^1][^3] - **现象**:5 条请求均发生在 **同一秒内**(`08:17:01`) - **来源 IP**:3 个相邻 IP(`120.77.139.21/23/24`) - **风险分析**: - 短时间内相同业务接口(`/healthcheck-web-client`)被密集调用 - 符合 CC 攻击特征:通过高频请求耗尽服务器资源 - 引用[1]指出:需监控单 IP 请求频率,防止连接耗尽 #### 2. **异常长参数列表(潜在爬虫特征)**[^4] - 示例: ``` GET ... /isShowEableLocaleReserve?groupType=0&pkgId=267952&stationId=... &itemIds=0108,0102,0201,... (共24个参数) ``` - **风险分析**: - 超长参数列表(`itemIds` 含 24 个值)暴露数据爬取意图 - 引用[4]提到:爬虫会规律性翻页,长参数可能用于批量获取数据 - 需确认此类请求是否持续高频出现 #### 3. **固定来源但低伪装性** - **User-Agent 完全一致**: `Mozilla/5.0 (iPhone; CPU iPhone OS 18_5...) MicroMessenger/8.0.65...` - **Referer 完全一致**: `https://hljktj.boe.com/oss/mall/exam-detail.html?...` - **风险分析**: 高度一致的请求头可能为自动化脚本伪造,非真实用户行为。 --- ### 二、**未观察到直接攻击证据** #### 1. **状态码正常** - 所有请求均返回 **`200`**(成功),无 `4xx/5xx` 错误[^1] #### 2. **缺少关键攻击特征** - 无大量 `408`(请求超时)或 `429`(限流触发)[^1] - 无非标准 HTTP 方法(如 `HEAD`、`OPTIONS` 泛洪) - 无非业务相关路径扫描(如 `/admin`、`/wp-login.php`) --- ### 三、**安全加固建议** #### 1. **日志深度分析** ```bash # 检查单IP请求频率(按小时统计) awk '{print $1}' access.log | sort | uniq -c | sort -nr # 检测长参数请求(参数长度>100字符) awk -F\" '$2 ~ /GET/ && length($2)>100 {print $2}' access.log ``` #### 2. **配置防御策略**[^1][^3] ```nginx # 限制单IP连接速率(引用[1]) http { limit_req_zone $binary_remote_addr zone=one:10m rate=10r/s; server { location /healthcheck-web-client { limit_req zone=one burst=20; # 每秒最多10请求 } } } # 屏蔽异常长参数(引用[3]) location ~* \.php { if ($args ~ "^(.{100,})$") { return 403; } } ``` #### 3. **增强监控** - 启用 Nginx 实时状态模块 `ngx_http_stub_status_module` - 配置日志切割(引用[2]),避免日志过大影响分析: ```bash 00 00 * * * /bin/sh /server/scripts/cut_nginx_log.sh ``` --- ### 四、结论 ✅ **当前日志未显示频繁攻击**,但存在 **潜在风险特征**(高频集中请求、长参数爬取)。 ⚠️ 需结合更长时间窗口的日志(如 24 小时),并检查 `error.log` 中是否有 `408/429` 错误[^1] 以最终确认。 --- ### 相关问题 1. 如何通过 Nginx 日志识别慢速攻击Slowloris)? 2. 有哪些工具可自动化分析 Nginx 日志中的安全威胁? 3. 如何区分真实用户和恶意爬虫的流量模式? 4. Nginx 的 `limit_req` 和 `limit_conn` 模块有何区别?如何配置? [^1]: 错误日志监控与防御机制验证 [^2]: 日志切割与权限控制 [^3]: 请求方法优化与连接控制 [^4]: 爬虫翻页特征分析
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值