安装 Apache WAF mod_security

希望选择适合的环境

CentOS 6 或 7

# rpm -q mod_security mod_security_crs
mod_security-2.7.3-5.el6.x86_64
mod_security_crs-2.2.6-3.el6.noarch

# rpm -q mod_security mod_security_crs
mod_security-2.9.2-1.el7.x86_64
mod_security_crs-2.2.9-1.el7.noarch

首先,包括引入政策等。

    • デフォルトでインストールされるルールでは、誤検知が発生するので、最小限のルールのみ有効にします。

 

    • 現状、本番環境での初期導入時はSQLインジェクションとクロスサイトスクリプティングに関するルールのみ残し、他は無効にします。

 

    • 最初は、検出オンリーモードで様子をみるのが良さそうです。

 

    • 開発環境では全てのルールを有効にしてみるなど、いろいろ試してみてください。問題ないと確認できれば、本番環境で随時ルールを有効にしていきます。

 

    • デフォルトではログ出力が多いので、ディスク容量に余裕のない環境では設定を調整してください。

 

    本番環境での誤検知発生にそなえて、特定のURLでルールを無効にする方法を確認してください。

安装RPM软件包

从epel仓库安装rpm软件包。

# yum -y install mod_security mod_security_crs

mod_security是Apache的模块,mod_security_crs是WAF的规则。

在初始引导期间,必须在调整设置后重新启动 Apache 以使更改生效。

# service httpd restart

在更改设置时,将通过重新加载来反映。

# service httpd reload

只保留SQL注入和跨站脚本攻击的规则,禁用其他规则。

建议事先备份,WAF规则默认加载在/etc/httpd/modsecurity.d/activated_rule目录下。

# cd /etc/httpd/modsecurity.d
# cp -rp activated_rule activated_rule.orig
# cd activated_rule
# ls -l
total 88
lrwxrwxrwx 1 root root 64 Jul  3 16:21 modsecurity_35_bad_robots.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_35_bad_robots.data
lrwxrwxrwx 1 root root 62 Jul  3 16:21 modsecurity_35_scanners.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_35_scanners.data
lrwxrwxrwx 1 root root 69 Jul  3 16:21 modsecurity_40_generic_attacks.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_40_generic_attacks.data
lrwxrwxrwx 1 root root 75 Jul  3 16:21 modsecurity_41_sql_injection_attacks.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_41_sql_injection_attacks.data
lrwxrwxrwx 1 root root 62 Jul  3 16:21 modsecurity_50_outbound.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_50_outbound.data
lrwxrwxrwx 1 root root 70 Jul  3 16:21 modsecurity_50_outbound_malware.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_50_outbound_malware.data
lrwxrwxrwx 1 root root 77 Jul  3 16:21 modsecurity_crs_20_protocol_violations.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_20_protocol_violations.conf
lrwxrwxrwx 1 root root 76 Jul  3 16:21 modsecurity_crs_21_protocol_anomalies.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_21_protocol_anomalies.conf
lrwxrwxrwx 1 root root 72 Jul  3 16:21 modsecurity_crs_23_request_limits.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_23_request_limits.conf
lrwxrwxrwx 1 root root 69 Jul  3 16:21 modsecurity_crs_30_http_policy.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_30_http_policy.conf
lrwxrwxrwx 1 root root 68 Jul  3 16:21 modsecurity_crs_35_bad_robots.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_35_bad_robots.conf
lrwxrwxrwx 1 root root 73 Jul  3 16:21 modsecurity_crs_40_generic_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_40_generic_attacks.conf
lrwxrwxrwx 1 root root 79 Jul  3 16:21 modsecurity_crs_41_sql_injection_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_41_sql_injection_attacks.conf
lrwxrwxrwx 1 root root 69 Jul  3 16:21 modsecurity_crs_41_xss_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_41_xss_attacks.conf
lrwxrwxrwx 1 root root 72 Jul  3 16:21 modsecurity_crs_42_tight_security.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_42_tight_security.conf
lrwxrwxrwx 1 root root 65 Jul  3 16:21 modsecurity_crs_45_trojans.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_45_trojans.conf
lrwxrwxrwx 1 root root 75 Jul  3 16:21 modsecurity_crs_47_common_exceptions.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_47_common_exceptions.conf
lrwxrwxrwx 1 root root 82 Jul  3 16:21 modsecurity_crs_48_local_exceptions.conf.example -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_48_local_exceptions.conf.example
lrwxrwxrwx 1 root root 74 Jul  3 16:21 modsecurity_crs_49_inbound_blocking.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_49_inbound_blocking.conf
lrwxrwxrwx 1 root root 66 Jul  3 16:21 modsecurity_crs_50_outbound.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_50_outbound.conf
lrwxrwxrwx 1 root root 75 Jul  3 16:21 modsecurity_crs_59_outbound_blocking.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_59_outbound_blocking.conf
lrwxrwxrwx 1 root root 69 Jul  3 16:21 modsecurity_crs_60_correlation.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_60_correlation.conf

扩展名 .data 包含了用于参考的WAF规则等常量的定义。而 .conf 则是WAF规则的定义。

除了SQL注入modsecurity_crs_41_sql_injection_attacks.conf和跨站脚本modsecurity_crs_41_xss_attacks.conf之外,禁用其他conf文件。
如果仅仅删除符号链接,那么在进行yum更新时它们会再次变为有效,因此将其替换为同名的空文件。

# find . -type l -name '*_crs_*' | grep -Ev 'sql|xss' | xargs -I% echo rm % \; touch % | bash
# ls -l
total 48
lrwxrwxrwx 1 root root  64 Jul  3 19:56 modsecurity_35_bad_robots.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_35_bad_robots.data
lrwxrwxrwx 1 root root  62 Jul  3 19:56 modsecurity_35_scanners.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_35_scanners.data
lrwxrwxrwx 1 root root  69 Jul  3 19:56 modsecurity_40_generic_attacks.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_40_generic_attacks.data
lrwxrwxrwx 1 root root  75 Jul  3 19:56 modsecurity_41_sql_injection_attacks.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_41_sql_injection_attacks.data
lrwxrwxrwx 1 root root  62 Jul  3 19:56 modsecurity_50_outbound.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_50_outbound.data
lrwxrwxrwx 1 root root  70 Jul  3 19:56 modsecurity_50_outbound_malware.data -> /usr/lib/modsecurity.d/base_rules/modsecurity_50_outbound_malware.data
-rw-r--r-- 1 root root   0 Jul  3 19:56 modsecurity_crs_20_protocol_violations.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_21_protocol_anomalies.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_23_request_limits.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_30_http_policy.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_35_bad_robots.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_40_generic_attacks.conf
lrwxrwxrwx 1 root root  79 Jul  3 19:56 modsecurity_crs_41_sql_injection_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_41_sql_injection_attacks.conf
lrwxrwxrwx 1 root root  69 Jul  3 19:56 modsecurity_crs_41_xss_attacks.conf -> /usr/lib/modsecurity.d/base_rules/modsecurity_crs_41_xss_attacks.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_42_tight_security.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_45_trojans.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_47_common_exceptions.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_48_local_exceptions.conf.example
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_49_inbound_blocking.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_50_outbound.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_59_outbound_blocking.conf
-rw-r--r-- 1 root root   0 Jul  3 19:54 modsecurity_crs_60_correlation.conf

请恢复符号链接以使已经禁用的规则生效。

# ln -sf /usr/lib/modsecurity.d/base_rules/modsecurity_crs_30_http_policy.conf .

可以从备份中恢复。

# cp -P ../activated_rules.orig/modsecurity_crs_30_http_policy.conf .

要将默认设置恢复到 activated_rules 的备份。

# cd /etc/httpd/modsecurity.d
# mv activated_rule activated_rule.bk && mv activated_rule.orig activated_rule

如果您错误地覆盖或删除了文件等,想要回到默认状态,可以先删除已覆盖的文件,然后重新安装 mod_security_crs 包。

# rm /usr/lib/modsecurity.d/base_rules/*.conf
# yum reinstall mod_security_crs

日志输出的调整

默认情况下,错误日志会输出到 Apache 的 error_log 和 /var/log/httpd/modsec_audit.log。

在 modsec_audit.log 日志文件中,除了与 WAF 无关的 404 错误外,还会输出4xx、5xx 错误的详细信息。因此,在磁盘空间有限的环境中,日志很容易膨胀并且存在危险。

在只有错误日志的情况下可以判断是否被检测到,所以在担心的环境中,通常应将输出到modsec_audit.log的功能关闭,并在需要的时候打开。

    SecAuditEngine Off

确认动作

我将尝试给您提供一种汉语的原生表达方式:
通过在GET参数中添加?select+union来进行测试,以确认检测到SQL注入攻击后是否会出现403 Forbidden的错误。
例如:https://example.com/hoge/?union+select

以下是错误日志的输出示例。

[Thu Jul 05 13:57:50 2018] [error] [client 192.168.0.100] ModSecurity: Access denied with code 403 (phase 2). Operator GE matched 3 at TX:sqli_select_statement_count. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"] [line "108"] [id "981317"] [rev "2"] [msg "SQL SELECT Statement Anomaly Detection Alert"] [data "Matched Data: Connection found within TX:sqli_select_statement_count: 3"] [ver "OWASP_CRS/2.2.6"] [maturity "8"] [accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"] [tag "WASCTC/WASC-19"] [tag "OWASP_TOP_10/A1"] [tag "OWASP_AppSensor/CIE1"] [tag "PCI/6.5.2"] [hostname "example.com"] [uri "/hoge/"] [unique_id "Wz2lTsCoAa4AAEuRGe0AAAAA"]

可以通过grep字符串“ModSecurity: Access denied with code”来调查是否检测到了WAF。

# grep 'ModSecurity: Access denied with code ' /var/log/httpd/ssl_error_log

檢測資訊以 [名稱 “數值”] 的形式輸出,請適當插入換行符號。

# grep 'ModSecurity: Access denied with code ' /var/log/httpd/ssl_error_log | tail -1 | sed 's/ \[/\n[/g' 
[Thu Jul 05 13:57:50 2018]
[error]
[client 192.168.0.100] ModSecurity: Access denied with code 403 (phase 2). Operator GE matched 3 at TX:sqli_select_statement_count.
[file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_sql_injection_attacks.conf"]
[line "108"]
[id "981317"]
[rev "2"]
[msg "SQL SELECT Statement Anomaly Detection Alert"]
[data "Matched Data: Connection found within TX:sqli_select_statement_count: 3"]
[ver "OWASP_CRS/2.2.6"]
[maturity "8"]
[accuracy "8"]
[tag "OWASP_CRS/WEB_ATTACK/SQL_INJECTION"]
[tag "WASCTC/WASC-19"]
[tag "OWASP_TOP_10/A1"]
[tag "OWASP_AppSensor/CIE1"]
[tag "PCI/6.5.2"]
[hostname "example.com"]
[uri "/hoge/"]
[unique_id "Wz2lTsCoAa4AAEuRGe0AAAAA"]

重要的是[id “981317”],在禁用此规则时,应指定给SecRuleRemoveById。

    • id: 検知ルールID

 

    • client: 検知されたクライアントIP

 

    • file,line: 検知ルール定義場所

 

    • msg: 検知ルールの概要

 

    • data: 検知された問題のデータ

 

    hostname,uri: 検知されたURL

使用跨站脚本攻击,在适当的文本表单中输入javascript:alert(document.cookie),并提交以确认是否出现403 Forbidden错误。下面是错误日志的示例输出。

跨站脚本攻击是指在适当的文本表单中输入javascript:alert(document.cookie),然后提交以验证是否会出现403 Forbidden错误。以下是错误日志的示例输出。

[Thu Jul 05 14:55:33 2018] [error] [client 192.168.0.100] ModSecurity: Access denied with code 403 (phase 2). Pattern match "\\\\bdocument\\\\b\\\\s*\\\\.\\\\s*\\\\bcookie\\\\b" at ARGS:login_email. [file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_xss_attacks.conf"] [line "107"] [id "958001"] [rev "2"] [msg "Cross-site Scripting (XSS) Attack"] [data "Matched Data: document.cookie found within ARGS:login_email: javascript:alert(document.cookie)"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.6"] [maturity "8"] [accuracy "8"] [tag "OWASP_CRS/WEB_ATTACK/XSS"] [tag "WASCTC/WASC-8"] [tag "WASCTC/WASC-22"] [tag "OWASP_TOP_10/A2"] [tag "OWASP_AppSensor/IE1"] [tag "PCI/6.5.1"] [hostname "example.com"] [uri "/frontparts/login_check.php"] [unique_id "Wz2y1cCoAa4AAEuTGnsAAAAC"]

适当插入换行代码。

# grep 'ModSecurity: Access denied with code ' /var/log/httpd/ssl_error_log | tail -1 | sed 's/ \[/\n[/g'
[Thu Jul 05 14:55:33 2018]
[error]
[client 192.168.0.100] ModSecurity: Access denied with code 403 (phase 2). Pattern match "\\\\bdocument\\\\b\\\\s*\\\\.\\\\s*\\\\bcookie\\\\b" at ARGS:login_email.
[file "/etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_41_xss_attacks.conf"]
[line "107"]
[id "958001"]
[rev "2"]
[msg "Cross-site Scripting (XSS) Attack"]
[data "Matched Data: document.cookie found within ARGS:login_email: javascript:alert(document.cookie)"]
[severity "CRITICAL"]
[ver "OWASP_CRS/2.2.6"]
[maturity "8"]
[accuracy "8"]
[tag "OWASP_CRS/WEB_ATTACK/XSS"]
[tag "WASCTC/WASC-8"]
[tag "WASCTC/WASC-22"]
[tag "OWASP_TOP_10/A2"]
[tag "OWASP_AppSensor/IE1"]
[tag "PCI/6.5.1"]
[hostname "example.com"]
[uri "/frontparts/login_check.php"]
[unique_id "Wz2y1cCoAa4AAEuTGnsAAAAC"]

从POST参数ARGS: login_email中可以检测到输入的值javascript: alert(document.cookie)。

鉴于句子过长,以下是要点概括:

# tail -1 /var/log/httpd/ssl_error_log | perl -nle '/^(?:.*? ){3}(.*?) .*id "(.*?)".*msg "(.*?)"/ && print "$1 $2 $3"'

禁用WAF规则

如果错误地检测到用户的合法请求导致了虚假阳性的发生,我们会立刻禁用WAF规则来进行应对。
如果检测结果正确且是应用程序方面的问题,我们会修正后重新启用规则。

如果WAF检测到了,通常会默认返回403 Forbidden。由于基本认证和IP限制也会引发此问题,因此需要通过日志确认是否是WAF引起的。

定制规则文件

如果完全关闭规则,则指定SecRuleEngine;如果逐个关闭规则,则指定SecRuleRemoveById。可以在除.htaccess之外的任何上下文中进行说明。如果要在除虚拟主机之外的上下文中进行说明,请使用下面的z_customrules.conf。SecRuleRemoveById必须在SecRule之后进行评估,因此在此文件中进行说明是安全的。

请创建一个新文件并写入下面的内容,用于自定义原则和设置。
– /etc/httpd/modsecurity.d/activated_rules/modsecurity_crs_15_customrules.conf
– /etc/httpd/modsecurity.d/activated_rules/z_customrules.conf

modsecurity_crs_15_customrules.conf 在常数初始化之后和规则定义之前被加载。需要在SecRule之前编写SecDefaultAction和优先于默认规则的规则等。z_customrules.conf 在规则定义之后被加载。

只需检测模式

检测但不阻断,仅记录日志。

    SecRuleEngine DetectionOnly

将WAF功能完全关闭。

要完全关闭功能,请按照以下方式进行设置。

    SecRuleEngine Off

在指定的URL上禁用WAF功能。

在管理界面下,禁用WAF的设置如下所示。

<Directory /var/www/html/admin>
    SecRuleEngine Off
</Directory>

如果URL不支持文件,那么将使用Location。

<Location /admin>
    SecRuleEngine Off
</Location>

如果要单独禁用规则,请使用SecRuleRemoveById来描述。可以使用空格分隔的参数来指定多个规则ID。可以多次使用SecRuleRemoveById,没有问题。

<Directory /var/www/html/admin>
    SecRuleRemoveById 981317 950001 959073 981255 981245
    SecRuleRemoveById 950901 960024 981173 973300
</Directory>

在虚拟主机的情况下禁用WAF功能。

在虚拟主机环境中,描述了在特定的URL上禁用WAF功能的设置。

<VirtualHost *:443>
    <IfModule mod_security2.c>
        SecRuleEngine Off
    </IfModule>
</VirtualHost>

如果在mod_security.conf的非管理上下文中进行描述,则应指定IfModule以确保模块上传不会引发错误。

调整帖子尺寸

根据php的post_max_size和upload_max_filesize,可能需要调整WAF的SecRequestBodyLimit和SecRequestBodyNoFilesLimit。

参考资料

本地维基百科
本地参考手册v2.x
本地日志数据格式

广告
将在 10 秒后关闭
bannerAds