如何在 Ubuntu 14.04 和 Debian 8 上使用 Apache 设置 ModSecurity

介绍

ModSecurity是一个免费的Web应用程序防火墙(WAF),它与Apache,Nginx和IIS一起工作. 它支持灵活的规则引擎来执行简单和复杂的操作,并配备了核心规则集(CRS),其中包含SQL注入,跨站点脚本,木马,坏用户代理,会话劫持和许多其他利用。

前提条件

要遵循本教程,您将需要:

  • Ubuntu 14.04 或 Debian 8 Droplet.
  • 具有 sudo 特权的标准用户帐户,您可以通过遵循 Ubuntu 14.04Debian 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 来定制其他指令。 SecRequestBodyLimitSecRequestBodyNoFilesLimit 指令限制可以发布到您的 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

我们正在阻止的两个单词是 blockedword1blockedword2

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_FILENAMEform.php,REQUEST_METHODPOST,以及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文档

Published At
Categories with 技术
comments powered by Disqus