如何在 Debian/Ubuntu 上使用 Apache 设置 mod_security如何在 Debian/Ubuntu 上使用 Apache 设置 mod_security如何在 Debian/Ubuntu 上使用 Apache 设置 mod_security如何在 Debian/Ubuntu 上使用 Apache 设置 mod_security
  • 文章
  • 正则表达式
    • 工具
  • 登录
找到的结果: {phrase} (显示: {results_count} 共: {results_count_total})
显示: {results_count} 共: {results_count_total}

加载更多搜索结果...

搜索范围
模糊匹配
搜索标题
搜索内容
发表 admin at 2025年2月28日
类别
  • 未分类
标签

如何在 Debian/Ubuntu 上使用 Apache 设置 mod_security

序幕

Mod security 是一款免费的 Web 应用程序防火墙 (WAF),可与 Apache、Nginx 和 IIS 配合使用。它支持灵活的规则引擎来执行简单和复杂的操作,并附带一个核心规则集 (CRS),其中包含 SQL 注入、跨站点脚本、特洛伊木马、不良用户代理、会话劫持和许多其他攻击的规则。对于 Apache,它是一个附加模块,可以轻松安装和配置。

为了完成本教程,您需要在服务器上安装 LAMP。

安装 mod_security

Modsecurity 在 Debian/Ubuntu 存储库中可用:

apt-get install libapache2-modsecurity

验证是否加载了 mod_security 模块。

apachectl -M | grep --color security

您应该会看到一个名为 security2_module (shared) 的模块,这表明该模块已加载。

Modsecurity 的安装包括一个必须重命名的推荐配置文件:

mv /etc/modsecurity/modsecurity.conf{-recommended,}

重新加载阿帕奇

service apache2 reload

您会在 Apache 日志目录中找到一个新的 mod_security 日志文件:

root@droplet:~# ls -l /var/log/apache2/modsec_audit.log
-rw-r----- 1 root root 0 Oct 19 08:08 /var/log/apache2/modsec_audit.log

配置 mod_security

开箱即用,modsecurity 不做任何事情,因为它需要规则才能工作。默认配置文件设置为 DetectionOnly,它根据规则匹配记录请求并且不阻止任何内容。这可以通过编辑 modsecurity.conf 文件来更改:

nano /etc/modsecurity/modsecurity.conf

找到这一行

SecRuleEngine DetectionOnly

并将其更改为:

SecRuleEngine On

如果您在生产服务器上尝试此操作,请仅在测试所有规则后更改此指令。

另一个要修改的指令是 SecResponseBodyAccess。这配置是否缓冲响应主体(即由 modsecurity 读取)。只有在需要数据泄漏检测和保护时才需要这样做。因此,让它开启会耗尽 droplet 资源并增加日志文件的大小。

找到这个

SecResponseBodyAccess On

并将其更改为:

SecResponseBodyAccess Off

现在我们将限制可以发布到您的 Web 应用程序的最大数据量。两个指令配置这些:

SecRequestBodyLimit
SecRequestBodyNoFilesLimit

SecRequestBodyLimit 指令指定最大 POST 数据大小。如果客户端发送任何更大的内容,服务器将响应 413 Request Entity Too Large 错误。如果你的 web 应用程序没有任何文件上传,这个值可以大大减少。

配置文件中提到的值是

SecRequestBodyLimit 13107200

这是12.5MB。

与此类似的是 SecRequestBodyNoFilesLimit 指令。唯一的区别是这个指令限制了 POST 数据减去文件上传的大小——这个值应该“尽可能低”。

配置文件中的值为

SecRequestBodyNoFilesLimit 131072

这是128KB。

沿着这些指令的路线是另一个影响服务器性能的指令:SecRequestBodyInMemoryLimit。该指令几乎是不言自明的;它指定了多少“请求主体”数据(POSTed 数据)应该保存在内存(RAM)中,更多的东西将被放置在硬盘中(就像交换一样)。由于液滴使用 SSD,所以这不是太多一个问题;但是,如果您有备用 RAM,则可以设置一个不错的值。

SecRequestBodyInMemoryLimit 131072

这是配置文件中指定的值 (128KB)。

测试 SQL 注入

在继续配置规则之前,我们将创建一个易受 SQL 注入攻击的 PHP 脚本并进行试用。请注意,这只是一个没有会话处理的基本 PHP 登录脚本。请务必更改以下脚本中的 MySQL 密码,以便它连接到数据库:

<代码>/var/www/login.php

<html>
<body>
<?php
    if(isset($_POST['login']))
    {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $con = mysqli_connect('localhost','root','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>A Secret for you....</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>

该脚本将显示一个登录表单。输入正确的凭据将显示一条消息“A Secret for you”。

我们需要数据库中的凭据。创建一个 MySQL 数据库和一个表,然后插入用户名和密码。

mysql -u root -p

这将带您进入 mysql> 提示符

create database sample;
connect sample;
create table users(username VARCHAR(100),password VARCHAR(100));
insert into users values('jesin','pwd');
insert into users values('alice','secret');
quit;

打开浏览器,导航至 http://yourwebsite.com/login.php 并输入正确的凭据对。

Username: jesin
Password: pwd

您会看到一条消息,表明登录成功。现在回来输入一对错误的凭据——您会看到消息无效的用户名或密码。

我们可以确认脚本工作正常。接下来的工作是尝试使用 SQL 注入来绕过登录页面。在用户名字段中输入以下内容:

' or true -- 

请注意,在 -- 之后应该有一个空格,如果没有该空格,此注入将无法工作。将密码字段留空,然后点击登录按钮。

瞧!该脚本显示了针对经过身份验证的用户的消息。

设置规则

为了让您的生活更轻松,有很多规则已经与 mod_security 一起安装。这些称为 CRS(核心规则集),位于

root@droplet:~# ls -l /usr/share/modsecurity-crs/
total 40
drwxr-xr-x 2 root root  4096 Oct 20 09:45 activated_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 base_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 experimental_rules
drwxr-xr-x 2 root root  4096 Oct 20 09:45 lua
-rw-r--r-- 1 root root 13544 Jul  2  2012 modsecurity_crs_10_setup.conf
drwxr-xr-x 2 root root  4096 Oct 20 09:45 optional_rules
drwxr-xr-x 3 root root  4096 Oct 20 09:45 util

该文档位于

root@droplet1:~# ls -l /usr/share/doc/modsecurity-crs/
total 40
-rw-r--r-- 1 root root   469 Jul  2  2012 changelog.Debian.gz
-rw-r--r-- 1 root root 12387 Jun 18  2012 changelog.gz
-rw-r--r-- 1 root root  1297 Jul  2  2012 copyright
drwxr-xr-x 3 root root  4096 Oct 20 09:45 examples
-rw-r--r-- 1 root root  1138 Mar 16  2012 README.Debian
-rw-r--r-- 1 root root  6495 Mar 16  2012 README.gz

要加载这些规则,我们需要告诉 Apache 查看这些目录。编辑 modsecurity.conf 文件。

nano /etc/apache2/mods-enabled/modsecurity.conf

在 中添加以下指令:

Include "/usr/share/modsecurity-crs/*.conf"
Include "/usr/share/modsecurity-crs/activated_rules/*.conf"

activated_rules 目录类似于 Apache 的 mods-enabled 目录。规则在目录中可用:

/usr/share/modsecurity-crs/base_rules
/usr/share/modsecurity-crs/optional_rules
/usr/share/modsecurity-crs/experimental_rules

必须在 activated_rules 目录中创建符号链接才能激活它们。让我们激活 SQL 注入规则。

cd /usr/share/modsecurity-crs/activated_rules/
ln -s /usr/share/modsecurity-crs/base_rules/modsecurity_crs_41_sql_injection_attacks.conf .

必须重新加载 Apache 才能使规则生效。

service apache2 reload

现在打开我们之前创建的登录页面并尝试在用户名字段上使用 SQL 注入查询。如果您已将 SecRuleEngine 指令更改为 On,您将看到 403 Forbidden 错误。如果留给 DetectionOnly 选项,注入将成功,但尝试将记录在 modsec_audit.log 文件中。

编写自己的 mod_security 规则

在本节中,我们将创建一个规则链,如果在 HTML 表单中输入某些“垃圾”单词,它会阻止请求。首先,我们将创建一个 PHP 脚本,它从文本框中获取输入并将其显示回用户。

<代码>/var/www/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 目录中。我们会将我们的规则放在一个单独的新文件中。

nano /etc/modsecurity/modsecurity_custom_rules.conf

将以下内容添加到此文件中:

SecRule REQUEST_FILENAME "form.php" "id:'400001',chain,deny,log,msg:'Spam detected'"
SecRule REQUEST_METHOD "POST" chain
SecRule REQUEST_BODY "@rx (?i:(pills|insurance|rolex))"

保存文件并重新加载 Apache。在浏览器中打开 http://yourwebsite.com/form.php 并输入包含以下任何词的文本:pills、insurance、rolex。

您将看到一个 403 页面和一个日志条目,或者仅看到一个基于 SecRuleEngine 设置的日志条目。 SecRule 的语法是

SecRule VARIABLES OPERATOR [ACTIONS]

在这里,我们使用链式操作将变量 REQUEST_FILENAME 与 form.php、REQUEST_METHOD 与 POST 和 REQUEST_BODY 与正则表达式 (@rx) string (pills|insurance|rolex) 匹配. ?i: 不区分大小写匹配。成功匹配所有这三个规则后,ACTION 将拒绝并记录消息“检测到垃圾邮件”。 chain 操作模拟逻辑 AND 以匹配所有三个规则。

排除主机和目录

有时排除特定目录或域名是有意义的,如果它正在运行像 phpMyAdmin 这样的应用程序作为 modsecurity 并将阻止 SQL 查询。最好排除 WordPress 等 CMS 应用程序的管理后端。

要为完整的 VirtualHost 禁用 modsecurity,请放置以下内容

<IfModule security2_module>
    SecRuleEngine Off
</IfModule>

在 部分内。

对于特定目录:

<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>

延伸阅读

官方 modsecurity 文档 https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

提交人:Jesin A

©2015-2025 艾丽卡 support@alaica.com