如何在Ubuntu16.04上使用NAXSI保护Nginx

来自菜鸟教程
跳转至:导航、​搜索

作为 Write for DOnations 计划的一部分,作者选择了 The OWASP Foundation 来接受捐赠。

介绍

Nginx 是一种流行的开源 HTTP 服务器和反向代理,以其稳定性、简单的配置和节省的资源要求而闻名。 您可以通过使用像 NAXSI 这样的模块来大大提高 Nginx 服务器的安全性。 纳西西 ( Nginx 反 XSS 和 SQL 注入 ) 是一个免费的第三方 Nginx 模块,提供 Web 应用程序防火墙功能。 NAXSI 分析、过滤和保护进入您的 Web 应用程序的流量,并充当默认 DROP 防火墙,这意味着它会阻止所有进入的流量,除非被指示明确允许访问。

用户操作访问的简单性是 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

一旦成功,您将拥有一个带有 NAXSI 模块的 Nginx 编译版本。 为了让 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,即当请求被阻塞时,URL NAXSI 将重定向到。 该文件还启用了 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 软件套件来制作脚本。 为此,您将创建一个单元文件(请参阅 Understanding Systemd Units and Unit Files 以进一步学习)来配置 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

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

Output● 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

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

首先,复制你服务器的公网IP,使用curl命令恶意请求Nginx服务器。

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

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

Output<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 阻止:

Output2018/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 阻止。 它应该在终端中产生相同的响应:

Output<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 注入尝试被阻止的条目:

Output2018/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's Encrypt 保护 Nginx 和 如何在 Ubuntu 16.04 中为 Nginx 创建自签名 SSL 证书[ X211X]。