如何在Ubuntu 16.04上使用NAXSI保护Nginx

您可以使用NAXSI之类的模块大大提高Nginx服务器的安全性。 NAXSI(Nginx Anti XSS和SQL Injection)是一个免费的第三方Nginx模块,提供Web应用程序防火墙功能。在本教程中,您将使用NAXSI来保护Ubuntu 16.04服务器上的Nginx。在本教程结束时,您将了解NAXSI可以阻止哪种攻击以及如何配置NAXSI规则。

作者选择OWASP基金会作为Write for DOnations计划的一部分接受捐赠。

介绍

Nginx是一种流行的开源HTTP服务器和反向代理,以其稳定性,简单配置和节俭资源需求而闻名。 您可以使用NAXSI之类的模块大大提高Nginx服务器的安全性。 NAXSI( Nginx Anti XSS和SQL Injection )是一个免费的第三方Nginx模块,提供Web应用程序防火墙功能。 NAXSI分析,过滤和保护到达您的Web应用程序的流量,并且像DROP-by-default防火墙一样,这意味着除非指示专门允许访问,否则它会阻止所有流量。

用户可以简单地操作访问是一个关键功能,它将NAXSI与其他具有类似ModSecurity功能的Web应用程序防火墙(WAF)区分开来。 尽管ModSecurity具有丰富的功能集,但它比NAXSI更难维护。 这使得NAXSI成为一种简单且适应性强的选择,提供了易于使用的规则,可以很好地与流行的Web应用程序(如WordPress)配合使用。

在本教程中,您将使用NAXSI来保护Ubuntu 16.04服务器上的Nginx。 由于默认情况下NAXSI模块没有附带Nginx软件包,因此您需要使用NAXSI从源代码编译Nginx。 在本教程结束时,您将了解NAXSI可以阻止哪种攻击以及如何配置NAXSI规则。

先决条件

要完成本教程,您需要:

第1步 - 安装Nginx和NAXSI

大多数Nginx模块都不能通过存储库获得,NAXSI也不例外。 因此,您必须使用NAXSI从源手动下载和编译Nginx。

首先,使用以下命令下载Nginx。

注意:本教程使用的是Nginx 1.14版。 要使用更新版本,可以访问下载页面,并使用更新的版本号替换上述命令中突出显示的文本。 建议使用最新的稳定版本。

wget http://nginx.org/download/nginx-1.14.0.tar.gz

接下来,从Github上稳定的0.56版本下载NAXSI。

注意:本教程使用NAXSI的0.56版本。 您可以在NAXSI Github页面上找到更多最新版本。 建议使用最新的稳定版本。

wget https://github.com/nbs-system/naxsi/archive/0.56.tar.gz -O naxsi

您可能已经注意到,Nginx存储库是一个tar存档。 首先需要提取它以便能够编译和安装它,您可以使用tar命令来完成它。

tar -xvf nginx-1.14.0.tar.gz

在上面的命令中, -x指定提取实用程序, -v使实用程序以详细模式运行, -f指示要提取的存档文件的名称。

现在您已经解压缩了Nginx文件,您可以继续使用以下命令提取NAXSI文件:

tar -xvf naxsi

您现在在主目录中有naxsi- 0.56nginx- 1.14.0文件夹。 使用刚刚下载和解压缩的文件,可以使用NAXSI编译Nginx服务器。 进入你的nginx- 1.14.0目录

cd nginx-1.14.0

为了从源代码编译Nginx,您需要C编译器gcc ,Perl兼容正则表达式库libpcre3-devlibssl-dev ,它们实现SSL和TLD加密协议。 可以使用apt-get命令添加这些依赖项。

首先,运行以下命令以确保您具有更新的包列表。

sudo apt-get update

然后安装依赖项:

sudo apt-get install build-essential libpcre3-dev libssl-dev

现在您已拥有所有依赖项,您可以从源代码编译Nginx。 为了准备从系统上的源代码编译Nginx,执行以下脚本,该脚本将创建Makefile ,显示在何处查找所有必需的依赖项。

./configure \
--conf-path=/etc/nginx/nginx.conf \
--add-module=../naxsi-0.56/naxsi_src/ \
--error-log-path=/var/log/nginx/error.log \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-log-path=/var/log/nginx/access.log \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--lock-path=/var/lock/nginx.lock \
--pid-path=/var/run/nginx.pid \
--user=www-data \
--group=www-data \
--with-http_ssl_module \
--without-mail_pop3_module \
--without-mail_smtp_module \
--without-mail_imap_module \
--without-http_uwsgi_module \
--without-http_scgi_module \
--prefix=/usr

上述命令的每一行都定义了Nginx Web服务器的参数。 其中最重要的是--add-module=../naxsi- 0.56 /naxsi_src/参数,它连接NAXSI模块和Nginx,以及--user=www-data--group=www-data参数,这使得Nginx以您的Ubuntu 16.04服务器附带的名为www-data的专用用户/组的用户和组权限运行。 --with-http_ssl_module参数使Nginx服务器能够使用SSL加密,而--without-mail_pop3_module--without-mail_smtp_module--without-mail_imap_module参数将关闭不必要的邮件协议,否则这些协议将自动包含在内。 有关这些参数的进一步说明,请参阅官方的Nginx文档

使用./configure命令后,运行make命令以执行您刚刚创建的Makefile定义的一系列任务,以便从源代码构建程序。

make

构建Nginx并准备运行时,使用make install命令作为超级用户将构建的程序及其库复制到服务器上的正确位置。

sudo make install

一旦成功,您将获得Nginx的编译版本和NAXSI模块。 为了让NAXSI开始阻止不需要的流量,您现在需要建立一组NAXSI将通过创建一系列配置文件来处理的规则。

第2步 - 配置NAXSI

防火墙功能最重要的部分是其规则,它决定了如何阻止服务器的请求。 NAXSI默认带来的基本规则集称为核心规则 这些规则旨在搜索请求的某些部分中的模式,并过滤掉可能是攻击的模式。 NAXSI核心规则全局应用于服务器以进行签名匹配。

要配置Nginx以使用这些核心规则,请将naxsi_core.rules文件复制到Nginx配置目录。

sudo cp ~/naxsi-0.56/naxsi_config/naxsi_core.rules /etc/nginx/

现在已经建立了核心规则,添加基本的Naxsi规则,这些规则在每个位置的基础上启用和实现核心规则,并在URL请求不满足核心规则时为服务器分配操作。 /etc/nginx/目录中创建一个名为naxsi.rules的文件。 为此,请使用以下命令在文本编辑器中打开名为nano的文件,或使用您选择的文本编辑器。

sudo nano /etc/nginx/naxsi.rules

添加以下定义一些基本防火墙规则的代码块。

/etc/nginx/naxsi.rules
 SecRulesEnabled;
 DeniedUrl "/error.html";

 ## Check for all the rules
 CheckRule "$SQL >= 8" BLOCK;
 CheckRule "$RFI >= 8" BLOCK;
 CheckRule "$TRAVERSAL >= 4" BLOCK;
 CheckRule "$EVADE >= 4" BLOCK;
 CheckRule "$XSS >= 8" BLOCK;

上面的代码定义了DeniedUrl ,它是NAXSI在阻止请求时将重定向到的URL 该文件还支持NAXSI应阻止的各种攻击清单,包括SQL注入,跨站点脚本(XSS)和远程文件包含(RFI)。 将上述代码添加到文件后,保存并退出文本编辑器。

由于您将阻止的请求重定向到/error.html ,现在可以在/usr/html目录中创建error.html文件,以便为此目标提供登录页面。 在文本编辑器中打开文件:

sudo nano /usr/html/error.html

接下来,将以下HTML代码添加到该文件中,以创建一个网页,让用户知道他们的请求被阻止:

/usr/html/error.html
<html>
  <head>
    <title>Blocked By NAXSI</title>
  </head>
  <body>
    <div style="text-align: center">
      <h1>Malicious Request</h1>
      <hr>
      <p>This Request Has Been Blocked By NAXSI.</p>
    </div>
  </body>
</html>

保存文件并退出编辑器。

接下来,在文本编辑器中打开Nginx配置文件/etc/nginx/nginx.conf

sudo nano /etc/nginx/nginx.conf

要将NAXSI配置文件添加到Nginx的配置中,以便Web服务器知道如何使用NAXSI,请将突出显示的代码行插入nginx.conf文件的http部分:

/etc/nginx/nginx.conf
. . .
http {
    include       mime.types;
    include /etc/nginx/naxsi_core.rules;
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;


    default_type  application/octet-stream;
. . .

然后在同一文件的server部分中,添加以下突出显示的行:

/etc/nginx/nginx.conf
. . .
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
        include /etc/nginx/naxsi.rules;
            root   html;
            index  index.html index.htm;
        }
. . .

现在您已经为Nginx配置了NAXSI的核心和基本规则,防火墙将在您启动Web服务器时阻止匹配恶意请求。 接下来,您可以编写启动脚本以确保在重新启动服务器时Nginx启动。

第3步 - 为Nginx创建启动脚本

由于您手动安装了Nginx,因此下一步是创建启动脚本,以使Web服务器在系统重新加载时自动启动。

本教程使用Systemd软件套件制作脚本。 为此,您将创建一个单元文件(请参阅了解系统单元和单元文件以供进一步研究),以配置Systemd应如何启动和管理Nginx服务。

创建一个名为nginx.service的文件,并在文本编辑器中打开它:

sudo nano /lib/systemd/system/nginx.service

将以下行添加到文件中:

/lib/systemd/system/nginx.service
[Unit]
Description=The NGINX HTTP and reverse proxy server
After=syslog.target network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true

[Install]
WantedBy=multi-user.target

[Unit]部分定义了您正在配置的程序, [Service]描述了Nginx在启动时的行为方式, [Install]提供了有关单元安装的信息。 将这些行添加到nginx.service文件后, systemd将知道如何启动Nginx。

接下来,在服务器没有足够内存的情况下,Nginx需要一个文件夹来临时存储传入的请求数据,然后再进行处理。 由于您从源代码安装了Nginx,因此您需要创建一个Nginx可用于存储此数据的目录。 /var/lib/nginx一个名为body的目录:

sudo mkdir -p /var/lib/nginx/body

设置启动脚本后,您现在可以启动Nginx服务器。

使用以下命令启动服务器。

sudo systemctl start nginx

要检查服务器是否处于活动状态,请运行以下命令:

sudo systemctl status nginx

您将在终端中看到以下输出,说明服务器已成功启动:

● nginx.service - The NGINX HTTP and reverse proxy server
   Loaded: loaded (/lib/systemd/system/nginx.service; disabled; vendor preset: enabled)
   Active: active (running) since Mon 2018-11-05 13:59:40 UTC; 1s ago
  Process: 16199 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 16194 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
 Main PID: 16201 (nginx)
    Tasks: 2
   Memory: 1.3M
      CPU: 17ms
   CGroup: /system.slice/nginx.service
           ├─16201 nginx: master process /usr/sbin/ngin
           └─16202 nginx: worker proces
. . .

您现在有一个由NAXSI保护的正在运行的Nginx服务器。 下一步是运行模拟的XSS和SQL注入攻击,以确保NAXSI有效地保护您的服务器。

第4步 - 测试NAXSI

要在启用NAXSI模块的情况下测试Nginx已启动并运行,您将尝试使用恶意HTTP请求访问服务器并分析响应。

首先,复制服务器的Public IP并使用curl命令对Nginx服务器进行恶意请求。

curl 'http://your_server_ip/?q="><script>alert(0)</script>'

此URL包含q参数中的XSS脚本"><script>alert(0)</script> ,应该被服务器拒绝。根据您之前设置的NAXSI规则,您将被重定向到error.html文件并收到以下响应:

<html>
  <head>
    <title>Blocked By NAXSI</title>
  </head>
  <body>
    <div style="text-align: center">
      <h1>Malicious Request</h1>
      <hr>
      <p>This Request Has Been Blocked By NAXSI.</p>
    </div>
  </body>
</html>

NAXSI防火墙已阻止该请求。

现在,使用以下命令通过拖尾Nginx服务器日志使用Nginx日志验证相同:

tail -f /var/log/nginx/error.log

在日志中,您将看到来自远程IP地址的XSS请求被NAXSI阻止:

2018/11/07 17:05:05 [error] 21356#0: *1 NAXSI_FMT: ip=your_server_ip&server=your_server_ip&uri=/&learning=0&vers=0.56&total_processed=1&total_blocked=1&block=1&cscore0=$SQL&score0=8&cscore1=$XSS&score1=8&zone0=ARGS&id0=1001&var_name0=q, client: your_server_ip, server: localhost, request: "GET /?q="><script>alert(0)</script> HTTP/1.1", host: "your_server_ip"

CTRL-C退出tail并停止错误日志文件的输出。

接下来,尝试另一个URL请求,这次是恶意SQL注入查询。

curl 'http://your_server_ip/?q=1" or "1"="1"'

前面URL的or "1"="1"部分可以在数据库中公开用户的数据,并且将被NAXSI阻止。 它应该在终端中产生相同的响应:

<html>
  <head>
    <title>Blocked By NAXSI</title>
  </head>
  <body>
    <div style="text-align: center">
      <h1>Malicious Request</h1>
      <hr>
      <p>This Request Has Been Blocked By NAXSI.</p>
    </div>
  </body>
</html>

现在使用tail再次关注服务器日志:

tail -f /var/log/nginx/error.log

在日志文件中,您将看到SQL注入尝试的阻止条目:

2018/11/07 17:08:01 [error] 21356#0: *2 NAXSI_FMT: ip=your_server_ip&server=your_server_ip&uri=/&learning=0&vers=0.56&total_processed=2&total_blocked=2&block=1&cscore0=$SQL&score0=40&cscore1=$XSS&score1=40&zone0=ARGS&id0=1001&var_name0=q, client: your_server_ip, server: localhost, request: "GET /?q=1" or "1"="1" HTTP/1.1", host: "your_server_ip"

CTRL-C退出日志。

NAXSI现已成功阻止了XSS和SQL注入攻击,这证明NAXSI已正确配置并且您的Nginx Web服务器是安全的。

结论

您现在已基本了解如何使用NAXSI保护Web服务器免受恶意攻击。 要了解有关设置Nginx的更多信息,请参阅如何在Ubuntu 16.04上设置Nginx服务器块(虚拟主机) 如果您想继续研究Web服务器上的安全性,请查看如何在Ubuntu 16.04上使用Let加密来保护Nginx以及如何在Ubuntu 16.04中为Nginx创建自签名SSL证书