我們在使用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的結構就全部結束了。
