我们在使用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.协议监听器
安全模块:
在 IIS 中的几个模块执行请求处理管线中的安全相关的任务。除此之外,每个验证机制都有独立的模块,可供你自己选择自己需要的验证模块。还有一些模块用来过滤请求和URL授权。
内容模块:
在 IIS 中的几个模块执行请求处理管道中的内容相关的任务。内容模块包括模块来处理请求的静态文件,当客户端没有指定具体页面时,以返回一个默认的页面,列出一个目录,和更多的内容中指定的资源。
压缩模块:
在 IIS 中的两个模块在请求处理管道中执行压缩。
缓存模块:
网站或应用程序中通过存储网页之类的处理信息来提高性能和可重用性。
日志记录和诊断模块:
日志记录模块支持加载自定义模块,并将信息传递给HTTP.SYS.诊断模块用来在处理请求过程中关注和报告事件。
托管支持模块:
7.托管模块
除了本地化模块以外,IIS允许你使用托管代码模块来扩展IIS功能。部分托管模块,比如UrlAuthorization,有一个相对应的本地化模块来替换托管模块。
值得注意的是托管模块依赖于ManagedEngine模块。下面列出了完整的IIS7的托管模块,有关托管模块的详细信息请参阅MSDN上的.NET框架2.0.
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的结构就全部结束了。
协议侦听器是一个可以侦听预定义通信通道(端口),传递数据(请求的数据)和参与服务和客户端通信的程序。IIS7包含5个默认的协议侦听器:Http.sys, Net.tcp, Net.pipe,
Net.p2p 和 Net.msmq; 此外,也可以穿件和使用自定义侦听器。IIS6只有一个:Http.sys。其它的新的侦听器用来支持微软新的Windows Communication Foundation服务。除了
Http.sys,其它侦听器需要安装.NET Framework和Windows激活服务(Windows Process Activation Service ,简称WAS),它们和WWW服务一样运行在相同的服务宿主进程。
但是,协议侦听器可以通过WAS托管而不需要使用IIS。
每个侦听器,运行在内核模式,直接与操作系统交互。微软为了安全隐患考虑已经充分测试过每个侦听器,尽全力保证他们不会缓存溢出和出现其它安全问题。尽管微软知道发生安
全问题的可能性很小,但是还是在过去的4年里一直防御II6的Http.sys抵御每次攻击,所以他们树立了良好的榜样。协议侦听器可以在一个叫做ApplicationHost.config的XML 配置
文件里激活。为了减少可能的攻击,只有需要的侦听器才会被激活。
当客户端浏览器通过Internet请求一个page页面,这个时候首先被HTTP协议监听器HTTP.sys监听到,经过检查之后将请求发送给IIS来处理请求。一旦IIS处理完请求之后,
HTTP.sys就会将请求的响应结果输送到客户端。
默认的IIS提供了HTTP.sys作为协议侦听器来侦听HTTP/HTTPS的请求,因为我们web大部分通过HTTP/HTTPS协议作为请求协议。HTTP.sys组件在IIS6就已经存在了,IIS7以上
仍然在使用,并且在IIS7中HTTP.sys包含了对SSL(Secure Sockets Layer)的支持。
为了支持Services和应用程序对HTTP/HTTPS之外的协议的使用,你可以通过使用WCF(Windows Communication Foundation)相关的技术来实现对HTTP/HTTPS之外的协议的
使用。WCF可以通过监听适配器来提供对协议的监听和监听适配。详细的了解可以通过WCF来学习。
3.超文本传输协议堆栈(HTTP.sys)
HTTP 侦听器是 Windows 操作系统的网络子系统的一部分,HTTP.sys作为默认的侦听组件,通过内核模式设备驱动程序来实现。HTTP.sys通过侦听网络的HTTP/HTTPS协议的请求,然后传送给IIS来进行请求处理,IIS处理完之后响应给HTTP.sys,然后HTTP.sys将响应传输给客户端。IIS6.0开始HTTP.sys代替了Winsock(Windows Sockets API)来实现请求的侦听和响应的传送。IIS7中仍然是这样做的。
HTTP.sys有很多优点:
* 内核模式缓存。如果某个资源被频繁请求,HTTP.sys会把响应的内容进行缓存,缓存内同可以直接响应后续请求,由于这是基于内核模式缓存,不存在内核模式和用户模式的切换,响应速度得到了极大的改进。
* 内核模式请求队列。请求的上下文切换,因为内核将直接向正确的辅助进程的请求转发导致开销也更少。如果没有工作进程可用来接受请求,内核模式请求队列保存请求,直到工作进程拾了起来。
* 请求前处理和安全筛选。
4.Word Wide Web Publishing Service(W3SVC)
IIS7之前WWW service的全部功能,在IIS7被拆分成了两个服务: W3SVC和WAS服务。这样www service的责任就减轻了,但是HTTP请求的监听任务仍然在W3SVC头上。WAS的引入为IIS提供了非HTTP协议的支持,它通过监听适配器接口,抽象出针对不同协议的监听器。具体来说,除了专门用于监听HTTP请求的HTTP.sys 之外, WAS 利用TCP 监听器,命名管道监听器和MSMQ监听器提供基于TCP、命名管道和MSMQ传输协议的支持。W3SVC和WAS这两个服务作为本地系统运行在相同的 Svchost.exe 进程,和共享相同的二进制文件。
W3SVC在IIS6中的主要作用是什么呢?
在IIS6中主要承载着如下三大功能:
* HTTP请求的接收和配置管理,接收HTTP.sys监听到的请求,从元数据库中加载配置信息对相关组件进行相关配置。
* 进程管理:创建、回收、监听工作进程。管理应用程序池。
* 性能的监测。
在IIS7中WAS承担了 W3SVC的部分责任,主要进行进程的管理和应用程序池的管理。这表明你可以对http和非http请求使用相同的配置和模块。
除此之外,如果你不需要监听HTTP请求,你可以只启动WAS服务,而不需要启动W3SVC服务。
WAS中配置文件的管理:
在WAS启动时,WAS读取ApplicationHost.config文件中的信息,把这些信息传递给监听适配器,监听适配器组件主要作用就是建立WAS和协议侦听器(例如:http.sys)之间的通信。一旦监听适配器接收到了配置信息,适配器就会根据配置信息配置好相应的协议监听器准备好对请求协议的监听。
下面这些信息就是WAS主要从配置文件中需要获取的信息:
*全局配置信息。
*HTTP和非HTTP协议的配置信息。
*应用程序池的配置 比如进程账号信息。
*网站的配置信息。
*应用程序的配置信息比如应用程序采用的协议和应用程序属于哪一个应用程序池。
如果ApplicationHost.config改变了,WAS就会接收到通知来更新监听适配器的信息。
WAS的进程管理:
WAS管理着HTTP和非HTTP请求的应用程序池和工作进程。当一个协议监听器监听到一个客户端请求的时候,WAS来决定工作进程是否启动。如果应用程序池已经有一个工作进程,监听适配器就会把请求发送给该工作进程来处理。如过应用程序池 中没有可用工作进程,WAS就会启动一个新的工作进程来让监听适配器传送请求来进行处理。
由于WAS管理着http和非http请求协议,所以你可以在同一个应用程序池里面运行不同协议的请求的应用程序。
5.IIS 模块化
IIS7提供了新的与之前的IIS版本不同的架构。为了保留服务器自身的主要功能,IIS 提供一个 Web 服务器引擎,用来根据你的需求来增加/删除组件和模块的调用。
模块是服务器用来处理请求的单独的功能组件。比如IIS 使用身份验证模块来验证客户端凭据,用缓存模块来管理缓存活动。
新的架构相对于之前有如下优点:
* 你可以控制任何一个你服务器上需要的模块。
* 在你的环境中你可以给服务指定任意角色。
* 你可以用自己开发的模块来代替已存在的模块来实现更多的扩展。
新的体系结构也提高了安全性,并简化管理。通过删除不必要的模块,可以减少服务器的受攻击面和 server 辅助进程的计算机使用的内存内存占用。
6.本地化模块
以下各节描述了可用的完整安装的 IIS 7 +的本机模块。您可以根据您的需要删除它们或将它们替换成自定义模块。
HTTP 模块:
IIS7之后部门模块主要用来处理HTTP请求。HTTP模块能够将响应信息输出到客户端,返回HTTP错误,重定向请求等。
模块名称 | 描述 | 资源 |
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 |
模块名称 | 描述 | 资源 |
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 |
模块名称 | 描述 | 资源 |
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 |
模块名称 | 描述 | 资源 |
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 |
模块名称 | 描述 | 资源 |
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 |
模块名称 | 描述 | 资源 |
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 |