为Apache 2配置ModSecurity 保护

发布于 2022-09-11  2,428 次阅读


前言

ModSecurity 是一个免费的开源 Web 应用程序,最初是一个 Apache 模块,后来发展成为一个成熟的 Web 应用程序防火墙。它的工作原理是根据预定义的规则集实时检查发送到 Web 服务器的请求,防止典型的 Web 应用程序攻击,如 XSS 和 SQL 注入。

本次的环境为Debian11 LNMAP

安装

安装 ModSecurity

直接使用包管理器安装

apt install libapache2-mod-security2 -y

启用 Apache 2 模块

a2enmod headers

后重启Apache即可

配置 ModSecurity

使用推荐配置

cp /etc/modsecurity/modsecurity.conf-recommended /etc/modsecurity/modsecurity.conf

编辑/etc/modsecurity/modsecurity.conf

将开头部分

# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
#SecRuleEngine DetectionOnly
SecRuleEngine On

SecRuleEngine值改为On

# PCRE Tuning
# We want to avoid a potential RegEx DoS condition
#
SecPcreMatchLimit 500000
SecPcreMatchLimitRecursion 500000

增大SecPcreMatchLimitSecPcreMatchLimitRecursion的值
此处我改为了300000

设置核心规则

先删除默认规则

rm -rf /usr/share/modsecurity-crs/*

安装核心规则,此处有两种选项

官方发布

打开https://coreruleset.org/installation/获取最新发布的下载地址

下载完成后解压将coreruleset-*.*.*/ 下的文件移动到/usr/share/modsecurity-crs

使用默认规则

mv /usr/share/modsecurity-crs/crs-setup.conf.example /usr/share/modsecurity-crs/crs-setup.conf
mv /usr/share/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /usr/share/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

Git安装

rm -rf /usr/share/modsecurity-crs
git clone https://github.com/coreruleset/coreruleset /usr/share/modsecurity-crs
mv /usr/share/modsecurity-crs/crs-setup.conf.example /usr/share/modsecurity-crs/crs-setup.conf
mv /usr/share/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf.example /usr/share/modsecurity-crs/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf

注:该安装方法误报概率较高

启用ModSecurity

编辑/etc/apache2/mods-available/security2.conf

添加

Include /usr/share/modsecurity-crs/crs-setup.conf
Include /usr/share/modsecurity-crs/rules/*.conf

文件配置完后大概应为:

<IfModule security2_module>
        # Default Debian dir for modsecurity's persistent data
        SecDataDir /var/cache/modsecurity
        Include /usr/share/modsecurity-crs/crs-setup.conf
        Include /usr/share/modsecurity-crs/rules/*.conf
        # Include all the *.conf files in /etc/modsecurity.
        # Keeping your local configuration in that directory
        # will allow for an easy upgrade of THIS file and
        # make your life easier
        IncludeOptional /etc/modsecurity/*.conf

        # Include OWASP ModSecurity CRS rules if installed
        IncludeOptional /usr/share/modsecurity-crs/*.load
</IfModule>

这种结构

编辑/etc/apache2/sites-enabled/000-default.confVirtualHost块内添加SecRuleEngine On

编辑后结构类似与

<VirtualHost *:80>
        # The ServerName directive sets the request scheme, hostname and port that
        # the server uses to identify itself. This is used when creating
        # redirection URLs. In the context of virtual hosts, the ServerName
        # specifies what hostname must appear in the request's Host: header to
        # match this virtual host. For the default virtual host (this file) this
        # value is not decisive as it is used as a last resort host regardless.
        # However, you must set it for any further virtual host explicitly.
        #ServerName www.example.com

        ServerAdmin webmaster@localhost
        DocumentRoot /var/www/html

        # Available loglevels: trace8, ..., trace1, debug, info, notice, warn,
        # error, crit, alert, emerg.
        # It is also possible to configure the loglevel for particular
        # modules, e.g.
        #LogLevel info ssl:warn

        ErrorLog ${APACHE_LOG_DIR}/error.log
        CustomLog ${APACHE_LOG_DIR}/access.log combined

        # For most configuration files from conf-available/, which are
        # enabled or disabled at a global level, it is possible to
        # include a line for only one particular virtual host. For example the
        # following line enables the CGI configuration for this host only
        # after it has been globally disabled with "a2disconf".
        #Include conf-available/serve-cgi-bin.conf
        SecRuleEngine On
</VirtualHost>

重启Apache

systemctl restart apache2

测试效果

访问http://IP(Domain)/index.php?exec=/bin/bash应返回403错误

例如你访问https://www.moec.top/index.php?exec=/bin/bash会得到403错误

性能差异

未启用:

This is ApacheBench, Version 2.3 <$Revision: 1901567 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.moec.top (be patient).....done


Server Software:        cloudflare
Server Hostname:        www.moec.top
Server Port:            443
SSL/TLS Protocol:       TLSv1.3,TLS_AES_256_GCM_SHA384,256,256
Server Temp Key:        X25519 253 bits
TLS Server Name:        www.moec.top

Document Path:          /
Document Length:        38982 bytes

Concurrency Level:      10
Time taken for tests:   21.226 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      3969644 bytes
HTML transferred:       3898200 bytes
Requests per second:    4.71 [#/sec] (mean)
Time per request:       2122.601 [ms] (mean)
Time per request:       212.260 [ms] (mean, across all concurrent requests)
Transfer rate:          182.63 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        4   10   9.7      8      81
Processing:   746 2000 488.4   1925    3806
Waiting:      742 1940 474.7   1867    3591
Total:        753 2010 488.4   1973    3821

Percentage of the requests served within a certain time (ms)
  50%   1973
  66%   2094
  75%   2250
  80%   2327
  90%   2666
  95%   3038
  98%   3328
  99%   3821
 100%   3821 (longest request)

启用:

root@rnldp:~# ab -n 100 -c 10 https://www.moec.top/
This is ApacheBench, Version 2.3 <$Revision: 1901567 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking www.moec.top (be patient).....done


Server Software:        cloudflare
Server Hostname:        www.moec.top
Server Port:            443
SSL/TLS Protocol:       TLSv1.3,TLS_AES_256_GCM_SHA384,256,256
Server Temp Key:        X25519 253 bits
TLS Server Name:        www.moec.top

Document Path:          /
Document Length:        38982 bytes

Concurrency Level:      10
Time taken for tests:   20.473 seconds
Complete requests:      100
Failed requests:        0
Total transferred:      3969568 bytes
HTML transferred:       3898200 bytes
Requests per second:    4.88 [#/sec] (mean)
Time per request:       2047.265 [ms] (mean)
Time per request:       204.726 [ms] (mean, across all concurrent requests)
Transfer rate:          189.35 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        4   12  15.1      9     139
Processing:   808 1922 397.2   1895    2907
Waiting:      592 1854 397.2   1793    2907
Total:        822 1934 398.7   1907    2915

Percentage of the requests served within a certain time (ms)
  50%   1907
  66%   2090
  75%   2218
  80%   2329
  90%   2482
  95%   2576
  98%   2816
  99%   2915
 100%   2915 (longest request)

参考:

https://coreruleset.org/

https://bobcares.com/blog/modsecurity-pcre-limits-exceeded/

https://serverfault.com/questions/367481/mod-security-pcre-limits-exceeded

https://www.linode.com/docs/guides/securing-apache2-with-modsecurity/