<< Back to man.ChinaUnix.net   CU网友原创,转载请注明出自ChinaUnix.net及原作者

配置

ModSecurity 配置指令可以直接被添加到你的配置文件中(典型配置是在httpd.conf文件中).但是他不一定确信这个模块被激活或者是禁止在web服务器启动的时候 它通常是将配置信息放在<IfModule>容器内.在没有激活这个模块的时候,它可以允许Apache跳过这个配置容器.

<IfModule mod_security.c>
# mod_security configuration directives

# ...
</IfModule>

自从Apache允许将一组配置数据保存在一个(例如modsecurity.conf)配置文件中,然后被httpd.conf 使用Include 方法调用.:

 

Include conf/modsecurity.conf

关闭和开启过滤

过滤引擎缺省是关闭的。需要开启请求的监视的话,可以把这个指示加入配置文件中:

SetFilterEngine On

这个参数支持的值包括:

On - 分析每个请求

Off - 无动作

DynamicOnly - 只分析运行时动态生成的请求。使用这个选项可以防止Web服务器使用宝贵的CPU资源检查对静态文件的请求。希望了解ModSecurity如何判断哪些请求是动态生成的,可以参考“选择日志中记录什么”。

 

POST扫描

请求体的有效载荷(或者POST有效载荷)扫描缺省是禁止的。需要使用的话,需要手工打开:

SetFilterScanPOST On

mod_security 对请求体支持两种编码方式:

application/x-www-form-urlencoded - 用来传输表单数据

multipart/form-data - 用于文件传输

 

其他的编码没有被大多数web应用程序用到。为保证只有使用这两种编码方式的请求被web服务器接受,需要在配置文件中加入下列行

SecFilterSelective HTTP_Content-Type \

"!(^$|^application/x-www-form-urlencoded$|^multipart/formdata;)"

 

动态关闭缓存

可以关闭基于每个request的POST有效载荷扫描。如果环境变量MODSEC_NOPOSTBUFFERING被定义,ModSecurity不会进行POST有效载荷扫描。例如,要关闭文件上传的POST有效载荷的缓存,可以:

SetEnvIfNoCase Content-Type \

"^multipart/form-data;" "MODSEC_NOPOSTBUFFERING=Do not buffer

file uploads"

 

对变量MODSEC_NOPOSTBUFFERING的赋值会写在debug日志里,因此可以在这里记录你关闭缓存的原因。

 

块状传输编码

HTTP协议支持一种在事先不知道有效载荷大小的情况下传输请求的方法。请求体会包装成大小固定的块传输。这就是“块状传输编码”名字的由来。ModSecurity目前不支持分快请求。当一个请求按块状编码的时候,它的请求体会被忽略。到目前我所知的浏览器还没有使用块状编码来传输请求的。尽管Apache对某些操作支持这种编码,很多模块并不支持。

如果不加注意,这可能会为攻击者提供机会来散布恶意的有效载荷。可以在配置文件中加入下面这行来阻止攻击者利用这个漏斗:

SecFilterSelective HTTP_Transfer-Encoding "!^$"

 

这个改动不会影响使用块状传输编码来发送反馈。

 

缺省动作列表

只要一个请求能够匹配条规则,一个或多个动作就会发生。每个单独的过滤器都可以有自己的动作,但是为所有的过滤器定义一套缺省的动作会更方便。(如果需要你总可以定义pre-rule动作。)你可以用SecFilterDefaultAction这个配置指示来定义缺省动作。比如,下面这句会配置引擎使之记录每一条匹配的规则,然后用状态码404来拒绝请求:

SecFilterDefaultAction "deny,log,status:404"

SecFilterDefaultAction指示值接受一个参数,一个逗号分隔的动作列表。在这里指定的动作会作用在每一个匹配的过滤器上,除非这个规则自己已经定义了自己的动作列表。

 

1.8.6中,如果你指定了一个非致命的缺省动作列表(一个不会导致请求被拒绝的类表,比如log, pass)这样的列表在初始化阶段会被忽略。初始化阶段是被设计用来收集请求的信息的。允许非致命的动作会导致请求的部分的某些片断的丢失。因为这些信息在内部处理的时候是必需的,这样的动作不被允许。如果你希望ModeSecurity在“监测”模式下工作,需要禁止所有的隐式校验(URL编码校验,Unicode编码校验,cookie格式校验,字节范围限制)。

 

隐式校验

1.8.6中,隐式请求校验(如果配置了的话)只在请求处理开始阶段被采用。在那之后,只有标准化动作会被采用。这个修改允许更好的防护(请求报头现在会在开始时被自动检查)。同时允许“监测”模式的规则。

 

过滤器的继承

在父目录中定义的过滤器通常会被嵌套的Apache配置所继承。这个行为通常是可接受的(而且是必需的)。但并不总是这样。有时候你需要在网站的某些部分放松检查。使用SecFilterInheritance指示

SecFilterInheritance Off

可以通知ModeSecurity来忽视父过滤器这样你可以从报头开始定义规则。这个指示只影响规则。配置总是从父上下文中继承,但是你可以使用合适的配置指示来覆盖继承来的设置。

配置和规则的继承缺省总是激活的。如果你在一个禁止的继承的配置上下文下面有另一配置上下文,你需要继续禁止继承,那么必须显式的再禁止一次。

URL编码校验

特殊字符在通过URL传输之前需要被编码。任何一个字符都可以用%XY这种方式来编码。XY是一个十六进制的字符编码(参考http://www.rfc-editor.org/rfc/rfc1738.txt获得更多细节)十六进制数字只允许字母AF,但是攻击者有时使用其他字母来欺骗解码算法。ModSecurity检查所有的编码,校验他们是否合法。

你可以通过下列方法打开URL编码校验功能:

SecFilterCheckURLEncoding On

在使用multipart/form-data编码(文件上传)的时候,这个指示并不检查POST的有效载荷。因为URL编码不在这种编码中使用,所以这样做不是必要的。

 

Unicode编码校验

和其他很多的特性一样,Unicode编码校验缺省是禁止的。如果你的应用程序或是操作系统接受/理解Unicode,你应该开启这个选项。

 

关于UnicodeUTF-8编码的更多细节可以在RFC2279http://www.ietf.org/rfc/rfc2279.txt)中找到。

 

SecFilterCheckUnicodeEncoding On

这个特性假定使用的是UTF-8编码并检查3种类型的错误:

缺失字节。 UTF-8支持2字节到6字节的编码。ModeSecurity可以定位一个或多个字节的缺失。

非法编码。大多数字符中的两个最重要的位被假定固定为0x80。攻击者利用这个来破坏Unicode解码器。

超长字符。ASCII字符可以直接映射到Unicode编码空间中,表示成单个字符。但是,多数的ASCII字符以可以表示成2到6个字符。这样可以欺骗解码器使之误认为这个字符是其他的字符(从而躲过安全检查)。

 

字节范围检查

你可以强制要求HTTP请求中只包含某个特定字节范围内的字节。这对防止溢出攻击是有用的(因为他们通常包含一些“随机”的二进制内容)。

可以用下列指示,限制字节范围从32到126(包含这两个边界值):

SecFilterForceByteRange 32 126

缺省的范围值是0到255,也就是所有的字节值都是被允许的。

 

文本框: 当使用multipart/form-data编码(上传文件)的时候,这个指示不检查POST有效载荷中的字节范围。否则会阻止二进制文件的上传。但是当参数被从这样的请求中提取出来的时候,会被检查是否在合法的范围内。

允许其他人看到ModSecurity

通常攻击者无法分辨出是否web server在运行mod_security。你可以通过发送特殊信息或者使用不寻常的HTTP代码(比如406)来出卖你自己。如果希望保持隐藏状态,那么最好是发送返回码500,意思是“Internal Server Error”。收到这个返回值的攻击者通常会认为你的应用程序已经垮掉了。因为脆弱的应用程序在遇到意料外的输入的时候经常会垮掉,ModSecutiry仍然激活这件事情对于攻击者来说仍然是不可见的。

在这个问题上有另外一派人认为,你不应该隐藏你在使用ModeSecurity的事实。理论是如果攻击者看到这个的话,会了解你已经下了功夫,攻击会变得非常困难。这样他们就会离开去寻找更脆弱些的目标。或者可能他们会觉得更有挑战性,从而更坚定的攻击。

缺省情况下Apache会对每个请求返回自身的信息。ModSecurity会保持沉默(这是推荐的状态)。但是你可以通过加上下面这行来让其他人看到ModeSecurity:

SecServerResponseToken On

结果会大概是这个样子:

[ivanr@wkx conf]$ telnet 0 8080

Trying 0.0.0.0...

Connected to 0.

Escape character is '^]'.

GET / HTTP/1.0

HTTP/1.1 406 Not Acceptable

Date: Mon, 19 May 2003 18:13:51 GMT

Server: Apache/2.0.45 (Unix) mod_security/1.5

Content-Length: 351

Connection: close

Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">

<html><head>

<title>406 Not Acceptable</title>

</head><body>

<h1>Not Acceptable</h1>

<p>An appropriate representation of the requested resource /

could not be found on this server.</p>

<hr />

<address>Apache/2.0.45 (Unix) mod_security/1.4.2 Server at

wkx.dyndns.org Port 80</address>

</body></html>

Connection closed by foreign host.

 

你应该注意Apache本身支持两个运行时指示:ServerTokensServerSignature。使用这些指示你可以彻底隐藏你的服务器的消息,无论ModSecurity是如何配置的。