日期:2018-06-21  浏览次数:2444 次

一、介绍

 

引言

    ModSecurity是一个Web应用防火墙(WAF)。当前已经有超过70%的攻击发生在网络应用层,各级组织急需要能够保证他们的系统安全性的帮助。WAF系统的部署,可以为web应用增加一个外部安全层来检测或防止攻击。针对一系列的攻击,ModSecurity为web应用提供了强大的保护,并对HTTP流量进行监测和实时分析,这些都只是很少或是根本没有影响系统的基础设施。

 

HTTP流量记录

    web服务器已有的日志功能已经足够进行访问请求分析,但是就web的应用分析还有些不足,特别是大多情况下没办法记录下请求体。你的对手很清楚这一点,所以很多时候的攻击是通过POST请求产生,并导致您的系统失明。ModSecurity充分的获取HTTP交互中的所以内容,并记录完整的请求和响应。其日志功能可以允许您更细致的做出判断究竟什么是登录的时候,并确保相关的数据都被记录下来。一些请求和响应中的某些关键字段可能包含敏感数据,ModSecurity可以被配置成在记录这些审计日志前隐藏它。

 

实时监控和攻击检测

    除了提供记录日志功能外,ModSecurity还能实时的监控HTTP的流量以检测攻击。在某些时候,ModSecurity做为一个WEB入侵检测工具,可以让你对发生在WEB系统上的一些可疑事件做出响应。

 

攻击防御和及时修补

    ModSecurity能够立即针对你的WEB应用系统进行攻击防御,有三种通用的方法:

    1、消极(negative)安全模型:消极安全模型监控那些异常的、不常用的和通用的WEB攻击类请求。它统计每个请求的有关IP地址、应该连接、和用户帐户的异常分数,当出现较高的异常分数时,会记录日志并完全的阻止访问。

    2、积极安全模开型:部署积极安全模型后,只有那些明确的请求被允许通过,其它的一律禁止。这个模式要求你对需要保护的WEB应用要非常的了解。因此积极安全模式最好是用于那种大量访问却很少更新的系统,这样才能使这种模型的维护工作量降到最低。

    3、已知漏洞攻击:其规则语言使ModSecurity成为一个理想的外部修补工具,外部修补(有时是指虚拟修补)可以减少机会之窗。一些组织修补这些应用的漏洞通常需要几周的时间,使用ModSecurity,应用系统可以从外部修补,根本不用改应用的源码(甚至时不用去管它),可以保证你的系统安全直到有一个合适的补丁来应用到系统中。

 

灵活的规则引擎

    灵活的规则引擎是ModSecurity的核心,其实现了ModSecurity的规则语言,这是一个专用的程序语言设计的用于处理HTTP的传输数据。ModSecurity规则语言被设计的简单易用,非常的灵活:通用的操作是简单的,而复杂的操作也是可以实现的。经过认证的ModSecurity规则,放在ModSecurity中,包含了一整套规则,它实现了通用目的强化、协议正规化和对一些通用web应用安全问题的检测。大量评论认为,这些规则可以用于学习研究使用。

 

嵌入式模式部署

    ModSecurity是一个可嵌入式的WEB应用防火墙,意思就是它可以做为以apache为基础的已经提供WEB服务的WEB服务器的一部分。这样的部署译意风一些特殊的优势:

    1、不改变已有的网络结构。只需要花几分钟就可以为你的WEB服务器添加ModSecurity,而且由于它默认被设计为完全的被动方式,你可以自由的逐步部署并且只使用你需要的特性。同样也可以根据你的需要轻松的删除或停用它。

    2、不存在单点故障。与网络设备部署方式不同,你不会给你的系统带来新的故障点。

    3、绝对支持负载均衡。因为它以嵌入方式运行在WEB服务器上,ModSecurity会自动的利用附加的负载均衡特性。你不需要考虑负载均衡,除非你的系统本来就需要它。

    4、极少开销。因为它在WEB服务器进程内工作,不会带来网络间接通信的负载,而且只进行最小的分析和数据交换开销。

    5、加密或压缩内容没问题。许多IDS系统分析SSL流量的时候很困难,但对于ModSecurity没有麻烦,因为它工作于已解密和解压的数据环节。

 

基于网络的部署

在基于apache的反向代理模式上ModSecurity同样能工作的很好,我们很多客户选择这样做。在这种情形下,装了ModSecurity的可以保护任一一种WEB服务器(即使它不是apache的)。

 

可移植性

众所周知,ModSecurity可以很好的工作在众多操作系统上,我们的用户已经将它成功运行在Linux, Windows, Solaris, FreeBSD, OpenBSD, NetBSD, AIX, Mac OS X, 和HP-UX等系统上。

 

许可

ModSecurity有两种许可方式。用户可以选择在GNU许可第二版(本发布中包含这个许可文本)下免费的使用这个软件产品。还有一系列的商业许可可供选择,同时会有一些商业支持合同。有关更详细的商业许可信息请联系Breach Security。

 


   注意

     ModSecurity, mod_security, ModSecurity Pro, 和 ModSecurity Core Rules等都是Breach Security, Inc.的商标或注册商标。

 

 

二、ModSecurity Core Rules

概述

    ModSecurity是一个WEB应用防火墙引擎,自身所提供的保护非常少。为了变得更有用些,ModSecurity必须启用规则配置。为了让用户能够充分利用ModSecurity离开方块,Breach Security, Inc.为ModSecurity 2.x提供了一套免费的认证规则集。和入侵检测及防御系统不一样,它们依赖于具体的签名过的已知漏洞,而这一核心规则却是为从网络应用中发现的不知名的漏洞提供一般的保护,通常这些漏洞大多数情况下都是自定义编码的。这一核心规则有了大量的评论,从而使得这些能够被用来做ModSecurity的部署向导。最新的核心规则可能通过ModeSecurity的站点找到-http://www.modsecurity.org/projects/rules。

 

核心规则内容

    为了提供一般WEB应用保护,核心规则使用以下技术:

  • HTTP保护 - HTTP协议正规划检测,并启用本地有效策略
  • 一般WEB攻击保护 - 检测一般WEB应用的安全攻击
  • 自动检测 - 检测机器人、爬虫、扫描器和其他的表面恶意行动
  • 木马检测 - 检测木马程序进入
  • 过失隐藏 - 伪装服务器发出错误消息

三、安装

安装

ModSecurity安装过程包含以下几步:

1、ModSecurity 2.x工作于Apache 2.0.x或者更高版本

2、确认您已经安装了mod_unique_id。

   mod_unique_id是apache的httpd中的一个包

3、服务器中还没有libxml2的话,请安装它的最新版.

   http://xmlsoft.org/downloads.html

4、如果服务中还没有安装Lua,而且你将需要使用的话,请安装5.1.x分支的最新版

   http://www.lua.org/download.html

   注意ModSecurity需要的是动态库,而采用源代码编译时默认得不到这些,所以最好采用二进制发布版本。

5、停止apache的httpd服务

6、解开ModSecurity安装包

7、Unix(或者类Unix)操作系统和Windows上进行不同的构建

   Unix

a、运行configure脚本生成Makefile文件,通常不需要设置选项

./configure

更多的定制使用配置选项(使用./configure --help可以得到完整列表),但通常你只需要使用--with-apxs选项指定apache的httpd安装时的apxs的位置即可。

./configure --with-apxs=/path/to/httpd-2.x.y/bin/apxs

b、编译:make

c、可选的测试:make test

注意:这一步还是带有一点点试验性质,如果发现问题,请把构建过程中的所有输出发送到支持列表,大部分常见问题是找不到所需要的头和库文件。

d、可选构建ModSecurity的日志收集器:make mlogc

e、可选安装mlogc:查检发布版本包含在apache2/mlogc-src目录下的INSTALL文件

f、安装ModSecurity模块:make install

   Windows(MS VC++ 8)

a、编辑Makefile.win文件,配置apache主目录和二进制目录

b、编译:nmake -f Makefile.win

c、安装ModSecurity模块:nmake -f Makefile.win install

d、拷贝libxml2.dll和lua5.1.dll到apache的二进制目录,当然也可以象下面的操作那样使用LoadFile命令加载那些库文件。

8、编辑apache httpd的主配置文件(通常是httpd.conf)

   On UNIX(在Windows上,如果你没有按上述规定拷贝DLL文件话也可以)上你必须在ModSecurity之前加载libxml2和lua5.1,参考如下操作:

LoadFile /usr/lib/libxml2.so

LoadFile /usr/lib/liblua5.1.so

 

   按如下加载ModSecurity

LoadModule security2_modules modules/mod_security2.so

 

9、配置ModSecurity

10、启动apache httpd

11、到目前为止,你应该已经装好ModSecurity 2.x并且运行它了。

 


注意:

    如果你是自己编译的apache,那你或许经历了在PCRE上编译ModSecurity的问题,这是因为apache带上了PCRE,但通常PCRE的库文件又是由系统提供的,我希望绝大多数的供应商打包apache发布版本时配置使用外部PCRE的库文件(所以这不应成为问题)
    您想避免使用apache捆绑的PCRE库和ModSecurity使用的是系统提供的库,很简单的方法就是重新编译apach,并使用系统提供的PCRE库(或者你可以下载个最新版本的PCRE编译一下),你也可以在编译的时候使用--with-pcre开关。如果你不能重新编译apache,那么为了获得ModSecurity的编译成功,你还是需要获得捆绑的PCRE头文件(这可以在apache的代码中找到)并修改INCLUDE路径(在上述第7步中做)来指向它(通过ModSecurity的--with-pcre配置选项)。
    你注意,如果你的apache使用的是外部PCRE,那你可以在编译ModSecurity时使用WITH_PCRE_STUDY定义,这将给你的服务器处理正则表达式时有一个轻微的性能提高。

 

四、配置指令(一)

 

以下章节列出ModSecurity指令的纲要,大部分的ModSecurity指令可以用于Apache带有范围的指令中,如VirtualHost, Location, LocationMatch, Directory等。当然也还有其他的,只能在主配置文件中使用一次。这些信息在下述范围章节中指定,下述的版本指令章节中给出第一个版本可用给定的指令。

 

    这些规则除了核心规则文件之外 ,应当做为一个独立的于httpd.conf之外的配置文件,通过apache的include指定包含在其中。如此可以方便更新或迁移规则,如果你要创建自己的规则,作为核心规则使用,你应该创建一个文件叫modsecurity_crs_15_customrules.conf 当作核心规则放在相同的目录下。使用这个文件名,你的自定义规则会在标准的ModSecurity规则之后被加载,但会在其他规则之前,这可以使得您的规则在您需要实施具体的“允许”规则或纠正任务误报的核规则时得到优先评估,从而使其真正用到你的网站系统上。

 


注意:
    我们鼓励您不要去修改核心规则文件,但你可以把所有的改动(就象SecRuleRemoveByID等)放到自己定义的文件中,这样可以让您很方便的从ModSecurity站点升级新的核心规则文件。

 

SecAction

描述:无条件执行动作列表中的第一个也是唯一的一个参数,只接受一个参数,其句法规则与SecRule的第三个参数相同

语法:SecAction action1,action2,action3

示例:SecAction nolog,initcol:RESOURCE=%{REQUEST_FILENAME}

阶段:所有

范围:所有

版本:2.0.0

备注:无

 

    SecAction是您想无条件执行一个动作时的最好选择,这是有条件基于对请求/响应数据的检查导致明确的控制产生的一般动作,当你想运行一些特定的动作如initcol来初始化搜集时这是一个很有用的指令。

 

SecArgumentSeparator

描述:指定的字符做为application/x-www-form-urlencoded内容的分隔符,默认是&,非常少的情况下应用会使用分号(;)。

语法:SecArgumentSeparator character

示例:SecArgumentSeparator ;

阶段:所有

范围:Main

版本:2.0.0

备注:无

 

    这个指令用于后台WEB应用在使用非标准的参数分隔符,如果没有在每一个WEB应用中合理设置这个指令,那么ModSecurity可能无法适当的分析所有的参数,并且规则匹配的效果可能会显著的降低。

 

SecAuditEngine

描述:配置审计日志引擎的开启与否

语法:SecAuditEngine On|Off|RelevantOnly

示例:SecAuditEngine On

阶段:N/A

范围:任意

版本:2.0.0

 

备注:在当前事务可以通过ctl操作进行设置或修改

 

举例:以下例子说明不同的审计指令一起使用

 

SecAuditEngine RelevantOnly 
SecAuditLog logs/audit/audit.log
SecAuditLogParts ABCFHZ
SecAuditLogType concurrent
SecAuditLogStorageDir logs/audit
SecAuditLogRelevantStatus ^(?:5|4\d[^4])

 

允许值如下:

On - 默认情况下记录所有事务的日志
Off - 默认情况下不记录所有事务的日志
RelevantOnly - 默认只记录事务中由warning或error触发的日志,或者记录一些特意考虑过的状态码

 

SecAuditLog

描述:定义主审计日志文件路径

语法:SecAuditLog /path/to/auditlog

示例:SecAuditLog /usr/local/apache/logs/audit.log

阶段:N/A

范围:Any

版本:2.0.0

备注:伴随服务器运行开时,这个文件会以root打开,你不能为非root权限的用户对这个文件或存储这个文件的目录有可写权限。

 

    如果串行审计日志格式使用后,这个文件将被用作审计日志条目的存储。如果同时审计日志格式使用这个文件那将被当作索引,并包含所有的审计日志文件创建信息。如果你计划使用同时审计日志并发送审计日志数据到远程主机或商业ModSecurity管理平台,那么你需要配置和使用ModSecurity日志搜集器(mlogc)并使用下述格式去得到审计日志。

 

SecAuditLog "|/path/to/mlogc /path/to/mlogc.conf"

 

五、配置指令(二)

 

SecAuditLog2

描述:定义同时日志启用下的第二审计日志索引文件路径

语法:SecAuditLog2 /path/to/auditlog2

示例:SecAuditLog2 /usr/local/apache/logs/audit2.log

阶段:N/A

范围:Any

版本:2.1.2

 

备注:在本指令使用之前必须通过SecAuditLog定义主审计日志,另外这个文件仅用于当同时审计日志使用时复制主审计索引文件,不能用于非同时审计日志的情况。

 

 

SecAuditLogParts

描述:定义每个事务中记录到审计日志中的部分。每部分以一个独立的字母表示,当某个字母出现在列表中,也就是指每个事务中的相同部分会被记录,全部列表见下文。

语法:SecAuditLogParts PARTS

示例:SecAuditLogParts ABCFHZ

阶段:N/A

范围:Any

版本:2.0.0

备注:在这个时候ModSecurity不记录apache的见用响应内容(如404),或者服务器和日期的响应头。

 

默认:ABCFHZ.

 

可用的审计日志部分:

 

A - 审计日志标题(强制的)

B - 请求标题

C - 请求体(目前仅针对请求体存在,并且ModSecurity已经配置成拦截)

D - 为中间人响应头保留,暂未实现

E - 中间人响应体(目前仅对配置了拦截响应体和配置审计日志引擎记录有效)。中间人响应体和实际的响应体相同,除非ModSecurity拦截了中间人响应体,这种情况下,实际响应体会包含出错信息(可能是apache的默认错误信息,也可能是出错文档页面)。

F - 最终响应头(除了日期和服务器标题以外的被apache添加的近期内容传递信息)。

G - 为实际响应体保留,暂未实现。

H - 审计日志索引

I - 这C部分的替换,使用multipart/form-data编码时,在所有的异常情形下会记录与C相同的数据,在这种情况下,会记录假的application/x-www-form-urlencoded内容,这包含参数的相关信息,但不是这个文件的。如果你不想用文件(通常很大)来存储你的审计日志,这是很方便的。

J - 保留。实现后,这部分会包含文件使用multipart/form-data编码上传的信息。

K - 这部分包含一个完整的列表,按顺序匹配(每行一个),这些规则是完全合格的,从而表明继承默认的动作和操作,从2.5.0开始支持。

Z - 最终分界,意味着是条目的最后(强制的)

 

 

SecAuditLogRelevantStatus

描述:配置哪些响应状态码与审计日志的目的密切相关

语法:SecAuditLogRelevantStatus REGEX

示例:SecAuditLogRelevantStatus ^(?:5|4\d[^4])

阶段:N/A

范围:Any

版本:2.0.0

备注:必须将SecAuditEngine设置为RelevantOnly,其参数是个正则表达式。

 

    这个指令最主要的目的是允许你配置审计产生特殊HTTP响应状态码的唯一事务,这个指令通常用于减少审计日志文件的总体大小。记住一点,如果使用了这个参数,那么返回状态码是200的成功攻击事件不会记录。

 

 

SecAuditLogStorageDir

描述:配置同时审计日志条目存储时的路径

语法:SecAuditLogStorageDir /path/to/storage/dir

示例:SecAuditLogStorageDir /usr/local/apache/logs/audit

阶段:N/A

范围:Any

版本:2.0.0

备注:必须同时设置SecAuditLogType,启动apache前,需要先创建目录,而且必须让服务器用户运行时可以新建文件。

 

    尽管有了记录日志的机制,还需要确保指定的本地文件系统上有足够的磁盘究竟,并且不是在根分区上。

 

 

SecAuditLogType

描述:配置使用审计日志记录机制的类型

语法:SecAuditLogType Serial|Concurrent

示例:SecAuditLogType Serial

阶段:N/A

范围:Any

版本:2.0.0

备注:如果使用Concurrent类型必须指定SecAuditLogStorageDir

 

可用的值:

Serial - 所有的审计日志条目都被存储在主审计日志记录文件中,随意使用是很方便,但是它很慢,因为任何时候只有一个文件被打开也只能写入一条审计日志条目。

Concurrent - 审计日志条目被存储于不同的文件中,每个事务一个,如果你要把审计日志数据发送到远程ModSecurity控制主机上就使用Concurrent日志模式。

 

六、配置指令(三)

 

SecCacheTransformations (Deprecated/Experimental)

描述:控制transformations的缓存,2.5.6开始,缓存是默认关闭的,当时都不赞成开启并降低为实验性。

语法:SecCacheTransformations On|Off [options]

示例:SecCacheTransformations On "minlen:64,maxlen:0"

阶段:N/A

范围:Any

版本:2.5.0

备注:N/A

 

第一个参数:

On - 缓存变化(每阶段,每次变化)允许相同的变化只执行一次(默认的)

Off - 不缓存任务变化,强制所有的变化都被每一条规则实行生效

 

有以下可选项(逗号分隔)

incremental:on|off - 启用这个选项后,缓存每一个变化,而不只是最后一个变化(默认:off)

maxitems:N - 缓存N个以内的变化,超过时不再缓存,为0时表示unlimited,对于限制缓存一个使用大数字的ARGS表单这个选项是有用的。(默认:512)

minlen:N - 缓存变化的值的最小长度(默认:32)

maxlen:N - 缓存变化的值的最大长度,为0时表示unlimited (默认:1024)

 

七、配置指令(四)

 

SecChrootDir

描述:配置WEB服务器工作的安全目录

语法:SecChrootDir /path/to/chroot/dir

示例:SecChrootDir /chroot

阶段:N/A

范围:Main

版本:2.0.0

备注:这个功能在Windows系统的版本上不可用,ModSecurity提供的内部chroot功能在简单配置上工作的很好,举个最简单的配置例子,apache只提供静态页面服务或使用模块提供脚本运行功能。在一些复杂设置时你会遇到一些问题:

 

1、DNS查询无法工作(这是因为这一功能在chroot操作后,一经查询就要求加载一个共享库)
2、你不能使用PHP发送邮件,因为PHP使用sendmail但sendmail在安全目录之外
3、某些情况下apache会莫名其妙的不干活了(重载)

 

    你需要小心,这个内部chroot功能可能不是100%可用。由于大量默认的或是第三方为apache web服务器提供的模块,它们不可能去校验在内部chroot下是否可用,在没有被限制在安全目录中时,一个apache的模块,工作的很正常。特别是如果你正使用的模块在模块初始化阶段进行fork的(如mod_fastcgi,mod_fcgid,mod_cgid),建议你测试每个apache进程和观察其工作目录,进程根目录,以及所打开的文件列表。考虑一下你的选择,并做出自己的决定。

 

 

SecComponentSignature

描述:扩展组件签名为ModSecurity签名

语法:SecComponentSignature "COMPONENT_NAME/X.Y.Z (COMMENT)"

示例:SecComponentSignature "Core Rules/1.2.3"

阶段:N/A

范围:Main

版本:2.5.0

备注:这个指令可以让ModSecurity增加很多有意义的已知组件,完整的签名被记录在事务审计记录中,应该让ModSecurity模块和规则集作家使用,使调试更加容易。

 

 

SecContentInjection

描述:启用内容注入使用行为附加并加在前面

语法:SecContentInjection (On|Off)

示例:SecContentInjection On

阶段:N/A

范围:Any

版本:2.5.0

备注:N/A

 

 

SecCookieFormat

描述:选择当前配置文本中使用的cookie格式

语法:SecCookieFormat 0|1

示例:SecCookieFormat 0

阶段:N/A

范围:Any

版本:2.0.0

备注:None

 

可选值如下:

0 - 使用version 0 (Netscape) cookies,这是大部分应用使用的,也是默认值
1 - 使用version 1 cookies

 

八、配置指令(五)

 

SecDataDir

描述:指定连续数据(如ip地址数据,session数据等)存储的路径

语法:SecDataDir /path/to/dir

示例:SecDataDir /usr/local/apache/logs/data

阶段:N/A

范围:Main

备注:initcol、setsid和setuid需要用到这个指令,必须让服务器用户对这个目录可写

 

SecDebugLog

描述:指定ModSecurity调试日志文件的路径

语法:SecDebugLog /path/to/modsec-debug.log

示例:SecDebugLog /usr/local/apache/logs/modsec-debug.log

阶段:N/A

范围:Any

版本:2.0.0

备注:None

 

SecDebugLogLevel

描述:配置冗长的调试日志数据

语法:SecDebugLogLevel 0|1|2|3|4|5|6|7|8|9

示例:SecDebugLogLevel 4

阶段:N/A

范围:Any

版本:2.0.0

备注:1~3级别一直用于产生apache的错误日志,因为你可以在产品中一直使用0级别做为默认的日志级别,级别5用于调试,不建议在产品中使用这么高级别的日志,过度的日志记录会显著服务器的性能。

 

可用的值如下:

0 - 不记录.

1 - 仅仅错误日志(拦截请求)

2 - 警告

3 - 注意

4 - 事务控制的细节

5 - 同上,但包含每一个信息控制的信息

9 - 记录所有,包括每一个调试细节信息

 

九、配置指令(六)

 

SecDefaultAction

描述:定义匹配规则后的默认动作

语法:SecDefaultAction action1,action2,action3

示例:SecDefaultAction log,auditlog,deny,status:403,phase:2

阶段:Any

范围:Any

版本:2.0.0

备注:SecDefaultAction指令后的规则都继承这一设置,除非为某条规则指定了一个特定的动作,或者指定了新的SecDefaultAction。特别注意到,未经处理的disruptive动作是不允许的,但是在SecDefautlAction中一不小心就会继承了使用disruptive动作。

 

默认值勤是minimal(和以前的版本不同)

SecDefaultAction phase:2,log,auditlog,pass

注意:

SecDefaultAction必须指定一个disruptive动作和处理阶段,而且不能包含元数据动作。

警告:

SecDefaultAction不继承交叉配置的内容。(举个例子,这或许让你感到疑惑,请阅读ModSecurity Blog条目:http://blog.modsecurity.org/2008/07/modsecurity-tri.html)。

 

 

SecGeoLookupDb

描述:定义地理数据文件路径

语法:SecGeoLookupDb /path/to/db

示例:SecGeoLookupDb /usr/local/geo/data/GeoLiteCity.dat

阶段:N/A

范围:Any

版本:2.5.0

备注:从maxmind.com提取的免费数据文件

 

 

SecGuardianLog

描述:配置使用httpd-guardian脚本来监视拒绝服务攻击(DoS)的指令

语法:SecGuardianLog |/path/to/httpd-guardian

示例:SecGuardianLog |/usr/local/apache/bin/httpd-guardian

阶段:N/A

范围:Main

版本:2.0.0

备注:使用默认的httpd-guardian可以防止客户端在1分钟内请求120次或5分钟内请求360次。

 

从1.9版本后,ModSecurity支持一个新的指令,SecGuardianLog,设计此指令用于把所有允许数据通过管理日志功能发送到另一个程序。自从apache部署成典型的多进程方式,信息共享变得困难了,这一想法就是部署一个独立的外部进程使用状态机的方式去观察所有的请求,提供额外的保护。

 

随着ModSecurity发布,开发一个先进的外部保护工具将是一个重点。然而一个完整功能的工具已经可以做为apache httpd工具项目的一部分,工具名为httpd-guardian,它能用于防御DoS,使用黑名单列表(同一个项目中)和基于iptables(linux)或者基于pf(*BSD)的防火墙协同工作,动态的过滤黑名单中的恶意IP地址。也可以和SnortSam协同工作(http://www.snortsam.net)。如果已经配置过httpd-guardian(具体介绍请查看源代码)你只需要在apache配置中添加一行就可以部署它:

SecGuardianLog |/path/to/httpd-guardian

 

 

SecMarker

描述:在规则集中增加一个固定规则marker,可用于skipAfter动作。SecMarker指令本质上是创建了一条规则,这条规则什么也不做,其目的只是占用一个ID号

语法:SecMarker ID

示例:SecMarker 9999

阶段:Any

范围:Any

版本:2.5.0

备注:None

 

SecRule REQUEST_URI "^/$" \

    "chain,t:none,t:urlDecode,t:lowercase,t:normalisePath,skipAfter:99"

SecRule REMOTE_ADDR "^127\.0\.0\.1$" "chain"

SecRule REQUEST_HEADERS:User-Agent \

    "^Apache \(internal dummy connection\)$" "t:none"  

SecRule &REQUEST_HEADERS:Host "@eq 0" \

    "deny,log,status:400,id:08,severity:4,msg:'Missing a Host Header'"

SecRule &REQUEST_HEADERS:Accept "@eq 0" \

    "log,deny,log,status:400,id:15,msg:'Request Missing an Accept Header'"

 

SecMarker 99

 

十、配置指令(七)

 

SecPdfProtect

描述:启用PDF XSS保护功能,一量启用访问PDF文件的跟踪,直接访问尝试被转到包含一次性令牌的链接,只有提供有效令牌的请被无条件允许,无效令牌的请求也被允许,但被强制下载PDF文件。本实现用响应头去检测PDF文件,因此可以对一些URI请求中不含有.pdf扩展名却能动态生成PDF文件。

语法:SecPdfProtect On|Off

示例:SecPdfProtect On

阶段:N/A

范围:Any

版本:2.5.0

备注:None

 

SecPdfProtectMethod

描述:配置理想的保护方法用于请求的PDF文件进行保护。可有的选项有TokenRedirection和ForcedDownload。令牌重定向方式会尝试转到可有的令牌上,这允许PDF文件仍旧能使用内联方式打开,但仅用于GET请求方式。强制下载总是导致PDF文件使用二进制或附件方式传递,后者常用于非GET请求,强制下载方式被认为更安全,但对用户来说可能会导致可用性问题("这个PDF无法再打开了")。

语法:SecPdfProtectMethod method

示例:SecPdfProtectMethod TokenRedirection

阶段:N/A

范围:Any

版本:2.5.0

备注:None

默认:TokenRedirection

 

SecPdfProtectSecret

描述:定义用于产生一次性令牌的密钥,你应该设置一个足够长的串作为密钥(16个字符较好),一旦定下密钥,最好不要修改可能会破坏修改前发出的令牌。但即使你修改了也不是大问题,导致过去的几秒钟变成使用令牌强制下载PDF文件。

语法:SecPdfProtectSecret secret

示例:SecPdfProtectSecret MyRandomSecretString

阶段:N/A

范围:Any

版本:2.5.0

备注:None

 

SecPdfProtectTimeout

描述:定义令牌超时,令牌过期后,不能再用于允许访问PDF文件,请求仍旧被允许,但PDF文件会以附件方式传送。

语法:SecPdfProtectTimeout timeout

示例:SecPdfProtectTimeout 10

阶段:N/A

范围:Any

版本:2.5.0

备注:None

默认:10

 

SecPdfProtectTokenName

描述:定义令牌名,你想改变令牌的名字的唯一原因应是你想隐藏你正使用ModSecurity这一事实,这是一个好的理由,但这并不能提供帮助,因为敌人能找到保护PDF的算法并能计算出来,这树立了新的标志,所以如果你想就去试吧。

语法:SecPdfProtectTokenName name

示例:SecPdfProtectTokenName PDFTOKEN

阶段:N/A

范围:Any

版本:2.5.0

备注:None

默认:PDFTOKEN

 

十一、配置指令(八)

 

SecRequestBodyAccess

描述:配置是否让ModSecurity默认处理或缓冲请求体

语法:SecRequestBodyAccess On|Off

示例:SecRequestBodyAccess On

阶段:N/A

范围:Any

版本:2.0.0

备注:如果你计划检查POST_PAYLOAD就使用这个指令,这个指令必须和"phase:2"处理阶段动作和REQUEST_BODY变量/位置一起使用,这三部分任一一个没有配置,你就无法检查请求体。

 

可选值有:

On - 访问请求体

Off - 不尝试访问请求体

 

SecRequestBodyLimit

描述:配置ModSecurity允许的最大请求体的缓存区大小

语法:SecRequestBodyLimit NUMBER_IN_BYTES

示例:SecRequestBodyLimit 134217728

范围:Any

版本:2.0.0

备注:默认值是131072 KB (134217728 bytes)。任何超过此限制的都会被拒绝,提示413,请求体太大。还有一个硬限制,1GB。

 

SecRequestBodyNoFilesLimit

描述:配置ModSecurity允许的最大请求体的缓存区大小,除了请求中正在传送的文件大小。这项指令便于在受到某些使用大尺寸请求进行DoS攻击时减少影响。提供上传文件服务的WEB应用必须配置SecRequestBodyLimit为一个很大的值。由于大文件直接进行磁盘文件存取,不会加大内存的消耗。但是,仍然有可能有人利用超大请求体限制和发送大量大小的非上传请求。该指令消除这一漏洞。

语法:SecRequestBodyNoFilesLimit NUMBER_IN_BYTES

示例:SecRequestBodyLimit 131072

范围:Any

版本:2.5.0

备注:默认为1 MB (1048576 bytes)。这个值比较古老了,大部分应用应该到128KB或是更低,任何超过此限制的都会被拒绝,提示413,请求体太大。还有一个硬限制,1GB。

 

 

SecRequestBodyInMemoryLimit

描述:配置ModSecurity使用内存保存的最大请求体大小

语法:SecRequestBodyInMemoryLimit NUMBER_IN_BYTES

示例:SecRequestBodyInMemoryLimit 131072

阶段:N/A

范围:Any

版本:2.0.0

备注:None

 

默认的限制是128 KB,在内存中最多存储128KB

SecRequestBodyInMemoryLimit 131072

 

 

SecResponseBodyLimit

描述:配置允许缓存的最大响应体大小

语法:SecResponseBodyLimit NUMBER_IN_BYTES

示例:SecResponseBodyLimit 524228

阶段:N/A

范围:Any

版本:2.0.0

备注:任何超过此限制的都会被拒绝,提示500,内部服务器错误。这一设置不影响使用MIME类型的响应,缓存不为此做标记,有一个硬限制,1GB。

 

默认配置成 512 KB:

# Buffer response bodies of up to 512 KB in length 

SecResponseBodyLimit 524288

 

 

SecResponseBodyLimitAction

描述:配置SecResponseBodyLimit控制碰到响应体限制的情况,默认时ModSecurity拒绝超过指定长度的响应体,然而一些WEB站点,会产生一些非常长的响应为适当限制带来难度。这类网站不得不极大的提高关注度,把限制放到了首位(控制内存消耗)。有能力选择的是发生站点限制时,管理员能选择仅仅检查响应的第一部分,这部分可融入理想的限制,并让其通过。可以证明未经检查就允许部分响应是个漏洞,理论上这是对的,但仅适用于攻击者控制输出的案例(如它可以任意的长)。不管怎样,在这种情况下,无论如何是阻止不了漏洞的。攻击者在数据回送前可以压缩,打乱或者甚至是加密,因为可以穿越任意监控设备。

语法:SecResponseBodyLimitAction Reject|ProcessPartial

示例:SecResponseBodyLimitAction ProcessPartial

阶段:N/A

范围:Any

版本:2.5.0

备注:None

 

 

SecResponseBodyMimeType

描述:为响应数据缓存配置推荐的MIME类型

语法:SecResponseBodyMimeType mime/type

示例:SecResponseBodyMimeType text/plain text/html

阶段:N/A

范围:Any

版本:2.0.0

备注:可以使用多个SecResponseBodyMimeType指令来增加MIME类型

 

默认值是text/plain text/html:

SecResponseBodyMimeType text/plain text/html

 

 

SecResponseBodyMimeTypesClear

描述:清除推荐的响应体缓存MIME类型,允许你重新开始配置。

语法:SecResponseBodyMimeTypesClear

示例:SecResponseBodyMimeTypesClear

阶段:N/A

范围:Any

版本:2.0.0

备注:None

 

 

SecResponseBodyAccess

描述:配置响应体是否被缓存并被分析

语法:SecResponseBodyAccess On|Off

示例:SecResponseBodyAccess On

阶段:N/A

范围:Any

版本:2.0.0

备注:如果你计划检查HTML的响应,需要使用这个指令。这个指令必须和"phase:4"处理阶段动作和REQUEST_BODY变量/位置一起使用,这三部分任一一个没有配置,你就无法检查请求体。

 

可选值如下:

On - 访问响应体 (仅支持使用MIME类型,具体见上述).

Off - 不尝试访问响应体

 

十二、配置指令(九)

 

SecRule

描述:SecRule是ModSecurity主要的指令,用于分析数据并根据结果执行动作。

语法:SecRule VARIABLES OPERATOR [ACTIONS]

示例:SecRule REQUEST_URI "attack" \

"phase:1,t:none,t:urlDecode,t:lowercase,t:normalisePath"

阶段:Any

范围:Any

版本:2.0.0

备注:None

 

通常规则的格式如下:

SecRule VARIABLES OPERATOR [ACTIONS]

第二部分,OPERATOR描述如何进行检查,第三部分可选的,ACTIONS,描述当操作进行成功的匹配一个变量时具体怎么做。

 

规则中的变量

第一部分,VARIABLES描述哪个变量被检查,举个例子,下述规则会拒绝URI中含有单词dirty的事务。

SecRule ARGS dirty

 

每条规则可以指定一个或多个变量

SecRule ARGS|REQUEST_HEADERS:User-Agent dirty

 

XPath格式是选择操作的第三方支持格式。XPath格式仅能针对特殊变量XML使用,只有请求体使用XML格式时可用。

SecRule XML:/xPath/Expression dirty

注意:

不是所有的集合支持选择操作格式类型,你需要参考各个集合的文档来决定是否支持。

 

Collections

一个变量可以包含一个或多个片断的数据,根据变量的性质和方法进行使用,前一节我们看到了这两种方法的例子,当一个变量可以包含一个以上的值,我们把它称为集合。

 

集合在规则运行前都是可以扩展的。举例如下:

SecRule ARGS dirty

可以进行如下扩展:

SecRule ARGS:p dirty

SecRule ARGS:q dirty

请求中有两个参数,名为p和q。

 

集合有几个特色:

只读

在运行时创建事务数据,如:ARGS (包含所有请求参数列表)和REQUEST_HEADERS (包含所有的请求头列表).

 

短暂的读/

每个事备创建一个空的TX集合,规则能读也能写(如使用setvar动作),但信息存储在这个集合中直到事务结束。

 

连续的读/

有几个集合可写,但是为连续的后台存储。这些集合被用于跟踪客户端的交互事务,例如分成IP、SESSION和USER等类型的集合。

 

操作的规则

一种很简单的情况下,你可能会用一个正则表达式作为规则的第二个参数,我们已经在上面举过这样的例子,如果你这样做,ModSecurity假设你会使用rx(正则表达式)操作符,你也可以很明确的通过使用@来指定你想要的操作符,紧跟之后的是操作符的名字,在规则第二个参数的开始。

SecRule ARGS "@rx dirty"

注意我们为什么必须使用双引号把第二个规则参数括起来呢,这是因为第二个参数可能包含空格。一些带空格字符和数字会跟在操作符名字后面,如果出现非空格的字符,所有的这些都会被当作操作符的参数。这种情况下指定的参数中的正则表达式被作为模式进行匹配。

 

如果你使用取非操作符取反操作符返回的结果,可以让@处于第二个字符。

SecRule &ARGS "!@rx ^0$"

 

取非操作符

操作符的结果可以通过在第二个字符前使用感叹号来取反,下述规则匹配在User-Agent请求头中找不到dirty单词:

SecRule REQUEST_HEADERS:User-Agent !dirty

你能用感叹号与任一个参数联合使用,这样做,感叹号优先,后面跟上明确的操作符说明,下述规则与前面的例子有相同的效果。

SecRule REQUEST_HEADERS:User-Agent "!@rx dirty"

 

如果你在多个变量中使用取非操作符,这可能无法立即清楚将会发生什么情况,考虑下述例子:

SecRule ARGS:p|ARGS:q !dirty

这个规则与下面意思相同

SecRule ARGS:p !dirty

SecRule ARGS:q !dirty

警告:

取非用于单个操作符,而不要在整体的变量列表中使用。

 

规则中的动作

第三个参数,ACTIONS可以忽略,因为有个辅助功能,即指定的默认动作列表。如果这个参数没有被省略,当规则匹配时,这个参数指定的动作会联合默认的动作列表创建一个实际的动作列表被执行。

 

 

SecRuleInheritance

描述:配置当前环境是否继承父节点环境(大部分情况下都配置成可继承,你应当查一下文档的每一个指令,以明确它继承与否)

语法:SecRuleInheritance On|Off

示例:SecRuleInheritance Off

阶段:Any

范围:Any

版本:2.0.0

备注:指定资源的环境(如:Location, Directory,等)不能覆盖主服务器或虚拟服务器上配置的phase1规则。这是因为phase1在请求处理进程之前运行,早于apache分发请求的资源,虚拟服务环境可以覆盖主服务器配置的phase1规则。

 

例如:下面的例子显示了在主apache配置范围的哪个地方启用ModSecurity,不过,你可以为你的虚拟主机做不同的配置。第一个例子中,头一个虚拟主机没有继承ModSecurity的主配置指令,而第二做到了。

SecRuleEnine On

SecDefaultAction log,pass,phase:2

...  

 

<VirtualHost *:80>

ServerName app1.com 

ServerAlias www.app1.com

SecRuleInheritance Off

SecDefaultAction log,deny,phase:1,redirect:http://www.site2.com 

... 

</VirtualHost>  

 

<VirtualHost *:80> 

ServerName app2.com 

ServerAlias www.app2.com

SecRuleInheritance On SecRule ARGS "attack" 

... 

</VirtualHost>

 

可选的值如下:

On - 从父环境下继承规则

Off - 不从父环境下继承规则

注意:

Configuration Sections是apache的一个概念,指令 <Directory>, <Files>, <Location> 和 <VirtualHost> 都是用于创建Configuration Sections的,更多的信息请看apache的文档部分中的Configuration Sections。

 

SecRuleEngine

描述:配置规则引擎

语法:SecRuleEngine On|Off|DetectionOnly

示例:SecRuleEngine On

阶段:Any

范围:Any

版本:2.0.0

备注:这个指令针对每一条规则处理也可以通过ctl动作进行控制(ctl:ruleEngine=off)

 

可选的值:

On - 处理规则

Off - 不处理规则

DetectionOnly - 处理规则但不中断事务,即使规则配置了也不做。

十三、配置指令(十)

 

SecRuleRemoveById

描述:使用ID方式从上级环境中删除规则

语法:SecRuleUpdateActionById RULEID ACTIONLIST

示例:SecRuleRemoveByID 1 2 "9000-9010"

阶段:Any

范围:Any

版本:2.0.0

备注:这个指令支持多个参数,每个参数可以是一个规则ID,也可以是范围。带有空格的参数必须使用双引号括起来。

SecRuleRemoveById 1 2 5 10-20 "400-556" 673

 

 

SecRuleRemoveByMsg

描述:使用规则方式从上级环境中删除规则

语法:SecRuleRemoveByMsg REGEX

示例:SecRuleRemoveByMsg "FAIL"

阶段:Any

范围:Any

版本:2.0.0

备注:这个指令支持多个参数,每个指令是一个应用于消息的正则表达式(指定使用的消息动作)。

 

 

SecRuleScript (试验性的)

描述:这个指令创建一个特殊的规则,执行Lua脚本来决定是否匹配,和SecRule主要的不同是这个没有目的也没有操作符,这个脚本可以从ModSecurity环境中取到所有的变量,并使用(Lua)操作符来进行测试,第二个参数可选,与SecRule相同,是一些动作列表。

语法:SecRuleScript /path/to/script.lua [ACTIONS]

示例:SecRuleScript "/path/to/file.lua" "block"

阶段:Any

范围:Any

版本:2.5.0

备注:None

 

注意

所有的Lua脚本在配置时进行编译并存入内存,要重载脚本,你必须通过apache重启来重载整个ModSecurity配置。

示例脚本:

-- Your script must define the main entry

-- point, as below.

function main()

    -- Log something at level 1. Normally you shouldn't be

    -- logging anything, especially not at level 1, but this is

    -- just to show you can. Useful for debugging.

    m.log(1, "Hello world!");

 

    -- Retrieve one variable.

    local var1 = m.getvar("REMOTE_ADDR");

 

    -- Retrieve one variable, applying one transformation function.

    -- The second parameter is a string.

    local var2 = m.getvar("ARGS", "lowercase");

 

    -- Retrieve one variable, applying several transformation functions.

    -- The second parameter is now a list. You should note that m.getvar()

    -- requires the use of comma to separate collection names from

    -- variable names. This is because only one variable is returned.

    local var3 = m.getvar("ARGS.p", { "lowercase", "compressWhitespace" } );

 

    -- If you want this rule to match return a string

    -- containing the error message. The message must contain the name

    -- of the variable where the problem is located.

    -- return "Variable ARGS:p looks suspicious!"

 

    -- Otherwise, simply return nil.

    return nil;

end

第一个例子,我仅每次提取一个变量,这种情况下,你需要事先知道变量,然而很多时候,你想检查一些事先不知道的变量名字,就象下面这个例子。

Example showing use of m.getvars() to retrieve many variables at once:

 

function main()

    -- Retrieve script parameters.

    local d = m.getvars("ARGS", { "lowercase", "htmlEntityDecode" } );

 

    -- Loop through the paramters.

    for i = 1, #d do

        -- Examine parameter value.

        if (string.find(d[i].value, "<script")) then

            -- Always specify the name of the variable where the

            -- problem is located in the error message.

            return ("Suspected XSS in variable " .. d[i].name .. ".");

        end

    end

 

    -- Nothing wrong found.

    return nil;

end

注意

到http://www.lua.org/了解更多有关Lua程序语言,参考手册在http://www.lua.org/manual/5.1/能在线阅读

 

注意

Lua支持被标示试验方式的编程接口可以继续发展,同时我们努力让其最佳方式运行,感谢任何人为些提供编程接口。

 

 

SecRuleUpdateActionById

描述:按ID方式更新指定规则的动作列表

语法:SecRuleRemoveById RULEID ACTIONLIST

示例:SecRuleUpdateActionById 12345 deny,status:403

阶段:Any

范围:Any

版本:2.5.0

备注:本指令合并指定的动作列表和规则的动作列表,存在两个限制,一是规则ID不能被改变,也不能换阶段。另外还需要注意的是动作可以多次被附加到原来的。

 

SecAction \

  "t:lowercase,phase:2,id:12345,pass,msg:'The Message',log,auditlog"

SecRuleUpdateActionById 12345 "t:compressWhitespace,deny,status:403,msg:'A new message'

The example above will cause the rule to be executed as if it was specified as follows:

 

SecAction \

  "t:lowercase,phase:2,id:12345,log,auditlog,t:compressWhitespace,deny,status:403,msg:'A new message'"

 

 

SecServerSignature

描述:通知ModSecurity改变响应头令牌数据中当前使用的"Server:" 

语法:SecServerSignature "WEB SERVER SOFTWARE"

示例:SecServerSignature "Netscape-Enterprise/6.0"

阶段:N/A

范围:Main

版本:2.0.0

备注:按指令的先后顺序执行,你必须完整的配置apache ServerTokens指令。通过该指令,ModSecurity会改写服务器签名数据并存入内存空间的数据集中。如果ServerTokens没有完整设置,那么内存空间就没有希望的足够大来存入我们看到的新数据。

 

 

SecTmpDir

描述:配置临时文件创建的路径

语法:SecTmpDir /path/to/dir

示例:SecTmpDir /tmp

阶段:N/A

范围:Any

版本:2.0.0

备注:需要提供apache用户进程的可写权限,这个目录的位置也是当apache检查数据用完内存时(比SecRequestBodyInMemoryLimit指令指定的还多的数据)会将数据交换到磁盘上的位置。

 

 

SecUploadDir

描述:配置拦截文件存储的目录

语法:SecUploadDir /path/to/dir

示例:SecUploadDir /tmp

阶段:N/A

范围:Any

版本:2.0.0

备注:This directory must be on the same filesystem as the temporary directory defined with SecTmpDir. This directive is used with SecUploadKeepFiles.

 

 

SecUploadFileMode

描述:用8进制数(和chmod一样)配置所有上传文件的模式(权限)

语法:SecUploadFileMode octal_mode|"default"

示例:SecUploadFileMode 0640

阶段:N/A

范围:Any

版本:2.1.6

备注:这个功能在不支持8进制文件模式的操作系统上不可用。默认模式(0600)仅允许有读写许可的帐号修改这个文件,如果其他帐号也需要访问(使用clamd是个好例子),那么这个指令是必须的。不管怎样,要慎用这个指令,避免将敏感数据显露给未授权用户,使用"default"值时,还原默认设置。

 

 

SecUploadKeepFiles

描述:配置是否保存事务处理后的拦截文件

语法:SecUploadKeepFiles On|Off|RelevantOnly

示例:SecUploadKeepFiles On

阶段:N/A

范围:Any

版本:2.0.0

备注:该指令要求已经定义存储目录(使用SecUploadDir).

 

可选值:

On - 保存上载文件

Off - 不保存上载文件

RelevantOnly - 只保存被确认与请求有关的文件

 

 

SecWebAppId

描述:创建服务器上的一个分区只属于一个WEB应用

语法:SecWebAppId "NAME"

示例:SecWebAppId "WebApp1"

阶段:N/A

范围:Any

版本:2.0.0

备注:通过使用分区来避免会话ID和用户UD之间的冲突,在同一台服务器上部署多个应用时一定要使用这个指令,如果不使用,会话ID之间的冲突可能发生,默认值是default,如:

<VirtualHost *:80> 

ServerName app1.com 

ServerAlias www.app1.com

SecWebAppId "App1"

SecRule REQUEST_COOKIES:PHPSESSID !^$ chain,nolog,pass 

SecAction setsid:%{REQUEST_COOKIES.PHPSESSID} 

... 

</VirtualHost>  

 

<VirtualHost *:80> 

ServerName app2.com 

ServerAlias www.app2.com

SecWebAppId "App2"

SecRule REQUEST_COOKIES:PHPSESSID !^$ chain,nolog,pass 

SecAction setsid:%{REQUEST_COOKIES.PHPSESSID} 

... 

</VirtualHost>

配置显示了两个例子,SecWebAppId与apache的VirtualHost指令协同工作,在一台服务器上应创建各自独特的集合名称,一般情况下,当启用setsid时,ModSecurity会使用"SESSION"的錅来创建集合,这可以保存专用值,然而象上述例子一样使用SecWebAppId,集合的名字会变成"App1_SESSION"和"App2_SESSION"。

 

SecWebAppId相关的两个情况:

你正把事务和报警记录到ModSecurity控制台上,并且你想用WEB应用ID来搜索仅属于那些应用的事务。

你正使用数据留存设施(SESSION和USER集合)并且你需要在属于不同的应用之间的会话和用户的冲突。

 

 

十四、处理阶段

 

ModSecurity 2.x允许把规则置于下述五个阶段之一:

请求头(REQUEST_HEADERS)

请求体(REQUEST_BODY)

响应头(RESPONSE_HEADERS)

响应体(RESPONSE_BODY)

记录(LOGGING)

 

    下图是标准的apache请求流程,5个ModSecurity处理阶段显示其中。

为了在规则执行时选择阶段,需要使用阶段命令,可以通过规则中直接使用,也可以通过SecDefaultAction指令。

SecDefaultAction "log,pass,phase:2"

SecRule REQUEST_HEADERS:Host "!^$" "deny,phase:1"

注意:

    要注意规则的执行是依赖于阶段,即使是一个配置文件中的两条邻近的规则,只要是设置了在不同的阶段中执行,它们就不会是一个接一个的生效。配置文件中的规则顺序仅仅是在规则各自的阶段中是重要的。在使用Skip和SkipAfter动作时尤为重要。

 

注意:

    LOGGING阶段比较特别,无论前面的各个阶段发生了什么事,都会每个事务的最后被执行。这就意味着哪怕是请求被中断或是放行事务时都会被执行。

 

请求头阶段

    这个阶段的规则会在apache完成请求头的读取后立即被执行(post-read-request阶段),这时,还没有读取请求体,意味着不是所有的参数都可用。如果你必须让规则尽早运行,应把规则放在这个阶段(在apache使用这个请求做某些事前),在请求体被读取前做些事情,从而决定是否缓存这个请求体,或者决定你将希望这个请求体如何被处理(如是否以XML格式解析或不解析)。

 

注意:

    这个阶段的规则无法影响apache的范围指令(Directory, Location, LocationMatch等)像post-read-request钩子一样还无法得到信息。VirualHost指令有些例外,如果想在apache的locations使用ModSecurity规则,那么他们应该运行在阶段2,参考apache请求环/ModSecurity处理阶段图表。

 

请求体阶段

    这是通用输入分析阶段,大部分传统的应用规则不在这儿,这个阶段你肯定能收到参数(只有读取过请求体后),在请求体阶段,ModSecurity支持三种编码类型。

application/x-www-form-urlencoded - used to transfer form data

multipart/form-data - used for file transfers

text/xml - used for passing XML data

 

    大部分WEB应用还没有使用其他的编码方法。

 

响应头阶段

    发生在响应头被发送到客户端之前,如果你想观察响应发生前就在这儿运行,如果你想使用响应头来决定你是否想缓存响应体也行。注意一些响应状态码(如404)在请求环的早期就被apache管理着,我也无法触发预期。加上apache在后面的勾子上双增加了一些响应头(如日期、服务器和连接信息等),这些我们无法触发和审查。在代理配置模式下或使用phase:5(logging)工作的较好。

 

响应体阶段

    这是通用输出分析阶段,这里你能运行规则截断响应体(当然提供缓存)。这个阶段你想检查输出的HTML信息公布、错误消息和失败的验证文字。

 

日志阶段

    在日志发生前运行的一个阶段,放在这个阶段的规则只能影响日志记录器如何执行,这个阶段可以检测apache记录的错误消息,在这个阶段你不能拒绝或阻断连接,因为太迟了,这个阶段也允许检测其他的响应头,如那在phase:3或者phase:4阶段中不可用的。注意在这个阶段,你应当小心不要继承破坏性的动作到规则中,这样的情况在ModSecurity2.5.0及其以后的版本中被当作配置错误。

 

十五、变量(A~E

 

Variables

    以下都是ModSecurity 2.x中支持的变量

 

ARGS

    ARGS是一个集合,可以作为静态参数(以名称匹配论点)方式或以正则表达式(以正则表达式匹配的所有匹配的论点名称)方式用于它自身(意思为POST负载中的所有论点),

 

    一些变量是事实上的集合,在运行时可以扩展更多的变量,下述例子会测试所有的请求论点。

 

SecRule ARGS dirty

    不过有些时候你只想看看集合的一部分,可以通过selection操作(colon)得到完美的帮助,下述例子仅提供查看名为p的变量(值得注意的是,通常行情况下,请求可以包含多个同名的变量)

SecRule ARGS:p dirty

 

    它也可以指定排除方式,下面的例子将仔细检查所有的请求参数是否有单词dirty,除了名字为z的参数(再则,z参数可以为0个,也可以是多个)

SecRule ARGS|!ARGS:z dirty

 

    这儿用了一个特殊的操作符,允许你统计一个集合中有多少个变量。如果一个请求中使用了0个以上的参数,下面的规则就会有效果(暂时忽视了第二个参数)。

SecRule &ARGS !^0$

 

    还有些时候你需要查看一个参数数组,每个名字只有稍微不同,这种情况下,你可以为集合操作符自己指定一个正则表达式,下面的规则就是查阅所有以id_打头的参数名字。

SecRule ARGS:/^id_/ dirty

 

注意:

    如果参数p不存在,则使用ARGS:p不会对操作符调用起到任何作用。

 

    在ModSecurity 1.x时,ARGS变量代表 QUERY_STRING + POST_PAYLOAD,但是现在已经扩展成独立的变量了。

 

 

ARGS_COMBINED_SIZE

    此变量相比apache的LimitRequest指令允许你更有针对性的设置Arguments的总大小。如你可以创建一条规则确保参数数据的部大小小于一个特定的阈值(帮助防止缓存溢出问题)。例:如果参数的大小超过25个字符就阻断它。

SecRule REQUEST_FILENAME "^/cgi-bin/login\.php" \

    "chain,log,deny,phase:2,t:none,t:lowercase,t:normalisePath"

SecRule ARGS_COMBINED_SIZE "@gt 25"

 

 

ARGS_NAMES

    是参数名的集合,你可以搜索你想阻断的特定的参数名,在一个积极策略情况下,你也可以仅仅使用白名单(使用!可以反转规则)来审计参数名。例:下例规则仅允许规则名为p和a的两个参数,如果有其他参数名字在其中,就会被阻断。

SecRule REQUEST_FILENAME "/index.php" \

    "chain,log,deny,status:403,phase:2,t:none,t:lowercase,t:normalisePath"

SecRule ARGS_NAMES "!^(p|a)$" "t:none,t:lowercase"

 

 

ARGS_GET

ARGS_GET类似于ARGS,但仅针对于查询字符串中包含的参数。

 

 

ARGS_GET_NAMES

ARGS_GET_NAMES类似于ARGS_NAMES,但仅针对于查询字符串中包含的参数。

 

 

ARGS_POST

ARGS_POST类似于ARGS,但仅针对于POST字符串中包含的参数。

 

 

ARGS_POST_NAMES

ARGS_POST_NAMES类似于ARGS_NAMES,但仅针对于POST字符串中包含的参数。

 

 

AUTH_TYPE

    这个变量保存认证方法用于验证一个用户,例:

注意

    这个数据在使用非本地认证的代理模式部署时不可用,在代理模式部署下,你需要检查REQUEST_HEADERS认证头。

 

 

ENV

    是个集合,规则一个单独的参数(在colon之后),ENV变量通过setenv设置,不提供CGI环境变量的访问,例如:

SecRule REQUEST_FILENAME "printenv" pass,setenv:tag=suspicious

SecRule ENV:tag "suspicious"

 

 

十六、变量(F-H

FILES

    是个集合,包含一系列的初始文件名(就如同在远程用户的文件系统上命名的一样),注意:只有从请求体中提取的文件才是有用的,例:

SecRule FILES "\.conf$" log,deny,status:403,phase:2

 

FILES_COMBINED_SIZE

    单一值,所有上传文件大小的总和,注意:只有从请求体中提取的文件才是有用的,例:

SecRule FILES_COMBINED_SIZE "@gt 1000" log,deny,status:403,phase:2

 

FILES_NAMES

    W/O参数集合,包含用于文件上传的表单字段列表,注意:只有从请求体中提取的文件才是有用的,例:

SecRule FILES_NAMES "^upfile$" log,deny,status:403,phase:2

 

FILES_SIZES

    集合,包含文件尺寸的列表,用于实施单独文件上传的大小限制。注意:只有从请求体中提取的文件才是有用的,例:

SecRule FILES_SIZES "@gt 100" log,deny,status:403,phase:2

 

FILES_TMPNAMES

    集合,包含磁盘上临时文件名的集合,和@inspecFile一起使用,注意:只有从请求体中提取的文件才是有用的,例:

SecRule FILES_TMPNAMES "@inspectFile /path/to/inspect_script.pl"

 

GEO

    GEO是和@geoLookups操作符一起使用的集合,可以用于匹配地理位置字段进行IP或主机名字的查询,2.2.0以后版本可用

字段:

COUNTRY_CODE: 两个字符的国家代号,如:US、UK等

COUNTRY_CODE3: 升级为三个字符的国家代号

COUNTRY_NAME: 完整的国家名

COUNTRY_CONTINENT: 两个字符的国家所在洲的代号,如:EU 

REGION: 两个字符表示的区域,对美国来说是州,对加拿大来说,是省,等等

CITY: 城市名

POSTAL_CODE: 邮政编码

LATITUDE: 纬度

LONGITUDE: 经度

DMA_CODE: 中心城区代码(仅指美国)

AREA_CODE: 电话区号(仅指美国)

例如:

SecRule REMOTE_ADDR "@geoLookup" "chain,drop,msg:'Non-UK IP address'"

SecRule GEO:COUNTRY_CODE "!@streq UK"

 

HIGHEST_SEVERITY

    这个变量是迄今为止所有规则匹配时最为严格的,Severities是个数值,和比较操作符一起,如@lt等

注意:更高的severities,其数值越小,255表示没有设置severity

 

SecRule HIGHEST_SEVERITY "@le 2" "phase:2,deny,status:500,msg:'severity %{HIGHEST_SEVERITY}'"