歡迎光臨
每天分享高質量文章

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


 

受蘋果公司新規定影響,微信 iOS 版的贊賞功能被關閉,可透過二維碼轉賬支援公眾號。

    閱讀原文

    贊(0)

    分享創造快樂