ModSecurity是一个免费的Web应用程序防火墙(WAF),可与Apache,Nginx和IIS配合使用。它支持灵活的规则引擎来执行简单和复杂的操作,并附带核心规则集(CRS),其中包含SQL注入,跨站点脚本,特洛伊木马,恶意用户代理,会话劫持和许多其他漏洞利用的规则。Apache作为附加模块加载,是易于安装和配置的。
要学习本教程,您需要:
没有服务器的同学可以在这里购买,不过我个人更推荐您使用免费的腾讯云开发者实验室进行试验,学会安装后再购买服务器。
在此步骤中,我们将安装ModSecurity。
首先,更新包索引文件。
sudo apt-get update
然后,安装ModSecurity。
sudo apt-get install libapache2-mod-security2 -y
您可以使用以下命令验证是否已加载ModSecurity模块。
sudo apachectl -M | grep --color security2
如果输出为security2_module (shared)
,则表示模块已加载。
ModSecurity的安装包括一个必须重命名的推荐配置文件。
sudo mv /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf
最后,重新加载Apache。
sudo service apache2 reload
将在/var/log/apache2/modsec_audit.log
中的Apache日志目录中创建ModSecurity的新日志文件。
开箱即用,ModSecurity没有做任何事情,因为它需要规则才能工作。在此步骤中,我们将首先启用一些配置指令。
要在此步骤中查找和替换配置指令,我们将使用sed
流编辑器。
将默认的ModSecurity配置文件设置为DetectionOnly
,根据规则匹配记录请求,不阻止任何内容。这可以通过编辑modsecurity.conf
文件和修改SecRuleEngine
指令来更改。如果您在生产服务器上尝试此操作,请仅在测试所有规则后更改此指令。
sudo sed -i "s/SecRuleEngine DetectionOnly/SecRuleEngine On/" /etc/modsecurity/modsecurity.conf
该SecResponseBodyAccess
指令配置是否缓冲响应主体(即由ModSecurity读取)。只有在需要数据泄漏检测和保护时才需要这样做。因此,将其保留将使用腾讯云CVM资源并增加日志文件大小,因此我们将其关闭。
sudo sed -i "s/SecResponseBodyAccess On/SecResponseBodyAccess Off/" /etc/modsecurity/modsecurity.conf
您可能希望通过编辑/etc/modsecurity/modsecurity.conf
自定义其他指令。在SecRequestBodyLimit
和SecRequestBodyNoFilesLimit
指令限制可以发布到Web应用程序的最大数据。
特别是,该SecRequestBodyLimit
指令指定了最大POST数据大小。如果客户端发送任何更大的内容,服务器将响应413请求实体太大错误。如果您的Web应用程序没有任何文件上载,则可以保留此值。配置文件中指定的预配置值为13107200字节(12.5MB)。如果要更改此值,请查找modsecurity.conf
行:
SecRequestBodyLimit 13107200
同样,SecRequestBodyNoFilesLimit
限制POST数据的大小减去文件上载。应该将此值设置得尽可能低,以便在有人发送非常大的请求主体时降低对拒绝服务(DoS)攻击的敏感性。配置文件中的预配置值为131072字节(128KB)。如果要更改此值,请查找modsecurity.conf
行:
SecRequestBodyNoFilesLimit 131072
影响服务器性能的指令是SecRequestBodyInMemoryLimit
。该指令几乎是不言自明的; 它指定应将多少“请求体”数据(POST数据)保存在内存(RAM)中,更多内容将被放置在硬盘中(就像交换一样)。由于腾讯云CVM使用SSD,因此这不是什么大问题。但是,如果您有备用RAM,则可以更改此设置。此指令的预配置值为128KB。如果要更改此值,请查找modsecurity.conf
行:
SecRequestBodyInMemoryLimit 131072
在配置一些规则之前,我们将创建一个易受SQL注入攻击的PHP脚本,以测试ModSecurity的保护。
注意:这是一个基本的PHP登录脚本,没有会话处理或表单卫生。它仅用作测试SQL注入和ModSecurity规则的示例。它将在本教程结束之前删除。
首先,访问MySQL提示符。
mysql -u root -p
在这里,创建一个名为sample的MySQL数据库并连接到它。
create database sample;
connect sample;
然后创建一个包含一些凭据的表 - 用户名sammy和密码密码。
create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('sammy','password');
最后,退出MySQL提示符。
quit;
接下来,在Apache的文档根目录中创建登录脚本。
sudo nano /var/www/html/login.php
将以下PHP脚本粘贴到该文件中。请务必将下面脚本中的MySQL密码更改为您之前设置的密码,以便脚本可以连接到数据库:
<html>
<body>
<?php
if(isset($_POST['login']))
{
$username = $_POST['username'];
$password = $_POST['password'];
$con = mysqli_connect('localhost','root','your_mysql_password','sample');
$result = mysqli_query($con, "SELECT * FROM `users` WHERE username='$username' AND password='$password'");
if(mysqli_num_rows($result) == 0)
echo 'Invalid username or password';
else
echo '<h1>Logged in</h1><p>This is text that should only be displayed when logged in with valid credentials.</p>';
}
else
{
?>
<form action="" method="post">
Username: <input type="text" name="username"/><br />
Password: <input type="password" name="password"/><br />
<input type="submit" name="login" value="Login"/>
</form>
<?php
}
?>
</body>
</html>
此脚本将显示登录表单。打开浏览器并导航到http://your_server_ip/login.php
查看它。如果输入正确的凭证对,例如“ 用户名”字段中的“ sammy” 和“ 密码”字段中的密码,您将看到消息“ 这是仅在使用有效凭据登录时才会显示的文本”。如果您导航回登录屏幕并使用不正确的凭据,您将看到消息无效的用户名或密码。
下一个工作是尝试SQL注入以绕过登录页面。为用户名字段输入以下内容。
' or true --
请注意,注入--
后应该有一个空格。将密码字段留空并点击登录按钮。该脚本显示了针对经过身份验证的用户的消息!在下一步中,我们将阻止这一点。
在此步骤中,我们将设置一些ModSecurity规则。
为了简化操作,有许多规则已经与ModSecurity一起安装。这些称为CRS(核心规则集),位于/usr/share/modsecurity-crs
目录中。要加载这些规则,我们需要配置Apache以读取这些目录中的文件.conf
,因此请打开文件security2.conf
进行编辑。
sudo nano /etc/apache2/mods-enabled/security2.conf
在文件(</IfModule>
)的最后一行之前添加以下两个指令。
IncludeOptional /etc/modsecurity/*.conf
IncludeOptional "/usr/share/modsecurity-crs/*.conf"
IncludeOptional "/usr/share/modsecurity-crs/activated_rules/*.conf"
</IfModule>
保存并关闭文件。
有时排除特定目录或域名(如果它正在运行应用程序,如phpMyAdmin)是有意义的,因为ModSecurity将阻止SQL查询。最好排除像WordPress这样的CMS应用程序的管理后端。如果您在新服务器上学习本教程,则可以跳过此步骤。
要为完整的VirtualHost禁用ModSecurity,请将以下指令放在其虚拟主机文件的<VirtualHost>[...]</VirtualHost>
块中。
<IfModule security2_module>
SecRuleEngine Off
</IfModule>
要省略特定目录(例如/var/www/wp-admin
):
<Directory "/var/www/wp-admin">
<IfModule security2_module>
SecRuleEngine Off
</IfModule>
</Directory>
如果您不想在目录中完全禁用ModSecurity,请使用该SecRuleRemoveById
指令通过指定其ID来删除特定规则或规则链。
<LocationMatch "/wp-admin/update.php">
<IfModule security2_module>
SecRuleRemoveById 981173
</IfModule>
</LocationMatch>
接下来,我们将激活SQL注入规则文件。所需的规则文件应该符号链接到activated_rules
目录,这类似于Apache的mods-enabled
目录。切换到activated_rules
目录。
cd /usr/share/modsecurity-crs/activated_rules/
然后从modsecurity_crs_41_sql_injection_attacks.conf
文件创建一个符号链接。
sudo ln -s ../base_rules/modsecurity_crs_41_sql_injection_attacks.conf .
最后,重新加载Apache以使规则生效。
sudo service apache2 reload
现在打开我们之前创建的登录页面,尝试在用户名字段上使用相同的SQL注入查询。因为我们在第2步中将SecRuleEngine
指令更改为On
,所以会显示403 Forbidden错误。(如果SecRuleEngine
只剩下DetectionOnly
选项,注入将成功但尝试将记录在modsec_audit.log
文件中。)
因为此PHP登录脚本仅用于测试ModSecurity,所以您应该在测试完成后将其删除。
sudo rm /var/www/html/login.php
在本节中,我们将创建一个规则链,如果在HTML表单中输入通常与垃圾邮件相关的某些单词,则会阻止请求。
首先,我们将创建一个示例PHP脚本,该脚本从文本框中获取输入并将其显示回用户。打开一个名为form.php
的文件来编辑。
sudo nano /var/www/html/form.php
粘贴以下代码:
<html>
<body>
<?php
if(isset($_POST['data']))
echo $_POST['data'];
else
{
?>
<form method="post" action="">
Enter something here:<textarea name="data"></textarea>
<input type="submit"/>
</form>
<?php
}
?>
</body>
</html>
自定义规则可以添加到任何配置文件中,也可以放在ModSecurity目录中。我们将把规则放在一个名为modsecurity_custom_rules.conf
的单独的新文件中。
sudo nano /etc/modsecurity/modsecurity_custom_rules.conf
将以下内容粘贴到此文件中。我们阻止的两个词是blockedword1和blockedword2。
SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(blockedword1|blockedword2))"
SecRule
的语法是SecRule VARIABLES OPERATOR [ACTIONS]
。在这里,我们所使用的链动作相匹配的变量REQUEST_FILENAME
与form.php
,REQUEST_METHOD
与POST
和REQUEST_BODY
与正则表达式(@rx)
的字符串(blockedword1|blockedword2)
。这?i:
是一个不区分大小写的匹配。在成功匹配所有这三个规则时,将ACTION
拒绝并使用msg "Spam detected."
链操作进行记录。链动作模拟逻辑AND以匹配所有三个规则。
保存文件并重新加载Apache。
sudo service apache2 reload
在浏览器中打开http://your_server_ip/form.php
。如果输入包含blockedword1或blockedword2的文本,您将看到403页面。
由于此PHP表单脚本仅用于测试ModSecurity,因此您应该在测试完成后将其删除。
sudo rm /var/www/html/form.php
在本教程中,您学习了如何安装和配置ModSecurity,以及添加自定义规则。
想要了解更多关于使用Apache设置ModSecurity的相关教程,请前往腾讯云+社区学习更多知识。
参考文献:《How To Set Up ModSecurity with Apache on Ubuntu 14.04 and Debian 8》
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。