介绍
ModSecurity是一个免费的Web应用程序防火墙(WAF),它与Apache,Nginx和IIS一起工作. 它支持灵活的规则引擎来执行简单和复杂的操作,并配备了核心规则集(CRS),其中包含SQL注入,跨站点脚本,木马,坏用户代理,会话劫持和许多其他利用。
前提条件
要遵循本教程,您将需要:
- Ubuntu 14.04 或 Debian 8 Droplet.
- 具有 sudo 特权的标准用户帐户,您可以通过遵循 Ubuntu 14.04或 Debian 8的初始服务器设置教程来设置。
步骤 1 – 安装 ModSecurity
在此步骤中,我们将安装ModSecurity。
首先,更新包索引文件。
1sudo apt-get update
然后安装 ModSecurity。
1sudo apt-get install libapache2-mod-security2 -y
您可以使用以下命令验证 ModSecurity 模块已加载。
1sudo apachectl -M | grep --color security2
如果输出表示security2_module (shared)
,则表示该模块已加载。
ModSecurity的安装包括一个推荐的配置文件,必须更名。
1sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
最后,重新加载Apache。
1sudo service apache2 reload
ModSecurity 的新日志文件将在 Apache 日志目录中创建到 `/var/log/apache2/modsec_audit.log。
步骤 2 – 配置 ModSecurity
除了盒子之外,ModSecurity没有做任何事情,因为它需要规则来工作. 在此步骤中,我们将首先启用一些配置指令。
要找到并更换此步骤中的配置指令,我们将使用sed
,一个流编辑器. 您可以阅读 `sed’ 教程系列来了解有关该工具的更多信息。
基本指令,使
默认的 ModSecurity 配置文件设置为DetectionOnly
,该文件根据规则匹配记录请求,而不会阻止任何内容。通过编辑modsecurity.conf
文件并修改SecRuleEngine
指令,可以更改此功能。
1sudo sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /etc/modsecurity/modsecurity.conf
SecResponseBodyAccess
指令配置了响应器官是否被缓冲(即通过ModSecurity读取)。这只有在需要数据泄露检测和保护的情况下才有必要。
1sudo sed -i "s/SecResponseBodyAccess On/SecResponseBodyAccess Off/" /etc/modsecurity/modsecurity.conf
可选指令修改
您可以通过编辑 /etc/modsecurity/modsecurity.conf
来定制其他指令。 SecRequestBodyLimit
和 SecRequestBodyNoFilesLimit
指令限制可以发布到您的 Web 应用程序的最大数据。
具体而言,SecRequestBodyLimit
指令规定了最大POST数据大小。如果客户端发送了更大的东西,服务器将以 413 Request Entity Too Large] 错误响应。如果您的 Web 应用程序没有任何文件上传,则可以将此值保留为现状。配置文件中指定的预配置值为 13107200 字节(12,5 MB)。
1[label Optional `modsecurity.conf` directive change]
2SecRequestBodyLimit 13107200
同样,SecRequestBodyNoFilesLimit
限制了POST数据大小减去文件上传的值,该值应尽可能降低,以减少在某人发送非常大的请求机构时对拒绝服务(DoS)攻击的敏感性。配置文件中的预配置值为131072字节(128KB)。
1[label Optional `modsecurity.conf` directive change]
2SecRequestBodyNoFilesLimit 131072
一个影响服务器性能的指令是SecRequestBodyInMemoryLimit
。这个指令相当于自我解释;它规定了多少请求体
数据(POSTed数据)应该存储在内存(RAM),任何其他东西都将被放置在硬盘(就像交换一样)。由于Droplets使用SSD,这不是很多问题。然而,如果您需要储存RAM,这可以改变。本指令的预配置值是128KB。如果你想改变这个值,请寻找下面的行:modsecurity.conf
:
1[label Optional `modsecurity.conf` directive change]
2SecRequestBodyInMemoryLimit 131072
步骤 3 – 测试 SQL 注射
在配置一些规则之前,我们将创建一个易受 SQL 注射的 PHP 脚本,以测试 ModSecurity 的保护。
<$>[注] 注意:这是一个基本的PHP登录脚本,没有会话处理或表单清理。它只是用作例子来测试SQL注射和ModSecurity的规则。
首先,请访问 MySQL 提示。
1mysql -u root -p
在这里,创建一个名为 sample的MySQL数据库,并连接到它。
1create database sample;
2connect sample;
然后创建一个包含某些身份证的表 - 用户名 sammy和密码 密码。
1create table users(username VARCHAR(100),password VARCHAR(100));
2insert into users values('sammy','password');
最后,输出 MySQL 提示。
1quit;
接下来,在 Apache 文档根中创建登录脚本。
1sudo nano /var/www/html/login.php
将下面的 PHP 脚本粘贴到文件中,请确保在下面的脚本中更改 MySQL 密码,以便脚本可以连接到数据库:
1[label /var/www/html/login.php]
2
3<html>
4<body>
5<?php
6 if(isset($_POST['login']))
7 {
8 $username = $_POST['username'];
9 $password = $_POST['password'];
10 $con = mysqli_connect('localhost','root','your_mysql_password','sample');
11 $result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");
12 if(mysqli_num_rows($result) == 0)
13 echo 'Invalid username or password';
14 else
15 echo '<h1>Logged in</h1><p>This is text that should only be displayed when logged in with valid credentials.</p>';
16 }
17 else
18 {
19?>
20 <form action="" method="post">
21 Username: <input type="text" name="username"/><br />
22 Password: <input type="password" name="password"/><br />
23 <input type="submit" name="login" value="Login"/>
24 </form>
25<?php
26 }
27?>
28</body>
29</html>
打开您的浏览器并导航到http://your_server_ip/login.php
查看它. 如果您输入正确的凭证对,例如在 Username字段和 Password字段中的密码,您将看到消息 这只是在登录时才会显示的文本. 如果您返回登录屏幕并使用错误的凭证,您将看到消息 无效的用户名或密码。
下一个任务是尝试 SQL 注射来绕过登录页面。
1[label SQL injection username]
2' or true --
请注意,此注射后应该有一个空间,以便工作。 让密码字段空,然后点击登录按钮。 脚本显示面向验证用户的消息! 在下一步,我们将防止这种情况发生。
步骤四:制定规则
在此步骤中,我们将设置一些ModSecurity规则。
允许CRS
为了使事情变得更容易,有很多规则已经与ModSecurity一起安装了,这些规则被称为CRS(核心规则集),并位于/usr/share/modsecurity-crs
目录中。
1sudo nano /etc/apache2/mods-enabled/security2.conf
添加以下两个指令,红色突出,在文件的最后一行之前(</IfModule>
)。
1[label Updated security2.conf]
2 IncludeOptional /etc/modsecurity/*.conf
3 IncludeOptional "/usr/share/modsecurity-crs/*.conf"
4 IncludeOptional "/usr/share/modsecurity-crs/activated_rules/*.conf"
5</IfModule>
保存并关闭文件。
排除目录/域名(可选)
有时,如果它运行一个应用程序,如phpMyAdmin,将排除特定目录或域名是有意义的,因为ModSecurity将阻止SQL查询。
要禁用完整的 VirtualHost 的 ModSecurity,请将下列指令放置在其虚拟主机文件中的<VirtualHost>[...]</VirtualHost>
块中。
1<IfModule security2_module>
2 SecRuleEngine Off
3</IfModule>
若要省略特定目录(例如, /var/www/wp-admin
):
1<Directory "/var/www/wp-admin">
2 <IfModule security2_module>
3 SecRuleEngine Off
4 </IfModule>
5</Directory>
如果您不想在目录中完全禁用 ModSecurity,请使用SecRuleRemoveById
指令通过指定其ID来删除特定规则或规则链。
1<LocationMatch "/wp-admin/update.php">
2 <IfModule security2_module>
3 SecRuleRemoveById 981173
4 </IfModule>
5</LocationMatch>
激活 SQL 注射规则
接下来,我们将激活 SQL 注入规则文件. 所需的规则文件应与activated_rules
目录同步链接,类似于 Apache 的mods-enabled
目录。
1cd /usr/share/modsecurity-crs/activated_rules/
然后从modsecurity_crs_41_sql_injection_attacks.conf
文件中创建一个符号链接。
1sudo ln -s ../base_rules/modsecurity_crs_41_sql_injection_attacks.conf .
最后,重新加载Apache,以便规则生效。
1sudo service apache2 reload
现在打开我们之前创建的登录页面,并尝试在用户名字段中使用相同的 SQL 注入查询. 因为我们在步骤 2 中将SecRuleEngine
指令更改为On
,会显示一个 403 Forbidden 错误。
由于此PHP登录脚本仅用于测试ModSecurity,您应该在测试结束后删除它。
1sudo rm /var/www/html/login.php
步骤五:写下自己的规则
在本节中,我们将创建一个规则链,如果某些通常与垃圾邮件相关的单词在HTML格式中输入,则将阻止请求。
首先,我们将创建一个示例的PHP脚本,从文本框中获取输入,并将其显示给用户。
1sudo nano /var/www/html/form.php
输入以下代码:
1[label /var/www/html/form.php]
2<html>
3 <body>
4 <?php
5 if(isset($_POST['data']))
6 echo $_POST['data'];
7 else
8 {
9 ?>
10 <form method="post" action="">
11 Enter something here:<textarea name="data"></textarea>
12 <input type="submit"/>
13 </form>
14 <?php
15 }
16 ?>
17 </body>
18</html>
定制规则可以添加到任何配置文件或放置在ModSecurity目录中,我们将我们的规则放置在一个名为modsecurity_custom_rules.conf
的新文件中。
1sudo nano /etc/modsecurity/modsecurity_custom_rules.conf
我们正在阻止的两个单词是 blockedword1和 blockedword2。
1[label modsecurity_custom_rules.conf]
2SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
3SecRule REQUEST_METHOD "POST" chain
4SecRule REQUEST_BODY "@rx (?i:(blockedword1|blockedword2))"
在这里,我们使用链操作来匹配变量REQUEST_FILENAME
与form.php
,REQUEST_METHOD
与POST
,以及REQUEST_BODY
与(@rx)
字符串(blockedword1 Doueblockedword2)
的常规表达式。i:
做了一个案例不敏感的匹配。在所有这三个规则的成功匹配中,ACTION
是否定日志,并用msg``Spam 检测到
。
保存文件并重新加载Apache。
1sudo service apache2 reload
在浏览器中打开http://your_server_ip/form.php
。 如果输入包含 blockedword1 或 blockedword2 的文本,你会看到一个 403 页面。
由于此PHP表格脚本仅用于测试ModSecurity,您应该在测试结束后删除它。
1sudo rm /var/www/html/form.php
结论
在本教程中,您已了解如何安装和配置ModSecurity,并添加自定义规则. 要了解更多信息,您可以查看 官方ModSecurity文档。