IIS作为ASP.NET Core2.1 反向代理服务器未说的秘密
--以下內容針對 ASP.NET Core2.1,2.2出現IIS進程內寄宿 暫不展開討論---
?
?
? ? ? ? 相比ASP.NET,出現了3個新的組件:ASP.NET Core Module、Kestrel、dotnet.exe, 后面我們會理清楚這三個組件的作用和組件之間的交互原理。?
?ASP.NET Core 設計的初衷是開源跨平臺、高性能web服務器,跨平臺特性是ASP.NET Core相對于早期ASP.NET 是一個顯著的飛躍,.NET程序可以理直氣壯與JAVA同臺競技,而ASP.NET Core的高性能特性更是成為致勝法寶。?
1. ASP.NET Core宏觀梳理
?為實現跨平臺部署.Net程序,微軟為ASP.NET Core重新梳理了部署架構:
? ? ? ? ① 由于各平臺都有特定web服務器, 為解耦差異,采用HTTP通信的方式,將web服務器的請求轉發到 ASP.NET Core 程序處理?
? ? ? ? ②?ASP.NET Core Web進程(dotnet.exe)會使用一個進程內HTTP服務器:Kestrel, 處理轉發過來的請求?
? ? ? ? ③ Web服務器現在定位成?反向代理服務器, ASP.NET Core? Module組件負責轉發請求到內網Kestrel服務器
? ? ? ?常規代理服務器,只用于代理內部網絡對外網的連接需求,客戶機必須指定代理服務器將本來要直接發送到外網web服務器上的http請求發送到代理服務器,常規的代理服務器不支持外部對內部網絡的訪問請求;
當一個代理服務器能夠代理外部網絡的主機,訪問內部網絡,這種代理服務器的方式稱為反向代理服務器 。
? ? ? ? ?④ web進程(dotnet.exe)是IIS網站工作進程w3wp.exe 創建出來的子進程, 正因為如此,ASP.NET Core Module對網站工作進程 w3wp.exe 設定的進程內環境變量可以被 dotnet.exe 子進程繼承。??
? ? 驗證:
? ? -? ?任務管理器或 tasklist /fi? "imagename eq dotnet.exe"? 命令 找到dotnet.exe進程ID:22792
? ? -? ?wmic?process?where?ProcessId=22972 get?ParentProcessId? ? 返回父進程ID:8232
? ? -? 任務管理器或 tasklist /fi? "pid eq 8232"? 命令找到 父進程是 w3wp.exe
?
2. Kestrel: 進程內HTTP服務器
? ? ? ? ?與老牌web服務器解耦,實現跨平臺部署
-? 進程內Http服務器,ASP.NET Core 保持獨立運作一個Http服務器的能力,可將 ASP.NET Core 網站當可執行程序啟動,?在內網部署和開發環境中我們完全可以使用Kestrel來充當web服務器。
-? 客觀上Kestrel還是作為Http服務器,功能還比不上老牌的web服務器,? 可以說在生產部署現狀上要求使用老牌web服務器反向代理請求
? Kestrel自誕生之日起還有一些網絡安全方面的缺陷,這些缺陷包括一個合適的timeouts,Size limits,和并發數量等
? ??
3. ASP.NET Core Module
? ? ? ? ?反向代理服務器的作用是將請求轉發給內網的Http服務器,IIS上使用ASP.NET Core Module組件將請求轉發到Kestrel Http服務器(注意該組件只在IIS上有效)。
?從整個拓撲圖上看,請求首先到達內核態Http.sys Driver,該驅動將請求路由到IIS上指定網站;然后Asp.Net Core Module將請求轉發給Kestrel服務器。
?3.1??組件能力
作為企業級轉發組件ASP.NET Core Module需要完成:
? ? ①?進程管理: 控制web啟動進程內Kestrel服務器在某端口上啟動,并監聽轉發請求
? ? ②?故障恢復: 控制web在1min內崩潰重啟?
? ? ③?請求轉發
? ? ④?啟動日志記錄: web啟動失敗,可通過配置將日志輸出到指定目錄?
? ? ⑤?請求頭信息轉發:dotnet.exe程序需要收到原始的請求信息
? ? ? ?代理服務器轉發請求時可能丟失的信息:
-??源IP地址丟失
-? scheme:原始請求的scheme:https/http丟失(反向代理服務器和Kestrel之間通過Http交互,并不直接記錄原始請求的scheme)
-? IIS/nginx等代理服務器可能修改原始請求的Host消息頭
? ? ?⑥ 轉發windiws認證token
? ? ? ? ?以上能力,可以參考https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/aspnet-core-module?view=aspnetcore-2.1
給出的AspNetCore Module配置參數?
?3.2??ASP.NET Core Module組件與dotnet.exe 進程結合
? ? ? ??自然可以猜想ASP.NET Core Module與UseIISIntegration()關系很密切:
? ? ? - Web啟動的時候,ASP.NET Core Module會通過進程內環境變量指定kestrel監聽的端口
? ? ? -?UseIISIntegration() 拿到環境變量進行一系列配置:
? ? ? ? ? ?① 服務器在http://localhost:{指定端口}上監聽
? ? ? ? ? ?② 根據 token檢查請求是否來自AspNet Core Module(非ASPNE TCore Module轉發的請求會被拒絕)?
? ? ? ? ? ?③ 保持原始請求信息 :利用ForwardedHeaderMiddleware中間件保存原始請求信息,存儲在Header
? ? ? 在IIS部署時,?UseIISIntegration()會默認為你配置并啟用ForwardedHeaderMiddleware 中間件; 在linux平臺部署需要你手動啟用ForwardedHeader middleware
https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/proxy-load-balancer?view=aspnetcore-2.2
? ?
? ? ? ?通過 UseIISIntegration() 源碼快速驗證:
ASP.NET Core程序生成源碼:
?? ? IISSetupFilter?內容:
? ? 著重理解下UseIISIntegration第②點配置:?怎樣拒絕非ASP. NET Core Module 轉發的請求?
? ? ??①?AspNetCore Module 為w3wp.exe 工作進程設置進程內環境變量?ASPNETCORE_TOKEN=******
? ? ? ② dotnet.exe進程繼承了父進程?ASPNETCORE_TOKEN=****** 環境變量
? ? ? ③?AspNetCore Module轉發請求到kestrel時,會在Request里面加上一個 MS-ASPNETCORE-TOKEN:****** 的請求頭;非AspNetCore Module自然沒有該請求頭?
? ? ? ?④?IISMiddleware中間件:請求頭中匹配該ASPNETCORE_TOKEN=******的請求是有效的。
?附:部署在IIS后面的Kestrel 也是一個web服務器,怎樣Hack訪問搭配ASP.NET Core Module的Kestrel服務器?
? ? ? ? 按照上文的理論,部署在IIS后面的dotnet.exe程序是依靠 AspNetCore Module 設定的進程內環境變量ASPNETCORE-TOKEN來識別【非AspNetCore Module轉發的請求】。
因此,理論上將該PairToken拷貝到請求頭,可訪問部署在IIS后面的Kestrel 服務器(這是一個hack行為,對于理解部署圖很有幫助)。
操作方式如下:
? ?① 在任務管理器中找到你要分析的dotnet進程,tasklist? /fi "imagename eq dotnet.exe" ,找到要分析{ pid }
? ?② 找到該進程占用port : netstat -ano | findstr {pid}
? ?③?利用輸出的port: curl localhost:{port}? --verbose:? 會提示400 badrequest,這與源碼的返回一致?
? ?④ 從error log 中拷貝出該環境變量:ASPNETCORE_TOKEN
'MS-ASPNETCORE-TOKEN' does not match the expected pairing token '4cdaf1fd-66d5-4b64-b05f-db6cb8d5ebe5', request rejected.? ? ⑤?在request中添加?MS-ASPNETCORE-TOKEN:****** 請求頭?
【實際上 ,可以在ASP.NET Core dotnet.exe程序內寫日志輸出 ASPNETCORE_TOKEN?環境變量值。】
原文地址:https://www.cnblogs.com/mi12205599/p/10334506.html
.NET社區新聞,深度好文,歡迎訪問公眾號文章匯總 http://www.csharpkit.com
總結
以上是生活随笔為你收集整理的IIS作为ASP.NET Core2.1 反向代理服务器未说的秘密的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [小技巧]C#中如何为枚举类型添加描述方
- 下一篇: Asp.NetCore轻松学-部署到 I