关于iis filter(筛选器)的总结

微软IIS的ISAPI筛选器权限法则

前言:
微软IIS中的ISAPI其实是个对于很多人都很陌生的东西,这个东西几乎控制着IIS中一切动态内容的生命,因为只有ISAPI,才可以让你的动态内容交互式网页(如ASPX/PHP等),因为ISAPI的高安全性、速度快,许多使用Windows Sever系统的网站在使用IIS时都选择了ISAPI而抛弃了笨拙的CGI模式。今天就给大家说一说IIS中ISAPI的种种法则。

ISAPI简介:
ISAPI其实通俗理解就是控制IIS显示动态交互式内容的一个“漏斗”,只有用户许可的动态内容(多数是指一种动态语言)才可以从这个漏斗流下,并提供给访问者。这个漏斗在IIS中被叫做“ISAPI筛选器”。

种种法则:
现在就开始讲一下ISAPI的权限法则,这或许可以帮助有些站长尽快配置好自己的IIS。
尽管ISAPI是控制内容显示的,但是在Windows Sever 2003版本中,用户在ISAPI筛选器中所指定ISAPI链接库不能直接调用解析用户请求的动态内容。
例如:
现在这里有一个动态内容网页AC.PHP,用户现在请求该文件,但是却返回“无法找到文件或目录”的错误,其实并不是没有找到文件,而是PHP文件解析所用到的ISAPI文件(如PHP5ISAPI.DLL)并没有正确被加载(在ISAPI筛选器显示为红箭头以及“未加载”)。

到这里很多人就不知道该如何做了,其实这个出错的原因是导致该ISAPI文件没有权限而无法运行造成的,只要把权限基于这个ISAPI链接库,就可以正常运行了。
如何解决这一问题,如果你在使用IIS 6.0版本,你真够幸运的,你可以在这个版本中轻易解决这个问题,以下是我总结的方案:

1.首先确定权限的限制是由两部分造成的:系统文件权限以及服务器扩展权限,首先来到这个ISAPI链接库文件所在的地方,之后给予这个文件EveryOne的完全控制权限(你也可以选择读取+写入+执行的权限组合)。
2.解决服务器扩展权限:来到IIS6.0的“服务器扩展”设置页面,如果你想图省事,可以直接点击“允许所有的未知ISAPI”的按钮,但我并不推荐这样做,这样太不安全了!我们在此应当添加一个新的服务器扩展,扩展名你可以随便填,文件就选择到那个ISAPI链接库文件上,然后勾选“将状态设置为允许”后,保存。
3.为了使设置生效,请重启系统,重启后你的ISAPI扩展就可以正常加载了!

加载筛选器,无箭头

当一个 ISAPI 筛选器添加到 IIS 6.0 上网站时,该筛选器在 IIS Microsoft 管理控制台 (MMC) 中的状态列为空。 直到向站点发出请求时并试图加载筛选器之前,筛选器的状态都是未知的。 只有当你向站点发出请求,才能确定该筛选器的状态。此时如果未加载该筛选器,在 IIS MMC 中会出现一个红色箭头,如果加载,会显示一个绿色箭头。来自MSDN.

ISAPI Filter 安装常见错误
HOWTO: Diagnose and Fix Common ISAPI Filter Installation Failures
首先,你确定了解ISAPI Filter 的以下方面:

你已经有一个ISAPI Filter DLL ,无论你是自己编译/连接而成,还是直接得到一个现成的dll.

你知道这个筛选器是网站级别的还是全局级别的;
全局筛选器,需要重启IIS才能加载;站点级别,IIS6,会在第一个网站的请求到达时加载。以前的IIS版本,会立刻加载;
但是,现在筛选器好像没有加载,也不工作:

 在IIS6,加载/运行筛选器失败导致启动网站失败,也就是说出现了"503 Service Unavailable" 错误;
IIS以前的版本,加载/运行筛选器失败会被 IIS忽略,所以只是有请求时筛选器不起作用;
当你安装筛选器,遇到以上情况时,最好的解决方法就是去Windows事件日志找错误原因:选择日志来源为W3SVC 或 W3SVC-WP ,关于加载 HTTP Filter DLL失败的日志;日志的数据一项是诊断筛选器加载出错的最重要的信息来源。

以下是常见的错误和解决方法:

Data: 02 00 00 00
Win32 error 2 - NET HELPMSG 2 returns "The system cannot find the file specified."

Win32 error 2 -系统不能找到指定的文件

IIS6,IIS加载一个 ISAPI Filter,无论它是站点级别还是全局的,这个 ISAPI Filter所指定的路径下的相应的dll不存在;
IIS6以前的版本,这种错误不会出现,因为这种情况会被IIS忽略;但是IIS6认为这种无效的路径指定对网站是严重的错误,所以筛选器加载失败会导致503 Service Unavailable error的错误;
解决方法:首先,确定ISAPI Filter 是否对于站点是必须的;如果不是,可以删除此筛选器;如果必须,将dll放到指定路径下,或者修改路径为dll所在路径即可;
Data: 05 00 00 00
Win32 error 5 - NET HELPMSG 5 returns "Access is denied."

Win32 error 5 -拒绝访问,没有访问权限

因为 IIS是通过进程来加载和运行ISAPI Filter的,也就是说这个进程的身份没有权限访问ISAPI Filter DLL文件; IIS6 ,以隔离模式运行时,进程的身份是可以修改的,它至少是IIS_WPG 组中的一个成员;对于IIS6以非隔离模式运行, 或者以前的IIS版本,进程的身份是 Local System。所以检查ISAPI Filter DLL的权限,是否不允许进程身份的用户访问;
ISAPI Filter DLL的GetFilterVersion() 函数返回FALSE,出错原因:GetLastError() 返回ERROR_ACCESS_DENIED。拒绝访问的原因与你自己写得筛选器内部实现有关系。比如说:筛选器试图读/写一个注册表项,或者文件;因为IIS6的进程身份默认没有很高的权限,所以可能会导致ERROR_ACCESS_DENIED错误,所以筛选器返回FALSE。
Data: 7E 00 00 00
Win32 error 126 - NET HELPMSG 126 returns "The specified module could not be found."

Win32 error 126 - 没有找到指定的库

 ISAPI Filter DLL链接到站点上没有的资源。
一个常见的错误:你的dll是DEBUG版本的,但是在服务器上没有相关的DEBUG信息(DEBUG CRT/ATL/MFC );这些信息是Visual Studio安装的,所以可能你的筛选器再你自己的机器上运行良好,但是在别的服务器上却出错了。
另一个常见的错误是你的dll链接到一个比较新版的CRT/ATL/MFC DLLs ,在目标机器上没有这个库;比如,你的dll是在Visual Studio .NET 下编写的,用新版本的mfc的库,但是目标机器上的版本太旧,所以导致在你的机器上能运行的程序在别的机器上不能正常运行。
解决方案:用.NET自带的工具DEPENDS.EXE ,来查看你所编写的dll连接的库文件,它会告诉你那个dll找不到(红色显示);只要保证你写的dll程序所链接到dll库在目标机器上都有就可以正常运行了
Data: 7F 00 00 00
Win32 error 127 - NET HELPMSG 127 returns "The specified procedure could not be found."

Win32 error 127 - 没有找到指定的函数

为了加载筛选器,你需要导出一些函数供IIS调用,你至少要导出的函数有:GetFilterVersion 和 HttpFilterProc (TerminateFilter 可选)。使用MS LINK.EXE工具,你可以通过编写.DEF文件来指定导出的函数,文件内容如下:
LIBRARY MyFilterNameEXPORTS    GetFilterVersion    HttpFilterProc如果你的 ISAPI DLL 调用了一个系统的 API函数,而不幸的是这个函数在目标机器上不存在,这种情况的时候你会得到这种错误,这种错误十分隐蔽,因为你可以成功的编译连接生成dll,但是在没有指定API的系统上,筛选器会加载失败。比如:你的筛选器中用到了 RegGetValue() 这个API函数,而这个函数是在 安装了 Windows Server SP1 (所有平台) 或者 XP Pro x64的机器上才有,你下载并且安装最新的Microsoft Platform SDK,里面有 advapi32.lib 以及头文件。然后就可以运行了。你如果尝试在旧版的 advapi32.dll 上运行,由于不支持RegGetValue(). ,所以会得到127的错误。因为你的dll要调用的函数在目标机器上不存在。
解决方案:使用目标机上存在的API,这是为什么有些代码可以编译但是不能运行的原因之一。

Data: Arbitrary Value

用日志中的数据一项可以比较准确的知道你的筛选器为什么安装失败,或者不能运行。 ISAPI Filter DLL 可以记录任何错误数据的日志,很可能是与我上面提的那些无关的数据。

IIS加载并且初期化筛选器:通过调用LoadLibrary() 来调用指定路径下的 dll,然后确定GetFilterVersion()和  HttpFilterProc() 的入口地址确实存在(即被导出了),最后调用GetFilterVersion() 函数初期化筛选器,如果返回FALSE,IIS会记录错误日志: "HTTP Filter failed to load" ,数据项为GetLastError() 的返回值。
也就是说,ISAPI Filter 会产生一个日志,如果成功或者失败--失败的原因就是日志中数据那一项。
没时间检查了,可能会有错误,原文地址:

http://blogs.msdn.com/david.wang/archive/2005/06/21/HOWTO-Diagnose-and-Fix-Common-ISAPI-Filter-Installation-Failures.aspx

最后说一下,我遇到的问题:

1)我的筛选器是写log文件的,但是一直没有log文件生成,我在日志中也没有找到相关的iis日志记录,后来发现是写log的文件夹权限设置问题,给IIS_WPG组加上写权限就可以了。至于为啥没有日志呢,我也不大清楚了。

2)筛选器本身的dll文件权限设置不对,原来只有管理员有权限,给everyone加上访问权限后,问题解决。

本文来自租赁宝网技术支持,参考网站:http://www.zulinbao.com 

原文地址:https://www.cnblogs.com/systemxgl/p/1940974.html