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

作者选择了 The OWASP Foundation作为 Write for Donations计划的一部分获得捐款。

介绍

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

用户可以操纵访问的简单性是区分NAXSI与其他Web应用程序防火墙(WAF)的关键功能,具有类似的功能,如ModSecurity。尽管ModSecurity具有丰富的功能集,但它比NAXSI更难维护。

在本教程中,您将使用NAXSI在您的Ubuntu 16.04服务器上保护 Nginx。由于NAXSI模块默认情况下不包含 Nginx 包,您将需要使用NAXSI从源编译 Nginx。

前提条件

要完成本教程,您将需要:

步骤 1 — 安装 Nginx 和 NAXSI

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

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

<$>[注] **注:**本教程使用 Nginx 版本 1.14。要使用更新的版本,您可以访问 下载页面并用更新的版本号代替上一命令中的突出文本。

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

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

<$>[注] 注: 本教程使用 NAXSI 的版本 0.56 您可以在 NAXSI Github 页面找到更多最新版本。

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

正如您可能已经注意到的那样, Nginx 存储库是一个tar档案,您首先需要提取它才能编译和安装它,您可以使用tar命令来做到这一点。

1tar -xvf nginx-1.14.0.tar.gz

在之前的命令中,‘-x’指定了提取实用程序,‘-v’使实用程序运行在语音模式中,而‘-f’则表示了要提取的档案文件的名称。

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

1tar -xvf naxsi

您现在在您的主目录中有 naxsi-0.56nginx-1.14.0 文件夹. 使用您刚刚下载和提取的文件,您可以使用 NAXSI 编译 Nginx 服务器。 移动到您的 nginx-1.14.0 目录

1cd nginx-1.14.0

要从源头编译 Nginx,您需要 C 编译器 gcc、Perl 兼容常规表达式库 libpcre3-devlibssl-dev,该库实现 SSL 和 TLD 加密协议。

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

1sudo apt-get update

然后安装依赖:

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

现在你有所有的依赖,你可以从源编译 Nginx. 为了准备 Nginx 将从源编译在你的系统上,执行下面的脚本,这将创建的Makefile,显示在哪里找到所有必要的依赖。

 1./configure \
 2--conf-path=/etc/nginx/nginx.conf \
 3--add-module=../naxsi-0.56/naxsi_src/ \
 4--error-log-path=/var/log/nginx/error.log \
 5--http-client-body-temp-path=/var/lib/nginx/body \
 6--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
 7--http-log-path=/var/log/nginx/access.log \
 8--http-proxy-temp-path=/var/lib/nginx/proxy \
 9--lock-path=/var/lock/nginx.lock \
10--pid-path=/var/run/nginx.pid \
11--user=www-data \
12--group=www-data \
13--with-http_ssl_module \
14--without-mail_pop3_module \
15--without-mail_smtp_module \
16--without-mail_imap_module \
17--without-http_uwsgi_module \
18--without-http_scgi_module \
19--prefix=/usr

前命令的每一行都定义了 Nginx 网页服务器的参数。其中最重要的参数是连接 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' 参数。

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

1make

当 Nginx 已建立并准备运行时,请使用安装命令作为超级用户来将嵌入式程序及其库复制到您的服务器上的正确位置。

1sudo make install

一旦成功,你将有一个编译的版本的Nginx与NAXSI模块. 为了让NAXSI开始阻止不需要的流量,你现在需要建立一套规则,NAXSI将采取行动,通过创建一系列的配置文件。

步骤 2 – 配置 NAXSI

防火墙运作的最重要部分是它的规则,这些规则决定了请求是如何从服务器上被阻止的。NAXSI 默认的基本规则被称为 core 规则. 这些规则旨在搜索请求部分中的模式,并过滤可能是攻击的模式。

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

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

现在已经建立了核心规则,添加基本的 Naxsi 规则,以每个位置为基础启用和实施核心规则,并分配服务器在 URL 请求不符合核心规则时执行的操作。在 /etc/nginx/ 目录中创建一个名为 naxsi.rules 的文件。

1sudo nano /etc/nginx/naxsi.rules

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

 1[label /etc/nginx/naxsi.rules]
 2 SecRulesEnabled;
 3 DeniedUrl "/error.html";
 4
 5 ## Check for all the rules
 6 CheckRule "$SQL >= 8" BLOCK;
 7 CheckRule "$RFI >= 8" BLOCK;
 8 CheckRule "$TRAVERSAL >= 4" BLOCK;
 9 CheckRule "$EVADE >= 4" BLOCK;
10 CheckRule "$XSS >= 8" BLOCK;

上面的代码定义了DeniedUrl,这是NAXSI在阻止请求时将重定向的URL。该文件还允许列出NAXSI应该阻止的不同类型的攻击,包括SQL注入,跨站点脚本(XSS)和远程文件包含(RFI)。

由于您已将被阻止的请求重定向到 /error.html,您现在可以在 /usr/html 目录中创建一个 error.html 文件,以便为该目的地提供一个定位页面。

1sudo nano /usr/html/error.html

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

 1[label /usr/html/error.html]
 2<html>
 3  <head>
 4    <title>Blocked By NAXSI</title>
 5  </head>
 6  <body>
 7    <div style="text-align: center">
 8      <h1>Malicious Request</h1>
 9      <hr>
10      <p>This Request Has Been Blocked By NAXSI.</p>
11    </div>
12  </body>
13</html>

保存文件并离开编辑器。

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

1sudo nano /etc/nginx/nginx.conf

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

 1[label /etc/nginx/nginx.conf]
 2. . .
 3http {
 4    include mime.types;
 5    include /etc/nginx/naxsi_core.rules;
 6    include /etc/nginx/conf.d/*.conf;
 7    include /etc/nginx/sites-enabled/*;
 8
 9    default_type application/octet-stream;
10. . .

然后在同一文件的服务器部分中,添加以下突出的行:

 1[label /etc/nginx/nginx.conf]
 2. . .
 3    server {
 4        listen 80;
 5        server_name localhost;
 6
 7        #charset koi8-r;
 8
 9        #access_log logs/host.access.log main;
10
11        location / {
12        include /etc/nginx/naxsi.rules;
13            root html;
14            index index.html index.htm;
15        }
16. . .

现在你已经配置了 Nginx 与 NAXSI 的核心和基本规则,防火墙将在启动 Web 服务器时阻止匹配恶意请求。

步骤 3:为 Nginx 创建启动脚本

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

要做到这一点,您将创建一个 Unit 文件(参见 理解 Systemd 单位和 Unit 文件进一步研究)来配置 Systemd 应该如何启动和管理 Nginx 服务。

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

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

将以下行添加到文件中:

 1[label /lib/systemd/system/nginx.service]
 2[Unit]
 3Description=The NGINX HTTP and reverse proxy server
 4After=syslog.target network.target remote-fs.target nss-lookup.target
 5
 6[Service]
 7Type=forking
 8PIDFile=/run/nginx.pid
 9ExecStartPre=/usr/sbin/nginx -t
10ExecStart=/usr/sbin/nginx
11ExecReload=/usr/sbin/nginx -s reload
12ExecStop=/bin/kill -s QUIT $MAINPID
13PrivateTmp=true
14
15[Install]
16WantedBy=multi-user.target

[Unit]部分定义了您正在配置的程序,[Service]描述了 Nginx 在启动时应该如何行为,而[Install]提供了有关单元安装的信息。

接下来, Nginx 需要一个文件夹来暂时存储输入请求数据,然后在您的服务器没有足够的内存的情况下处理它。 由于您从源头上安装了 Nginx,您需要创建一个目录, Nginx 可以用来存储这些数据。

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

随着启动脚本的设置,您现在将能够启动 Nginx 服务器。

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

1sudo systemctl start nginx

要检查您的服务器是否活跃,请执行以下命令:

1sudo systemctl status nginx

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

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

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

步骤 4 – 测试 NAXSI

要测试 Nginx 是否在启用 NAXSI 模块时运行,您将尝试用恶意 HTTP 请求击中服务器并分析响应。

首先,复制您的服务器的公共IP,并使用弯曲命令对 Nginx 服务器进行恶意请求。

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

这个 URL 包含了 XSS 脚本,在 q 参数中包含了 XSS 脚本,并且应该被服务器拒绝. 根据您之前设置的 NAXSI 规则,您将被重定向到 error.html 文件,并收到以下响应:

 1[secondary_label Output]
 2<html>
 3  <head>
 4    <title>Blocked By NAXSI</title>
 5  </head>
 6  <body>
 7    <div style="text-align: center">
 8      <h1>Malicious Request</h1>
 9      <hr>
10      <p>This Request Has Been Blocked By NAXSI.</p>
11    </div>
12  </body>
13</html>

NAXSI 防火墙阻止了请求。

现在,使用 Nginx 日志来验证使用以下命令对 Nginx 服务器日志进行尾声:

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

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

1[secondary_label Output]
22018/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,退出尾巴,停止输出错误日志文件。

接下来,尝试另一个 URL 请求,这次使用恶意 SQL Injection 查询。

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

上面的URL的1`="1``部分可以在数据库中暴露用户的数据,并将被NAXSI阻止,它应该在终端产生相同的响应:

 1[secondary_label Output]
 2<html>
 3  <head>
 4    <title>Blocked By NAXSI</title>
 5  </head>
 6  <body>
 7    <div style="text-align: center">
 8      <h1>Malicious Request</h1>
 9      <hr>
10      <p>This Request Has Been Blocked By NAXSI.</p>
11    </div>
12  </body>
13</html>

现在使用尾巴再次跟踪服务器日志:

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

在日志文件中,您将看到 SQL Injection 尝试的封锁条目:

1[secondary_label Output]
22018/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 网络服务器是安全的。

结论

要了解有关设置 Nginx 的更多信息,请参阅 如何在 Ubuntu 16.04 上设置 Nginx 服务器块(虚拟主机)。如果您想继续研究 Web 服务器上的安全性,请参阅 如何在 Ubuntu 16.04 上使用Let's Encrypt 保护 Nginx如何在 Ubuntu 16.04 中为 Nginx 创建自签名的 SSL 证书

Published At
Categories with 技术
comments powered by Disqus