Naxsi是第三方Nginx模块,提供Web应用程序防火墙功能。它为您的Web服务器带来了额外的安全性,并保护您的服务器免受各种Web攻击,如XSS和SQL的注入。
Naxsi灵活而强大。您可以使用现成的规则来处理流行的Web应用程序,例如WordPress。同时,您还可以使用Naxsi的学习模式创建自己的规则并对其进行微调。
Naxsi类似于Apache的ModSecurity。因此,如果您已熟悉ModSecurity和/或寻求Nginx的类似功能,您肯定会对Naxsi感兴趣。但是,您可能无法在Naxsi中找到ModSecurity的所有功能。
本教程介绍如何安装Naxsi,了解规则,创建白名单以及在何处查找已为常用Web应用程序编写的规则。
在学习本教程之前,请确保完成以下先决条件:
除非另有说明,否则本教程中需要root权限的所有命令都应作为具有sudo权限的非root用户运行。
要安装Naxsi,您必须安装使用它编译的Nginx服务器。为此,您将需要该nginx-naxsi
包。您可以使用以下apt-get
命令以通常的Ubuntu方式安装它:
sudo apt-get update
sudo apt-get install nginx-naxsi
这将安装Naxsi以及Nginx及其所有依赖项。它还将确保服务在腾讯CVM上自动启动和停止。
注意:果您已经安装了没有Naxsi的Nginx,则需要使用 nginx-naxsi
软件包或者其他您拥有的软件包来替换nginx-core
包。如果其他Nginx软件包不支持可加载模块,那您也不能只是将Naxsi加载到现有的Nginx服务器中。
在大多数情况下,用nginx-naxsi
来替换nginx-core
是没有问题的,并且你任然可以继续使用以前的配置
在更换大多数情况下,nginx-core
用nginx-naxsi
是没有问题的,你可以继续使用以前的配置。尽管如此,通过这种升级来创建现有/etc/nginx/
目录的备份仍然是个好主意。之后,请按照新安装的说明进行操作,并确认您同意删除系统上现有的Nginx软件包。
Nginx的默认安装提供了一个基本的,有效的Nginx环境,该环境足以让我们熟悉Naxsi。我们不会花时间定制Nginx,而是直接配置Naxsi。
首先,要启用Naxsi,我们必须加载/etc/nginx/naxsi_core.rules
文件中的核心规则。此文件包含用于检测恶意攻击的通用签名。我们稍后会详细讨论这些规则。现在,我们只是将规则包含在HTTP侦听器部分的Nginx主配置文件/etc/nginx/nginx.conf
中。因此,打开后一个文件进行nano编辑:
sudo nano /etc/nginx/nginx.conf
然后找到该http
部分并通过删除该行开头的#
字符取消注释Naxsi规则的include部分。它现在应该是这样的:
http {
...
# nginx-naxsi config
##
# Uncomment it if you installed nginx-naxsi
##
include /etc/nginx/naxsi_core.rules;
...
保存文件并退出编辑器。
其次,我们必须启用以前的规则并为Naxsi配置一些基本选项。默认情况下,在/etc/nginx/naxsi.rules
文件中找到基本的Naxsi配置。打开此文件:
sudo nano /etc/nginx/naxsi.rules
仅将DeniedUrl
的值更改为默认情况下已存在的错误文件,并保持其余不变:
# 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;
}
警告:确保在include
语句末尾为naxsi.rules
添加分号,因为默认情况下没有分号。因此,如果您只取消注释该语句,则配置中将出现语法错误。
完成上述更改后,您可以重新加载Nginx以使更改生效:
sudo service nginx reload
下一步说明如何检查更改是否成功以及如何读取日志。
为了确保Naxsi工作,即使仍处于学习模式,让我们访问应该抛出异常的URL并查看异常的错误日志。
我们稍后会看到这条规则是如何运作的。现在,拖尾Nginx的错误日志并找到异常(该-f
选项保持输出打开并向其添加新内容:
sudo tail -f /var/log/nginx/error.log
尝试通过URLhttp://Your_Droplet_IP/index.html?asd=----
访问您的腾讯CVM。这应该触发Naxsi安全性异常,因为破折号用于SQL中的注释,因此被认为是SQL注入的一部分。
在该输出sudo tail -f /var/log/nginx/error.log
中,您现在应该看到以下新内容:
2015/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
是腾讯CVM的IP。URI还包含request(index.htm
)的文件名,Naxsi仍在学习模式(learning=1
)中的事实,以及所有已处理请求的总数(total_processed=24
)。
此外,在上面的行之后,应该跟随有关重定向到 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规则的更多信息,此外,了解日志这一点是非常重要的。
Naxsi配置中最重要的部分是它的规则。有两种类型的规则 - 主要规则和基本规则。主要规则(标识为MainRule
)是全局应用于服务器,因此是主要Nginxhttp
配置块的一部分。它们包含用于检测恶意活动的通用签名。
基本规则(由...标识BasicRule
)主要是用于将假阳性签名和规则列入白名单。它们按位置应用,所以应该是服务器块(vhost)配置的一部分。
让我们从主要规则开始,然后看一下/etc/nginx/naxsi_core.rules
文件nginx-naxsi
包中提供的默认规则。这是一个示例行:
...
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
注释的上述rule(id 1007
)意味着如果在请求的任何部分(正文,参数等)中找到该--
字符串,则将向SQL计数器添加4个点。
如果我们回到触发日志中的SQL异常的示例URI(http://Your_Droplet_IP/index.html?asd=----
),您会注意到要触发规则1007,我们需要2对破折号(--
)。这是因为对于每一对我们得到4分,SQL链需要8分来阻止请求。因此,只有一对短划线是不会有问题,并且在大多数情况下合法的流量不会受到影响。
一条特殊规则指令是negative
。如果签名不匹配,它会应用分数,即当请求中的某些内容丢失时,您怀疑是恶意活动。
例如,让我们用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
,则将向EVADE计数器添加4个点。此规则也是正则表达式(rx:
)如何用于签名描述的示例。
默认的Naxsi规则几乎一定会阻止您网站上的某些合法流量,特别是如果您有一个支持各种用户交互的复杂Web应用程序。这就是为什么有白名单来解决这些问题。
使用第二种规则(Naxsi的基本规则)创建白名单。使用基本规则,您可以将整个规则或部分规则列入白名单。
为了演示基本规则的工作原理,让我们回到SQL注释规则(id 1007)。想象一下,在你的网站上,你有一个文件名中有两个短划线的文件,例如some--file.html
。使用规则1007,此文件将使用4个点增加SQL计数器。如果仅仅只有文件名和结果分数不足以阻止请求,而且它仍然是误报,这可能会导致问题。例如,如果我们还有一个带有两个破折号的参数,那么请求将触发规则1007。
要测试它,像以前一样拖尾错误日志:
sudo tail -f /var/log/nginx/error.log
尝试访问http://Your_TencentCVM_IP/some--file.html?asd=--
。您无需在您的网站上提供此文件进行测试。
您应该在错误日志的输出中看到类似于此类的熟悉异常:
2015/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
然后,将规则粘贴到文件中:
BasicRule wl:1007 "mz:URL";
如果你有其他白名单,他们也可以进入这个文件,每个都在新行上。
带有白名单的文件必须包含在您的服务器块中。要将其包含在默认服务器块中,请再次使用nano:
sudo nano /etc/nginx/sites-enabled/default
然后在Naxsi的前一个之后添加新的include,如下所示:
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_TencentCVM_IP/some--file.html?asd=--
再次尝试相同的请求,只有等于两个破折号的asd
参数将为SQL计数器触发4个点,但不常见的文件名不会。因此,您不会在错误日志中将此请求视为异常。
编写所有必要的白名单可能是一项繁琐的任务,也是一门独立的科学。这就是为什么一开始你可以使用现成的Naxsi白名单。对于最流行的Web应用程序,现在是有这样的白名单的。您只需下载它们并将它们包含在服务器块中就可以了,就像我们刚才所做的那样。
一旦确定在错误日志中没有看到合法请求的任何例外,就可以禁用Naxsi的学习模式。为此,用nano 打开/etc/nginx/naxsi.rules
文件:
sudo nano /etc/nginx/naxsi.rules
通过在LearningMode
前面添加#
字符来注释掉该指令,如下所示:
...
#LearningMode;
SecRulesEnabled;
#SecRulesDisabled;
...
最后,重新加载Nginx以使更改生效:
sudo service nginx reload
现在,Naxsi将阻止任何可疑请求,您的网站将更安全。
这就是使用Nginx和Naxsi构建Web应用程序防火墙的难易程度。这对于初学者来说就足够了,希望您有兴趣了解更强大的Naxsi模块所提供的功能。现在,您可以使您的Nginx服务器不仅速度快,而且安全。
更多Ubuntu教程请前往腾讯云+社区学习更多知识。
参考文献:《How To Install and Configure Naxsi on Ubuntu 14.04》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。