Nginx - 根据 GET 参数模式重定向请求

Nginx - 根据 GET 参数模式重定向请求

几天前,我的一台服务器遭受了 DDoS 攻击,持续了 4 天。以下是请求的日志片段:

36.224.180.253 - - [14/May/2013:03:11:46 +0800] "GET //?f5b2fd2f860dc=9597624054932145 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:11:50 +0800] "GET //?d69e553a2e8cc=8383534686131949 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:11:53 +0800] "GET //?cd28bceecb2f7=8014028628342069 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:11:59 +0800] "GET //?e39ba4d777ca3=8890936876339672 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:02 +0800] "GET //?3bc0dd265e14b=2334116190596257 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:06 +0800] "GET //?8b645989c8334=5444999657995141 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:09 +0800] "GET //?bb1f56833c451=7309469290160174 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"
36.224.180.253 - - [14/May/2013:03:12:11 +0800] "GET //?5fb9da415957e=3739296350043726 HTTP/1.1" 301 178 "-" "Opera/9.80 (Windows NT 6.1; WOW64) Presto/2.12.388 Version/12.14"

别在意 IP 了,这只是众多请求中的一个。有超过 3000 个不同的 IP 使用相同的 GET 请求模式。

我在 Varnish(varnish-3.0.3-1.el6.x86_64)后面使用 Nginx(nginx-1.2.8-1.el6.ngx.x86_64)。

我的问题是,如何将这种请求重定向到特定页面,比如 404.html?

答案1

Nginx 中的 Rewrite 仅适用于路径,因此您需要单独对变量使用比较来识别它们。您请求的内容如下:

if ($args ~ "([a-f0-9]{12,})=([a-f0-9]{12,})" ){
    rewrite ^/$ /404_rewrite?;
}

location  /404_rewrite {
    return 404;
}
  • 参数的匹配必须在引号内,否则{会使}Nginx 感到困惑。

  • ?重写末尾的 使 Nginx 删除所有参数,而不是将它们附加到重写的 url 。

但是您可能希望 Nginx 尝试延迟 DOS 中的每个请求,而不是尽快处理它们。

limit_req_zone  $binary_remote_addr  zone=dos_attack:20m   rate=30r/m;

if ($args ~ "([a-f0-9]{12,})=([a-f0-9]{12,})" ){
    rewrite ^/$ /404_rewrite?;
}

location  /404_rewrite {
    limit_req   zone=dos_attack  burst=1;
    internal;
    return 404;
}

这样做的目的是:

  • 将请求数设置为 30r/m,即每分钟 30 个请求或每两秒一个请求。

  • 将突发设置为 1。对于正常速率限制,突发设置为 >1,以允许客户端在短时间内意外超过速率限制时不受限制。

  • 分配 20 兆字节用于存储速率限制区域的信息。根据速率限制文档每个$binary_remote_addr文件占用 64 个字节来存储,因此这种速率限制最多可以在几十万台运行 DOS 的机器上运行。如果机器数量超过这个数字,速率限制就会失效。

相关内容