Copyright © 2002-2005 Ivan Ristic <[email protected]> http://www.modsecurity.org
中文版: 我爱臭豆腐,sakulagi,Alan.Jin http://www.chinaunix.net
中文版备注:
随着使用apache得人越来越多,和使用web服务得广泛.web服务器得安全问题也是一个至关重要得问题.但是在国内真正能够做web服务安全得感觉并不是很多(实际上也有很多是抄袭免费软件的概念和技术).而且即使是有得话相对来讲成本也是很高的.所以我希望能够找到一个价格相对低廉而且又有效的方法来防护web服务的安全.
当初打算翻译这个的另外一个原因是,经常浏览国外的安全方面的网站和一些外国站点.发现在apache上面安装ModSecurity 或者是介绍web安全的人100%或者是说99.99%都在介绍和使用这个插件.但是在国内的资料上面并没有看到这些东西或者是一带而过了.我本人外语不好当然了中文的水平也不好.但是我想这么好的一个软件应该叫更多的人熟悉和了解.我希望以后在有朝一日能够叫每个apache的服务器都安装这个插件用来抵御来自界的攻击.但是这个只是一个理想或者是梦想.
这里要非常感谢sakulagi,Alan.Jin 他们两个人的外语都比我好.特别是sakulagi 英文水平和中文水平都很好.如果大家要感谢的话应该是多感谢他们.我只是想他们两个人推荐这里这个软件和引入了要翻译这个手册的想法.
最后想说的是安装了这个软件并不是一个大力丸能够防止任何攻击和渗透.任何软件和工具都不是无敌的.都是需要管理员精心的配置和发挥他的最大的功效.
Modsecurity 是一个开放原代码的入侵检测和防护引擎,用来保护Web应用程序.他同样和可以当作一个Web应用程序防火墙.它嵌入到Web服务器中,担当一个强大的保护伞-保护来自应用程序的攻击.
ModSecurity 和web服务器结合,增强web服务器抗攻击的能力.一些只得关注的功能说明:
l 过滤请求:在web服务器或者其他模块获得handled之前, 按照原来的样子分析进入的请求.(严格的说,在这种嵌入式的操作里面,有一些操作在没有到达ModSecurity之前不可避免的进行了一些操作.)
l Anti-evasion 技术: paths and parameters are normalised before analysis takes place in order to fight evasion techniques.
l 了解HTTP协议:引擎获得了http的协议后,将进行非常详细的颗粒过滤.例如,它可以查看任何一个单独的参数,或者是制定的cookie值.
l POST 有效负载分析:这个引擎能够截取传送的内容使用POST方法.
l 审计记录:能够详细的记录每一个请求(包括POST)可以被用在法律分析上.
l HTTPS 过滤:当这个引擎被嵌入到web服务器中后,可以有权访问解密后的数据请求.
l 过滤被压缩的内容:和上面一样,安全引擎可以有权访问到被解压缩后的内容.
ModSecurity 能够被用于发现攻击,或者是发现和阻止攻击.
ModSecurity is available under two licenses. Users can choose to use the software under the terms of the GNU General Public License (http://www.gnu.org/licenses/gpl.html), as an Open Source / Free Software product. Alternatively, a variety of commercial licenses is available: end-user licenses for individual or site-wide deployment, OEM licenses for closed-source distribution with applications, web servers, or security appliances. For more information on commercial licensing please contact Thinking Stone Ltd:
Thinking Stone Ltd
Tel: +44 845 0580628
Fax: +44 870 7623934
http://www.thinkingstone.com
如果是没有这么多好人建立了Apache web服务器,和一些好人花费大量的时间来营造Apache的模块,我将不能经常学习Apache的模块设计.我特别感谢设计和编写mod_rewrite.的人们.
ModSecurity 的开发是由Ivan Ristic 和 Thinking Stone.欢迎注释和重要反馈.请发邮件到[email protected]
备注:
请不要发给我关于技术问题的邮件这个邮件地址是我私人信箱.我不能使用我的私人时间来处理这些技术问题.用户自己可以从mail archives寻找答案.如果你需要快速的回答问题和你想保证反映时间请考虑从Thinking Stone公司购买商业服务.
在你安装之前你需要选择适合你自己的安装方法.第一你需要选择是否安装最新的版本从ModSecurity 的CVS目录当中(里面有最新的特性,但是不稳定).或者是安装最新的稳定版本(推荐).如果你选择稳定版的话,你可以安装ModSecurity 的二进制文件.它已经被从原代码编译完成.
下面的一些内容可以帮助你更好的选择一个适合自己的方法来安装它.
如果你想要最新版本的模块话可以从CVS库中得到.可以从一个web站点获得从最近的一个稳定版本的被改变的列表(在CHANGES这个文件中).ModSecurity 的CVS库存放在SourceForge(http://www.sf.net).你可以直接通过这个地址访问和查看http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/mod-security/.
下载源程序到你的计算机.需要执行下面两个命令:
cvs -d:pserver:[email protected]:/cvsroot/mod-
security login
cvs -z3 -d:pserver:[email protected]:/cvsroot/mod-
security co mod_security
第一行是你使用anonymouse用户登陆,第二行是下载全部的可用的文件从CVS库中.
如果是不喜欢CVS,但是你还想要最新的版本你可以下载最新的nightly tar包从下面的地址:
http://www.modsecurity.org/download/snapshot/mod_security-snapshot.tar.gz 新功能被一一的加入到了mod_security中,用来测试在每一次改变之后.这方法可以确保从CVS上面有永远可用的版本下载.
可以从http://www.modsecurity.org/download/ 下载到稳定的版本.如果你不下载源代码分发的版本时.不时的可以有一些二进制的分发.如果有他们在下载页面的列表上.
从源程序安装有两个方法:一个是将模块和web 服务器编译到一起去.或者是编译mod_security.c 成动态共享对象(DSO).
DSO安装方法非常容易,安装方法有两种流派在Apache的安装方法中.第一要解压缩文件到一个地方(必须要作的),编译模块的命令:
/apachehome/bin/apxs -cia mod_security.c
在这之后你需要关闭和从新启动Apache 服务(如果你尝试从新启动它你可能会segfault)
/apachehome/bin/apachectl stop
/apachehome/bin/apachectl start
我知道有一些人使用的平台上没有apxs这个工具安装到系统上.这个工具在一些Unix的平台上的版本是独立的包.这个问题出现在安装的时候不是缺省安装.解决这个问题的方法是从你的软件厂商那里查找如何建立自定义的Apache模块.(在一些RedHat 平台上你需要安装http-devel 包后就有了apxs这个应用程序).
在静态的编译模块时,这个程序将被内置到web服务器本身.这种方法能够快一点的执行但是这个编译方法有更多的难度(以后的维护).
释放这个软件包后将mod_security.c 这个文件复制到Apache源代码目录src/modeules/extra 中.
更改configureation 脚本激活这个新模块:
# ./configure \
<your other configuration options here> \
--activate-module=src/modules/extra/mod_security \
-–enable-module=security
正常的编译,安装和启动你的web服务器.
在一些环境下,你想要安装二进制的模块.此刻我只是建立了Windows 二进制版本在下载的地方.在每一个版本中有两个DSO库文件,在每一个主要的Apache的分支中.在这些文件中选择一个适合你的Apache 的版本.参考下列描述:
复制mod_security.so (Unix 系统) 或者mod_security.dll (Windows 系统)到libexec/目录下(这个文件架是Apache 安装的目录,不是源代码目录).添加下面内容到httpd.conf :
LoadModule security_module libexec/mod_security.so
根据你现在的配置文件(你需要确认你的配置文件中模块的加载顺序)他需要使用AddModule 指令来激活模块.指令如下:
AddModule mod_security.c
在大多数的时候他不需要添加这个在配置文件中.但是推荐你将mod_security 加入到最后的module链表中(但是在实际当中,如果你打算使用内部的chroot功能的话必须要添加这个在配置文件中).可以在”在chroot 环境下模块顺序要求(Apache 1.x)”有详细的介绍.
复制mod_security.so (Unix系统)或者mod_security.dl (Windows 系统)到modules/ 目录中(这个目录是Apache 的安装目录,不是源程序目录).添加下来内容到httpd.conf配置文件中.:
LoadModule security_module modules/mod_security.so
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有效载荷)扫描缺省是禁止的。需要使用的话,需要手工打开:
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指示值接受一个参数,一个逗号分隔的动作列表。在这里指定的动作会作用在每一个匹配的过滤器上,除非这个规则自己已经定义了自己的动作列表。
在<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">1.8.6</span></chsdate>中,如果你指定了一个非致命的缺省动作列表(一个不会导致请求被拒绝的类表,比如log, pass)这样的列表在初始化阶段会被忽略。初始化阶段是被设计用来收集请求的信息的。允许非致命的动作会导致请求的部分的某些片断的丢失。因为这些信息在内部处理的时候是必需的,这样的动作不被允许。如果你希望ModeSecurity在“监测”模式下工作,需要禁止所有的隐式校验(URL编码校验,Unicode编码校验,cookie格式校验,字节范围限制)。
在<chsdate w:st="on" isrocdate="False" islunardate="False" day="30" month="12" year="1899"><span lang="EN-US" style="FONT-SIZE: 10pt; FONT-FAMILY: Courier; mso-font-kerning: 0pt; mso-bidi-font-family: Courier">1.8.6</span></chsdate>中,隐式请求校验(如果配置了的话)只在请求处理开始阶段被采用。在那之后,只有标准化动作会被采用。这个修改允许更好的防护(请求报头现在会在开始时被自动检查)。同时允许“监测”模式的规则。
在父目录中定义的过滤器通常会被嵌套的Apache配置所继承。这个行为通常是可接受的(而且是必需的)。但并不总是这样。有时候你需要在网站的某些部分放松检查。使用SecFilterInheritance指示
SecFilterInheritance Off
可以通知ModeSecurity来忽视父过滤器这样你可以从报头开始定义规则。这个指示只影响规则。配置总是从父上下文中继承,但是你可以使用合适的配置指示来覆盖继承来的设置。
配置和规则的继承缺省总是激活的。如果你在一个禁止的继承的配置上下文下面有另一配置上下文,你需要继续禁止继承,那么必须显式的再禁止一次。
特殊字符在通过URL传输之前需要被编码。任何一个字符都可以用%XY这种方式来编码。XY是一个十六进制的字符编码(参考http://www.rfc-editor.org/rfc/rfc1738.txt获得更多细节)十六进制数字只允许字母A到F,但是攻击者有时使用其他字母来欺骗解码算法。ModSecurity检查所有的编码,校验他们是否合法。
你可以通过下列方法打开URL编码校验功能:
SecFilterCheckURLEncoding On
在使用multipart/form-data编码(文件上传)的时候,这个指示并不检查POST的有效载荷。因为URL编码不在这种编码中使用,所以这样做不是必要的。
和其他很多的特性一样,Unicode编码校验缺省是禁止的。如果你的应用程序或是操作系统接受/理解Unicode,你应该开启这个选项。
关于Unicode和UTF-8编码的更多细节可以在RFC2279(http://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,也就是所有的字节值都是被允许的。
<shapetype id="_x0000_t202" path="m,l,21600r21600,l21600,xe" o:spt="202" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><path o:connecttype="rect" gradientshapeok="t"></path></shapetype><shape id="_x0000_s1026" style="MARGIN-TOP: 0px; Z-INDEX: 1; LEFT: 0px; MARGIN-LEFT: 0px; WIDTH: 560.9pt; POSITION: absolute; HEIGHT: 67.95pt; TEXT-ALIGN: left; mso-wrap-style: none; mso-position-horizontal: left" type="#_x0000_t202"><textbox style="mso-next-textbox: #_x0000_s1026; mso-fit-shape-to-text: t"><table cellspacing="0" cellpadding="0" width="100%"><tbody><tr> <td style="BORDER-RIGHT: #d4d0c8; BORDER-TOP: #d4d0c8; BORDER-LEFT: #d4d0c8; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"> <div> <table style="WIDTH: 100%; mso-cellspacing: 0cm; mso-padding-alt: 0cm 0cm 0cm 0cm" cellspacing="0" cellpadding="0" width="100%" border="0" class="MsoNormalTable"><tbody><tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes; mso-yfti-lastrow: yes"> <td style="BORDER-RIGHT: #d4d0c8; PADDING-RIGHT: 0cm; BORDER-TOP: #d4d0c8; PADDING-LEFT: 0cm; PADDING-BOTTOM: 0cm; BORDER-LEFT: #d4d0c8; PADDING-TOP: 0cm; BORDER-BOTTOM: #d4d0c8; BACKGROUND-COLOR: transparent"> <p class="MsoNormal" style="MARGIN: 0cm 91.25pt 0pt 98.8pt; TEXT-ALIGN: left; tab-stops: 522.0pt; mso-para-margin-top: 0cm; mso-para-margin-right: 8.69gd; mso-para-margin-bottom: .0001pt; mso-para-margin-left: 9.41gd; mso-layout-grid-align: none" align="left"><span style="FONT-FAMILY: 新宋体; mso-bidi-font-size: 10.5pt; mso-font-kerning: 0pt; mso-bidi-font-family: Courier"><font size="3">当使用<span lang="EN-US">multipart/form-data</span>编码(上传文件)的时候,这个指示不检查<span lang="EN-US">POST</span>有效载荷中的字节范围。否则会阻止二进制文件的上传。但是当参数被从这样的请求中提取出来的时候,会被检查是否在合法的范围内。<span lang="EN-US"><p></p></span></font></span></p> </td> </tr></tbody></table> <p class="MsoNormal" style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: left; mso-pagination: widow-orphan" align="left"><span lang="EN-US" style="FONT-SIZE: 12pt; FONT-FAMILY: 宋体; mso-font-kerning: 0pt; mso-bidi-font-family: 宋体"><p></p></span></p> </div> </td> </tr></tbody></table></textbox><wrap type="square"></wrap></shape>
<font size=