首页 / 帮助文档 / CentOS安全中配置mod_security与规则定制

CentOS安全中配置mod_security与规则定制

在CentOS服务器上配置mod_security并进行规则定制,核心就是三步:安装模块、加载OWASP核心规则集、根据自身业务场景调整规则。这是目前Apache/Nginx环境下最成熟的WAF(Web应用防火墙)方案之一,能有效拦截SQL注入、XSS跨站脚本、文件包含等常见攻击。很多运维人员装完就不管了,默认规则一跑,要么误杀正常请求,要么放过高级攻击,真正的价值在于"定制"二字。

mod_security本质上是一个开源的Web应用防火墙引擎,它以模块形式嵌入Apache(也支持Nginx),通过规则匹配来实时检测和阻断恶意HTTP请求。在CentOS 7/8/9上部署它并不复杂,但要让它真正发挥作用,你必须理解规则的工作原理和调优逻辑。下面我会从安装、基础配置、规则定制、性能优化四个维度,把这件事讲透。

一、CentOS上安装mod_security的具体操作

首先确认你的Apache版本,因为mod_security有v2和v3两个大版本,目前主流推荐v3。如果你用的是CentOS 7,系统自带的Apache是2.4.x,可以直接通过EPEL源或源码编译安装。CentOS 8/9则需要启用PowerTools或CodeReady源。

最简单的方式是通过yum安装(如果源里有):

yum install mod_security -y

如果源里没有或者版本太旧,就需要从源码编译。先安装依赖:

yum install gcc gcc-c++ make httpd-devel pcre-devel libxml2-devel -y

然后下载mod_security v3源码:

wget https://github.com/SpiderLabs/ModSecurity/archive/v3.0.12.tar.gz
tar -xzf v3.0.12.tar.gz
cd ModSecurity-3.0.12
git submodule init
git submodule update
./build.sh
./configure
make
make install

编译完成后,需要在Apache配置中加载模块。找到httpd.conf或在conf.d目录下新建一个modsecurity.conf:

LoadModule security3_module modules/mod_security3.so

重启Apache验证:

systemctl restart httpd
httpd -M | grep security

看到security3_module就说明加载成功了。

二、基础配置文件的核心参数解读

mod_security的主配置文件通常放在/etc/modsecurity/modsecurity.conf,CentOS上默认路径可能是/etc/httpd/conf.d/modsecurity.conf。这个文件里有几个关键指令必须理解。

第一个是SecRuleEngine,它控制mod_security的运行模式:

SecRuleEngine On

On是拦截模式,检测到攻击直接阻断;DetectionOnly是只记录不阻断,适合初期调试;Off是关闭。强烈建议先用DetectionOnly跑一周,观察误报情况,再切到On。

第二个是SecRequestBodyAccess,控制是否检查请求体:

SecRequestBodyAccess On

如果你的网站有文件上传、表单提交,这个必须开,否则POST请求体里的恶意代码检测不到。

第三个是SecResponseBodyAccess,控制是否检查响应体:

SecResponseBodyAccess Off

一般建议关掉,因为检查响应体会严重影响性能,而且大多数场景下没必要。

第四个是SecAuditLog,指定审计日志路径:

SecAuditLog /var/log/httpd/modsec_audit.log

所有被检测到的请求都会记录在这里,是排查误报和分析攻击的核心依据。

第五个是SecDataDir,指定临时数据目录:

SecDataDir /var/lib/modsecurity

这个目录需要提前创建并设置正确权限:

mkdir -p /var/lib/modsecurity
chown apache:apache /var/lib/modsecurity
三、加载OWASP核心规则集(CRS)并理解其结构

mod_security本身只是引擎,真正干活的是规则。OWASP(开放Web应用安全项目)维护的Core Rule Set(CRS)是目前最权威、最全面的开源规则集,覆盖了OWASP Top 10的所有攻击类型。

下载CRS:

cd /etc/modsecurity
git clone https://github.com/coreruleset/coreruleset.git
cd coreruleset
mv crs-setup.conf.example crs-setup.conf

然后在modsecurity.conf中引入:

Include /etc/modsecurity/coreruleset/crs-setup.conf
Include /etc/modsecurity/coreruleset/rules/*.conf

CRS的规则文件按功能分块,比如REQUEST-901-INITIALIZATION.conf是初始化规则,REQUEST-920-PROTOCOL-ENFORCEMENT.conf是协议强制规则,REQUEST-941-APPLICATION-ATTACK-XSS.conf是XSS防护,REQUEST-942-APPLICATION-ATTACK-SQLI.conf是SQL注入防护。每一块都有独立的文件,方便你单独启用或禁用。

CRS默认使用"偏执级别"(Paranoia Level),从PL1到PL4,级别越高规则越严格,误报也越多。生产环境建议从PL1开始:

SecAction \
 "id:900000,\
  phase:1,\
  nolog,\
  pass,\
  t:none,\
  setvar:'tx.paranoia_level=1'"

这个设置放在crs-setup.conf里就行。PL1能拦截绝大多数攻击,同时误报率可控。如果你的业务比较特殊,比如大量使用富文本编辑器,可以先从PL1逐步往上调,每次调一级观察一周。

四、根据业务场景进行规则定制的实战方法

默认规则再好,也不可能100%适配你的业务。规则定制才是mod_security真正的价值所在。定制主要分三个方向:放行特定请求、加强特定防护、编写自定义规则。

第一,放行特定URL或参数。比如你的网站有一个富文本编辑器接口,正常提交会触发XSS规则误报。你可以在modsecurity.conf末尾添加:

SecRule REQUEST_URI "@beginsWith /admin/editor/submit" \
    "id:1000001,\
    phase:1,\
    pass,\
    nolog,\
    ctl:ruleRemoveById=941100"

这条规则的意思是:当请求URI以/admin/editor/submit开头时,跳过ID为941100的XSS规则,并且不记录日志。ctl:ruleRemoveById是非常实用的指令,可以精确移除某条规则对特定请求的影响。

第二,针对特定攻击加强防护。比如你的网站是电商平台,经常遭受CC攻击(高频请求),可以添加限速规则:

SecAction \
    "id:1000002,\
    phase:1,\
    pass,\
    nolog,\
    setvar:'ip.cc_counter=+1'"
SecRule IP:CC_COUNTER "@gt 100" \
    "id:1000003,\
    phase:1,\
    deny,\
    status:429,\
    log,\
    msg:'Rate limit exceeded'"

这个简单的计数器规则,当同一个IP在短时间内请求超过100次就直接返回429状态码。当然这只是示例,生产环境需要配合更完善的IP追踪和时间窗口逻辑。

第三,编写自定义规则应对业务特有风险。比如你的网站允许用户上传文件,但只允许图片格式,可以写:

SecRule REQUEST_FILENAME "@endsWith .php" \
    "id:1000004,\
    phase:2,\
    deny,\
    status:403,\
    log,\
    msg:'PHP file upload blocked'"

这条规则在请求体阶段检查文件名后缀,发现.php直接拦截。注意phase的选择很重要:phase:1是请求头阶段,phase:2是请求体阶段,phase:3是响应头阶段,phase:4是响应体阶段。文件上传检查必须放在phase:2。

还有一个容易被忽视的点:规则的执行顺序。mod_security是按规则ID从小到大依次执行的,所以自定义规则的ID建议从1000000以上开始,避免和CRS的规则ID冲突。同时,使用ctl:ruleRemoveTargetById可以更精细地控制规则作用范围。

五、性能优化与误报处理的关键技巧

mod_security是有性能开销的,尤其是开启了请求体检查之后。在高并发场景下,如果配置不当,可能导致响应延迟增加30%-50%。几个优化建议:

首先,限制请求体大小。如果你的业务不需要大文件上传,把上限设小:

SecRequestBodyLimit 1048576

这是1MB的限制,超过的请求直接拒绝,既省资源又防大文件攻击。

其次,合理使用SecRuleEngine。在调试阶段用DetectionOnly,稳定后切On。不要长期开着DetectionOnly,因为它会让你产生"一切正常"的错觉。

第三,定期分析审计日志。用以下命令快速统计被拦截最多的规则:

grep -oP 'id "\K[0-9]+' /var/log/httpd/modsec_audit.log | sort | uniq -c | sort -rn | head -20

排在前面的规则ID就是误报重灾区,针对性地做放行处理。不要一上来就大面积关闭规则,那等于把WAF拆了。

第四,考虑使用SecRuleUpdateTargetByTag或SecRuleUpdateTargetById来微调规则的检测目标,而不是直接禁用整条规则。比如CRS的SQL注入规则检测了所有参数,但你的某个接口参数确实需要包含SQL关键字(比如搜索功能),可以只对那个参数关闭检测:

SecRuleUpdateTargetById 942100 "!ARGS:search_keyword"

感叹号表示排除,这样只有search_keyword这个参数不受942100规则约束,其他参数仍然受保护。

六、CentOS不同版本的注意事项

CentOS 7自带Apache 2.4.6,mod_security v2和v3都能用,但v2已经停止维护,强烈建议用v3。CentOS 8/9的Apache版本较新,编译v3时可能需要额外安装libcurl-devel和yajl-devel。

另外,CentOS 8/9默认使用dnf而非yum,包管理命令需要替换。如果你用的是Nginx而不是Apache,mod_security同样支持,但需要通过libmodsecurity库来加载,配置方式有所不同,不过规则文件是通用的。

还有一个容易踩的坑:SELinux。CentOS默认开启SELinux,mod_security的日志目录和数据目录如果权限不对,会被SELinux拦截。解决方法要么调整SELinux上下文,要么临时设为permissive模式测试:

setsebool -P httpd_modsecurity on
chcon -R -t httpd_sys_rw_content_t /var/log/httpd/modsec_audit.log

最后提醒一点,mod_security不是银弹。它能挡住大部分自动化攻击和已知漏洞利用,但对于精心构造的高级持续性威胁(APT)和零日漏洞,它的防护能力有限。把它当作纵深防御体系中的一层,配合系统加固、最小权限原则、定期更新补丁,才是真正的安全策略。

总结一下:CentOS上部署mod_security,安装只是起点,加载CRS是基础,规则定制才是灵魂。从PL1开始跑,逐步根据审计日志调优,针对业务特点写自定义规则,同时注意性能和SELinux的坑。这套流程走下来,你的Web服务器就有了一层相当靠谱的应用层防护。