如何在Ubuntu14.04上安装和配置Naxsi

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

介绍

Naxsi 是一个第三方 Nginx 模块,提供 Web 应用防火墙功能。 它为您的 Web 服务器带来额外的安全性,并保护您免受各种 Web 攻击,例如 XSS 和 SQL 注入。

Naxsi 灵活而强大。 您可以为流行的 Web 应用程序(例如 WordPress)使用现成的规则。 同时,您还可以创建自己的规则并使用纳西的学习模式对其进行微调。

Naxsi 类似于 ModSecurity for Apache。 因此,如果您已经熟悉 ModSecurity 和/或寻求 Nginx 的类似功能,您肯定会对 Naxsi 感兴趣。 但是,您可能无法在 Naxsi 中找到 ModSecurity 的所有功能。

本教程向您展示如何安装 Naxsi、了解规则、创建白名单以及在哪里可以找到已经为常用 Web 应用程序编写的规则。

先决条件

在学习本教程之前,请确保您完成以下先决条件:

除非另有说明,本教程中所有需要 root 权限的命令都应以具有 sudo 权限的非 root 用户身份运行。

第 1 步 — 安装 Naxsi

要安装 Naxsi,你必须安装一个用它编译的 Nginx 服务器。 为此,您将需要包 nginx-naxsi。 您可以使用 apt-get 命令以通常的 Ubuntu 方式安装它:

sudo apt-get update
sudo apt-get install nginx-naxsi

这将安装 Naxsi 以及 Nginx 及其所有依赖项。 它还将确保服务在 Droplet 上自动启动和停止。

注意: 如果你已经安装了没有 Naxsi 的 Nginx,你需要用包 nginx-naxsi 替换包 nginx-core,或者你可能拥有的另一种 Nginx。 其他 Nginx 包不支持可加载模块,您不能仅将 Naxsi 加载到现有 Nginx 服务器中。

在大多数情况下,将 nginx-core 替换为 nginx-naxsi 是没有问题的,您可以继续使用之前的配置。 不过,在进行此类升级时,首先创建现有 /etc/nginx/ 目录的备份始终是一个好主意。 之后,按照说明进行新安装,并确认您同意删除系统上现有的 Nginx 包。


Nginx 的默认安装提供了一个基本的、可工作的 Nginx 环境,足以熟悉 Naxsi。 我们不会花时间定制 Nginx,而是直接配置 Naxsi。 但是,如果您没有使用 Nginx 的经验,最好查看 How To Install Nginx on Ubuntu 14.04 LTS 及其相关文章,尤其是 How To Set Up Nginx Server Blocks (Virtual Hosts)在 Ubuntu 14.04 LTS 上。

第 2 步 — 启用 Naxsi

首先,要启用 Naxsi,我们必须加载文件 /etc/nginx/naxsi_core.rules 中的核心规则。 此文件包含用于检测恶意攻击的通用签名。 稍后我们将更详细地讨论这些规则。 现在,我们只需将 Nginx 的主配置文件 /etc/nginx/nginx.conf 中的规则包含在 HTTP 侦听器部分。 因此,打开后一个文件以使用 nano 进行编辑:

sudo nano /etc/nginx/nginx.conf

然后找到 http 部分并通过删除行首的 # 字符来取消注释 Naxsi 规则的包含部分。 它现在应该是这样的:

/etc/nginx/nginx.conf

http {
...
        # nginx-naxsi config
        ##
        # Uncomment it if you installed nginx-naxsi
        ##

        include /etc/nginx/naxsi_core.rules;
...

保存文件并退出编辑器。

其次,我们必须启用之前的规则并为 Naxsi 配置一些基本选项。 默认情况下,基本 Naxsi 配置位于文件 /etc/nginx/naxsi.rules 中。 打开这个文件:

sudo nano /etc/nginx/naxsi.rules

仅将 DeniedUrl 的值更改为默认已存在的错误文件,其余保持不变:

/etc/nginx/naxsi.rules

# Sample rules file for default vhost.
LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
DeniedUrl "/50x.html";

## check rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;

保存文件并退出。

以下是上面的配置指令及其含义:

  • LearningMode - 在学习模式下启动 Naxsi。 这意味着实际上不会阻止任何请求。 Nginx 错误日志中只会引发安全异常。 这种非阻塞的初始行为很重要,因为默认规则相当激进。 稍后,根据这些例外情况,我们将为合法流量创建白名单。
  • SecRulesEnabled - 为服务器块/位置启用 Naxsi。 同样,您可以通过取消注释 SecRulesDisabled 为站点或站点的一部分禁用 Naxsi。
  • DeniedUrl - 拒绝请求将在内部发送到的 URL。 这是您应该更改的唯一设置。 您可以使用默认文档根目录 (/usr/share/nginx/html/50x.html) 中现成的 50x.html 错误页面,也可以创建自己的自定义错误页面。
  • CheckRule - 设置不同计数器的阈值。 一旦超过此阈值(例如 SQL 计数器 8 分)请求将被阻塞。 要使这些规则更具侵略性,请降低它们的值,反之亦然。

文件 naxsi.rules 必须在服务器块的每个位置基础上加载。 让我们为默认服务器块的根位置 (/) 加载它。 首先打开服务器块的配置文件/etc/nginx/sites-enabled/default

sudo nano /etc/nginx/sites-enabled/default

然后,找到根位置 / 并确保它看起来像这样:

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ =404;
            # Uncomment to enable naxsi on this location
            include /etc/nginx/naxsi.rules;
    }

警告: 确保在 naxsi.rulesinclude 语句末尾添加分号,因为默认情况下没有分号。 因此,如果您只取消注释该语句,则配置中会出现语法错误。


完成上述更改后,您可以重新加载 Nginx 以使更改生效:

sudo service nginx reload

下一步说明如何检查更改是否成功以及如何读取日志。

第 3 步 — 检查日志

为了确保 Naxsi 正常工作,即使仍处于学习模式,让我们访问应该引发异常的 URL 并查看异常的错误日志。

我们稍后会看到这条规则是如何运作的。 现在,跟踪 Nginx 的错误日志以查找异常(-f 选项保持输出打开并附加新内容:

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

尝试通过 URL http://Your_Droplet_IP/index.html?asd=---- 访问您的 Droplet。 这应该会触发 Naxsi 安全异常,因为破折号用于 SQL 中的注释,因此被视为 SQL 注入的一部分。

sudo tail -f /var/log/nginx/error.log 的输出中,您现在应该看到以下新内容:

Output of nginx's error log2015/11/14 03:58:35 [error] 4088#0: *1 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/index.html&learning=1&total_processed=24&total_blocked=1&zone0=ARGS&id0=1007&var_name0=asd, client: X.X.X.X, server: localhost, request: "GET /index.html?asd=---- HTTP/1.1", host: "Y.Y.Y.Y"

上面一行中最重要的部分被突出显示:zone0=ARGS&id0=1007&var_name0=asd。 它为您提供区域(请求的一部分)、触发规则的 id 以及可疑请求的变量名称。

此外,X.X.X.X 是您本地计算机的 IP,Y.Y.Y.Y 是您的 Droplet 的 IP。 URI 还包含请求的文件名 (index.htm)、Naxsi 仍在学习模式下工作的事实 (learning=1) 以及所有已处理请求的总数 ([ X182X])。

此外,在上述行之后,应该有一条关于重定向到 DeniedUrl 的消息:

Output of nginx's error log2015/11/14 03:58:35 [error] 4088#0: *1 rewrite or internal redirection cycle while internally redirecting to "/50x.html" while sending response to client, client: X.X.X.X, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "Y.Y.Y.Y", referrer: "http://Y.Y.Y.Y/index.html?asd=----"

当 Naxsi 处于学习模式时,此重定向只会显示在日志中,但实际上不会发生。

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

稍后,我们将更多地了解 Naxsi 的规则,然后对日志有基本的了解就很重要了。

第 4 步 — 配置 Naxsi 规则

Naxsi 配置中最重要的部分是它的规则。 有两种类型的规则——主要规则和基本规则。 主要规则(由 MainRule 标识)全局应用于服务器,因此是主要 Nginx 配置的 http 块的一部分。 它们包含用于检测恶意活动的通用签名。

基本规则(由 BasicRule 标识)主要用于将误报签名和规则列入白名单。 它们适用于每个位置,因此应该是服务器块 (vhost) 配置的一部分。

让我们从主要规则开始,看看文件/etc/nginx/naxsi_core.rules中的nginx-naxsi包提供的默认规则。 这是一个示例行:

/etc/nginx/naxsi_core.rules

...
MainRule "str:--" "msg:mysql comment (--)" "mz:BODY|URL|ARGS|$HEADERS_VAR:Cookie" "s:$SQL:4" id:1007;
...

从上面的规则中,我们可以概括出以下部分,它们是普遍存在的,并且存在于每条规则中:

  • MainRule 是开始每个规则的指令。 同样,每条规则都以规则的 id 号结尾。
  • str: 位于规则的第二部分。 如果是 str: 则意味着签名将是纯字符串,如上例所示。 正则表达式也可以与指令 rx: 匹配。
  • msg: 对规则进行了一些说明。
  • mz: 代表匹配区域,或者将检查请求的哪一部分。 这可能是正文、URL、参数等。
  • s: 确定找到签名时将分配的分数。 分数被添加到不同的计数器,例如 SQL(SQL 攻击)、RFI(远程文件包含攻击)等。

本质上,带有注释 mysql comments 的上述规则 (id 1007) 意味着如果在请求的任何部分(正文、参数等)中找到字符串 --,则 4点将被添加到 SQL 计数器。

如果我们回到在日志中触发 SQL 异常的示例 URI (http://Your_Droplet_IP/index.html?asd=----),您会注意到要触发规则 1007,我们需要 2 对破折号 (--)。 这是因为对于每一对我们得到 4 个点,而 SQL 链需要 8 个点来阻止请求。 因此,只有一对破折号不会有问题,并且在大多数情况下,合法流量不会受到影响。

一种特殊的规则指令是 negative。 如果签名不匹配,它会应用分数,即 当请求中的某些内容丢失时,您怀疑存在恶意活动。

例如,让我们看看同一个文件 /etc/nginx/naxsi_core.rules 中带有 id 1402 的规则:

/etc/nginx/naxsi_core.rules

...
MainRule negative "rx:multipart/form-data|application/x-www-form-urlencoded" "msg:Content is neither mulipart/x-www-form.." "mz:$HEADERS_VAR:Content-type" "s:$EVADE:4" id:1402;
...

上述规则意味着如果 Content-type 请求标头中既没有 multipart/form-data 也没有 application/x-www-form-urlencoded 则将 4 个点添加到 EVADE 计数器。 此规则也是如何将正则表达式 (rx:) 用于签名描述的示例。

第 5 步 — 白名单规则

默认的 Naxsi 规则几乎肯定会阻止您网站上的一些合法流量,特别是如果您有一个支持各种用户交互的复杂 Web 应用程序。 这就是为什么有白名单来解决这些问题。

白名单是使用第二种规则创建的,即 Naxsi 的基本规则。 使用基本规则,您可以将整个规则或部分规则列入白名单。

为了演示基本规则是如何工作的,让我们回到 SQL 注释规则(id 1007)。 假设您有一个文件名中有两个破折号的文件,例如 some--file.html 在您的网站上。 使用规则 1007,此文件将 SQL 计数器增加 4 个点。 仅此文件名和结果分数不足以阻止请求,但它仍然是可能导致问题的误报。 例如,如果我们还有一个包含两个破折号的参数,那么请求将触发规则 1007。

要对其进行测试,请像以前一样跟踪错误日志:

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

尝试访问 http://Your_Droplet_IP/some--file.html?asd=--。 你不需要在你的网站上有这个文件来进行测试。

您应该在错误日志的输出中看到与此类似的熟悉异常:

Output of nginx's error log2015/11/14 14:43:36 [error] 5182#0: *10 NAXSI_FMT: ip=X.X.X.X&server=Y.Y.Y.Y&uri=/some--file.html&learning=1&total_processed=10&total_blocked=6&zone0=URL&id0=1007&var_name0=&zone1=ARGS&id1=1007&var_name1=asd, client: X.X.X.X, server: localhost, request: "GET /some--file.html?asd=-- HTTP/1.1", host: "Y.Y.Y.Y"

CTRL-C 停止显示错误日志输出。

为了解决这个误报触发,我们需要一个如下所示的白名单:

BasicRule wl:1007 "mz:URL";

白名单的重要关键字是wl,后跟规则ID。 为了更准确地说,我们将什么列入白名单,我们还指定了匹配区域——URL。

要应用此白名单,首先为白名单创建一个新文件:

sudo nano /etc/nginx/naxsi_whitelist.rules

然后,将规则粘贴到文件中:

/etc/nginx/naxsi_whitelist.rules

BasicRule wl:1007 "mz:URL";

如果您有其他白名单,它们也可以进入此文件,每一个都在新行中。

带有白名单的文件必须包含在您的服务器块中。 要将其包含在默认服务器块中,请再次使用 nano:

sudo nano /etc/nginx/sites-enabled/default

然后在 Naxsi 的前一个之后添加新的包含,如下所示:

/etc/nginx/sites-enabled/default

        location / {
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 404.
                try_files $uri $uri/ =404;
                # Uncomment to enable naxsi on this location
                include /etc/nginx/naxsi.rules;
                include /etc/nginx/naxsi_whitelist.rules;
        }

要使此更改生效,请重新加载 Nginx:

sudo service nginx reload

现在,如果您在浏览器中再次尝试对 Your_Droplet_IP/some--file.html?asd=-- 的相同请求,只有等于两个破折号的 asd 参数将触发 SQL 计数器的 4 个点,但不常见的文件名不会。 因此,您不会在错误日志中将此请求视为异常。

编写所有必要的白名单可能是一项乏味的任务,而且本身就是一门科学。 这就是为什么一开始您可以使用现成的 Naxsi 白名单 。 大多数流行的网络应用程序都有这样的。 您只需要像我们刚才那样下载它们并将它们包含在服务器块中。

一旦您确定在错误日志中没有看到任何合法请求的异常,您可以禁用 Naxsi 的学习模式。 为此,使用 nano 打开文件 /etc/nginx/naxsi.rules

sudo nano /etc/nginx/naxsi.rules

通过在前面添加 # 字符来注释掉 LearningMode 指令,如下所示:

/etc/nginx/naxsi.rules

...
#LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
...

最后,重新加载 Nginx 以使更改生效:

sudo service nginx reload

现在,Naxsi 将阻止任何可疑请求,您的网站将更加安全。

结论

这就是使用 Nginx 和 Naxsi 构建 Web 应用程序防火墙是多么容易。 这对于开始来说已经足够了,希望您有兴趣了解更多强大的 Naxsi 模块所提供的功能。 现在你可以让你的 Nginx 服务器不仅快速而且安全。