Nginx 针对异常访问返回炸弹(GZip Bomb)以降低服务器安全风险方法

在《网站如何屏蔽垃圾蜘蛛爬取》一文中,我们知道针对异常访问可以通过三种方式来屏蔽:① Robots 禁封、② UA 禁封、③ IP 禁封,今天发现还有一种方法叫做 Gzip Bomb(炸弹),一起来看看。

原理

浏览器默认支持 gzip 压缩方法,接收到服务器响应的数据后,会自动进行解压、解析;不论是 Linux 系统还是 Windows 系统,都可以很方便地创建大型空白文件(参见《Windows 及 Linux 下如何通过命令生成任意大小的空文件》),而对空白文件进行压缩可以实现非常高的压缩比;

因此我们可以创建大型空白文件并压缩放在服务器上,当侦测到异常访问时返回该文件,使对方使用的客户端因解压、解析该文件时占据大量内存,使之系统崩溃,以达到降低服务器安全风险。

步骤

以 Linux Ubuntu 18.04 为例。

创建文件

root@fw:~# cd /var/www/html
root@fw:~# dd if=/dev/zero bs=1M count=1024 | gzip > 1G.gzip

上述示例创建了一个 1G 的空白文件,经过 gzip 压缩后大约 1M 左右。

配置网站

root@fw:~# vim /etc/nginx/sites-available/default
......
server {
    listen 80 default_server;
    server_name _;
    root /var/www/html;
    location = / {
        index index.html;
    }
    location / {
        try_files $uri /bomb;
    }
    location = /bomb {
        default_type text/html;
        add_header Content-Encoding gzip;
        gzip off;
        root /var/www/html/1G.gzip;
    }
.....
}
......

上述示例中:

  • 当客户端访问根目录/index.html时,直接返回 index.html,属于正常访问;

  • 当访问异常路径或其他文件时,就会返回炸弹 1G.gzip;

  • 当访问域名与配置不一致,也会返回炸弹(这里配置默认所有);

效果

客户端访问异常路径或其他文件时,Nginx会返回 1M 大小的炸弹文件,由于无法判断目标文件的 MIME,就会使用我们定义的 default_type中声明的 Content-Type:text/html ,再配合 Content-Encoding: gzip,指导浏览器解开 gzip,慢慢吃光客户端所有内存,然后一步一步走向死亡的深渊。

局限性

这种方法仅对会对网站内容做解析的客户端有效,对于只取头部信息或者下载的客户端效果不大,因为不会做解析就不会解压,比如 HEAD请求。

另外如果网站使用了 CDN,而 CDN 又开启了对 text/html类型进行缓存,那么炸弹貌似也没有多大效果。