IIS 架构解析
我们在使用ASP.NET平台做web开发的时候,经常会接触到IIS(Internet Information Services 互联网信息服务)。这篇文章主要来介绍IIS7.0+的架构。IIS的安全脆弱性曾长时间被业内诟病,一旦IIS出现远程执行漏洞威胁将会非常严重。远程执行代码漏洞存在于 HTTP 协议堆栈 (HTTP.sys) 中,当 HTTP.sys 未正确分析经特殊设计的 HTTP 请求时会导致此漏洞。 成功利用此漏洞的攻击者可以在系统帐户的上下文中执行任意代码,可以导致IIS服务器所在机器蓝屏或读取其内存中的机密数据。微软的技术更新相对较快,IIS7相比较之前的IIS5,IIS6有了很大的改进,解决了IIS5的一些不足,也使用了一些新的结构来提升了性能和安全性。
Internet Information Services(IIS)7及以后的版本提供了一套请求处理机制主要又三大功能:
1.Windows Process Activation Service(WAS),Windows进程激活服务,主要用来支持HTTP/HTTPS之外的控制协议。
2.一个可以通过增加/删除模块来自定义的引擎。
3.集成了IIS和ASP.NET的请求处理管道。
我们主要通过以下及部分来分解IIS的结构:
* IIS的组成组件
* 协议监听器
* 超文本传输协议堆栈(HTTP.sys)
* Word Wide Web Publishing Service(www Service)
* IIS 模块化
* 本地化模块
* 托管模块
* IIS中请求的处理
* IIS中的应用程序池
* IIS中HTTP请求的处理
1. IIS 的组成组件
在Windows Server® 2008 (IIS 7.0) 和Windows Server 2008 R2 (IIS 7.5)中IIS包含了很多的组件来完成应用程序和Web server的重要功能。每一个组件都有自己的职责,比如请求的监听、进程的管理、配置文件的读取等等。这些组件主要包括以下三个:
* 协议侦听器(protocol listeners) 比如 HTTP.sys
* 服务组件 比如www service(World Wide Web Publishing Service)
* Windows 进程激活服务(Windows Process Activation Service WAS).
后面我们会对这些相关的组件做一些说明。
2.协议监听器
模块名称 | 描述 | 资源 |
CustomErrorModule | 错误状态代码设置响应时,发送默认或已配置的 HTTP 错误消息。 | Inetsrv\Custerr.dll |
HttpRedirectionModule | 支持可配置重定向的 HTTP 请求。 | Inetsrv\Redirect.dll |
ProtocolSupportModule | 执行相关协议的操作,例如设置基于配置的响应标头和重定向标头。 | Inetsrv\Protsup.dll |
RequestFilteringModule | 在 IIS 7.5 中。筛选器请求,当配置为控制协议和内容的行为。 | Inetsrv\modrqflt.dll |
WebDAVModule | 在 IIS 7.5 中。通过在 SSL 上使用 HTTP 发布更安全的内容。 | Inetsrv\WebDAV.dll |
安全模块:
在 IIS 中的几个模块执行请求处理管线中的安全相关的任务。除此之外,每个验证机制都有独立的模块,可供你自己选择自己需要的验证模块。还有一些模块用来过滤请求和URL授权。
模块名称 | 描述 | 资源 |
AnonymousAuthenticationModule | 当没有其他身份验证方法时,执行匿名身份验证。 | Inetsrv\Authanon.dll |
BasicAuthenticationModule | 执行基本身份验证。 | Inetsrv\Authbas.dll |
CertificateMappingAuthenticationModule | 使用 Active Directory 执行证书映射身份验证。 | Inetsrv\Authcert.dll |
DigestAuthenticationModule | 执行摘要式身份验证。 | Inetsrv\Authmd5.dll |
IISCertificateMappingAuthenticationModule | 使用 IIS 证书配置执行证书映射身份验证 | Inetsrv\Authmap.dll |
RequestFilteringModule | 执行 URLScan 任务,如配置允许的动作和文件扩展名、 设置限制、 和扫描坏字符序列。 | Inetsrv\Modrqflt.dll |
UrlAuthorizationModule | 执行 URL 授权。 | Inetsrv\Urlauthz.dll |
WindowsAuthenticationModule | 执行 NTLM 集成的身份验证。 | Inetsrv\Authsspi.dll |
IpRestrictionModule | 限制了 IPv4 地址在配置 ip 安全列表中列出。 | Inetsrv\iprestr.dll |
内容模块:
在 IIS 中的几个模块执行请求处理管道中的内容相关的任务。内容模块包括模块来处理请求的静态文件,当客户端没有指定具体页面时,以返回一个默认的页面,列出一个目录,和更多的内容中指定的资源。
模块名称 | 描述 | 资源 |
CgiModule | 执行通用网关接口 (CGI) 进程,打造响应输出。 | Inetsrv\Cgi.dll |
DefaultDocumentModule | 尝试返回的请求到父目录的默认文档。 | Inetsrv\Defdoc.dll |
DirectoryListingModule | 列出目录的内容。 | Inetsrv\dirlist.dll |
IsapiModule | 主机 ISAPI 扩展 Dll。 | Inetsrv\Isapi.dll |
IsapiFilterModule | 支持 ISAPI 筛选器 Dll。 | Inetsrv\Filter.dll |
ServerSideIncludeModule | 处理服务器端包含的代码。 | Inetsrv\Iis_ssi.dll |
StaticFileModule | 提供静态文件。 | Inetsrv\Static.dll |
FastCgiModule | 支持 FastCGI,提供更高的性能替代 CGI。 | Inetsrv\iisfcgi.dll |
压缩模块:
在 IIS 中的两个模块在请求处理管道中执行压缩。
模块名称 | 描述 | 资源 |
DynamicCompressionModule | 压缩的响应和适用 Gzip 压缩传输响应编码。 | Inetsrv\Compdyn.dll |
StaticCompressionModule | 静态内容执行预压缩 | Inetsrv\Compstat.dll |
缓存模块:
网站或应用程序中通过存储网页之类的处理信息来提高性能和可重用性。
模块名称 | 描述 | 资源 |
FileCacheModule | 提供用户模式缓存的文件和文件句柄。 | Inetsrv\Cachfile.dll |
HTTPCacheModule | 在 HTTP.sys 中提供内核模式和用户模式缓存。 | Inetsrv\Cachhttp.dll |
TokenCacheModule | 提供用户模式缓存的用户名称和令牌对用于生成 Windows 用户主体的模块。 | Inetsrv\Cachtokn.dll |
UriCacheModule | 提供用户模式缓存的 URL 的信息。 | Inetsrv\Cachuri.dll |
日志记录和诊断模块:
日志记录模块支持加载自定义模块,并将信息传递给HTTP.SYS.诊断模块用来在处理请求过程中关注和报告事件。
模块名称 | 描述 | 资源 |
CustomLoggingModule | 装载用户定义日志模块 | Inetsrv\Logcust.dll |
FailedRequestsTracingModule | 支持请求失败跟踪 | Inetsrv\Iisfreb.dll |
HttpLoggingModule | 传递信息和请求处理状态到HTTP.SYS作为日志 | Inetsrv\Loghttp.dll |
RequestMonitorModule | 跟踪请求在工作进程中的执行信息,报告运行时的状态和控制应用程序接口 | Inetsrv\Iisreqs.dll |
TracingModule | 事件报告给 Microsoft 跟踪 Windows 事件 (ETW)。 | Inetsrv\Iisetw.dll |
托管支持模块:
模块名称 | 描述 | 资源 |
ManagedEngine | 提供集成的 IIS 请求处理管线中的托管的代码模块。 | Microsoft.NET\Framework\v2.0.50727\webengine.dll |
ConfigurationValidationModule | system.web验证配置的问题,例如当应用程序以集成模式运行,但已处理程序或模块中的声明。 | Inetsrv\validcfg.dll |
7.托管模块
除了本地化模块以外,IIS允许你使用托管代码模块来扩展IIS功能。部分托管模块,比如UrlAuthorization,有一个相对应的本地化模块来替换托管模块。
值得注意的是托管模块依赖于ManagedEngine模块。下面列出了完整的IIS7的托管模块,有关托管模块的详细信息请参阅MSDN上的.NET框架2.0.
模块名称 | 描述 | 资源 |
AnonymousIdentification | 管理由支持匿名标识如 ASP.NET 配置文件功能使用的匿名标识符 | System.Web.Security.AnonymousIdentificationModule |
DefaultAuthentication | 确保身份验证对象是存在于上下文。 | System.Web.Security.DefaultAuthenticationModule |
FileAuthorization | 验证用户具有访问所请求的文件的权限。 | System.Web.Security.FileAuthorizationModule |
FormsAuthentication | 通过使用窗体身份验证支持的身份验证 | System.Web.Security.FormsAuthenticationModule |
OutputCache | 支持输出缓存 | System.Web.Caching.OutputCacheModule |
Profile | 通过使用ASP.NET身份来管理用户简历,从数据库存储和获取数据源 | System.Web.Profile.ProfileModule |
RoleManager | 管理当前用户的角色 | System.Web.Security.RoleManagerModule |
Session | 支持维护session状态,允许存储的信息输出到指定的客户端 | System.Web.SessionState.SessionStateModule |
UrlAuthorization | 基于用户名和权限列表决定当前用户是否有权限访问URL | System.Web.Security.UrlAuthorizationModule |
UrlMappingsModule | 支持真实的URL映射到一个用户友好的URL | System.Web.UrlMappingsModule |
WindowsAuthentication | 启用windows授权就可以设置ASP.NET用户认证 | System.Web.Security.WindowsAuthenticationModule |
8.IIS中请求的处理
在IIS7中,IIS和ASP.NET请求管道通过集成方式组合来处理I请求。新的请求架构包括执行特定的任务以响应请求的本地化和托管模块列表。这种设计相对于以前的版本有以下几大好处:
* 所有的文件类型可以使用最初仅提供给托管代码的功能。比如你现在可以为静态页面,活动服务器页面以及你的网站和应用程序中其他类型的文件使用ASP.NET Form身份认证和统一资源定位器授权。
*这种设计消除了IIS和ASP.NET中相互重复的几个功能。比如:当客户端请求一个托管文件时,服务器在集成管道中通过调用适当的认证模块来对客户端进行认证。但是在之前的IIS版本中,这种授权会在IIS和ASP.NET中都进行验证。
*你可以在同一个地方管理所有的模块,而不是去管理一部分在IIS里配置一部分在ASP.NET里的配置。这简化了站点和应用程序服务器上的管理。
9.在IIS中的应用程序池
应用程序池通过进程边界来分割应用程序来阻止服务器上的应用程序之间的相互干扰。IIS7继续沿用IIS6的工作进程隔离模式。此外,你现在可以指定一个设置来决定如何处理托管资源请求:集成模式和经典模式。
IIS6和IIS5的工作进程隔离模式是在服务器层级设置的。这就不可能允许两个隔离模(集成和经典)式在同一台服务器上运行。然而在IIS7集成模式和经典模式是在应用程序池级别来设置的。这就允许在同一台服务器上同时运行不同隔离模式的应用程序。
集成应用程序池模式:
当应用程序池是在集成模式下时,您可以利用 IIS 和 ASP.NET 的集成请求处理体系结构。在应用程序池中的工作进程接收请求时,该请求将经历事件的排序列表。每个事件调用的请求和生成响应的过程部分必要的本机和托管模块。在集成模式下运行应用程序池有几个好处。首先, IIS 和 ASP.NET 的请求处理模型被集成到统一的过程模型。这个模型消除了先前重复的 IIS 和 ASP.NET功能,如身份验证的步骤。另外,集成的模式使托管功能对所有内容类型的可用性。
经典应用程序池模式:
当一个应用程序池是经典模式的时候,IIS7处理请求的工作进程隔离模式和IIS6的处理方式是一样的。ASP.NET 请求首先通过在 IIS 中的本机处理步骤,然后将其路由到 Aspnet_isapi.dll 处理的托管运行时中的托管代码。最后,请求被路由通过 IIS 将响应发送回。这种 IIS 和 ASP.NET 请求处理模型的分离导致工作重复,一些处理步骤,如身份验证和授权。另外,托管的代码的功能,如窗体身份验证,只可用于 ASP.NET 应用程序或您有脚本的应用程序映射由 aspnet_isapi.dll 处理的所有请求。
一定要在升级到 IIS 7 及更高版本的生产环境和分配到应用程序池在集成模式下的应用程序之前在集成模式下测试您现有的应用程序的兼容性。如果应用程序将无法在集成模式下工作,只应在经典模式下添加到应用程序池的应用程序。例如,您的应用程序可能会依赖于从 IIS 传递到托管运行时,身份验证令牌和 IIS 7 和后来的新体系结构,由于进程中断您的应用程序。
10.在IIS中处理HTTP请求
下面的列表描述了请求处理流程:
1.当客户端发起你个面向服务器的http请求后,HTTP.sys截获该请求。
2.HTTP.sys通知WAS从配置文件中获取必要的信息。
3.WAS从applicationHost.config文件中请求配置信息。
4.W3SVC接收到相应的配置信息:应用程序池,网站配置等信息。
5.W3SVC使用配置信息来配置HTTP.sys.
6.WAS为请求隔离模式相匹配的应用程序池开启一个工作进程。
7.工作进程处理请求并且返回响应给HTTP.sys.
8.客户端接收响应。
总的请求过程如下图:
在工作过程中,在 Web 服务器核心,HTTP 请求通过几个有序的步骤,称为事间。在每个事件,本机模块处理请求,如用户进行身份验证或将信息添加到事件日志的一部分。如果请求需要一个托管的模块,本机 ManagedEngine 模块创建的 AppDomain,那里托管的模块可以执行进行必要的处理,如使用 Forms 身份验证的用户进行身份验证。当请求穿过所有的 Web 服务器核心事件时,到 HTTP.sys 会返回的响应。图 2 所示输入辅助进程的 HTTP 请求。
关于每个事件的作用感兴趣的同学可以自行研究。这里我们整个IIS的结构就全部结束了。