Iis

IIS10 URL Rewrite 2.1 雙編碼問題

  • November 7, 2017

我有一個帶有ARR 3.0 和 URL 重寫模組 2.1的 IIS10 伺服器,它充當其他幾個 Web 伺服器的反向代理。其他伺服器在不同的埠上執行,因此 IIS10 伺服器在埠 80 上提供“友好 URL”。URL 重寫用於將請求傳遞給後端伺服器。

這樣的伺服器之一是Jenkins

Jenkins 有一條警告消息,告訴您反向代理是否配置正確(更多詳細資訊請點擊此處),這條警告消息幫助我找到了反向代理中的問題。

問題是 URL 重寫正在以某種方式對我的 URL 進行解碼和編碼,當它們到達 Jenkins 時,它們與瀏覽器請求的不同。

例子:

URL重寫規則:

<rule name="Jenkins Rewrite" stopProcessing="true">
  <match url="(.*)" />
  <conditions>
    <add input="{HTTP_HOST}" pattern=".*jenkins.mydomain.*" />
    <add input="{HTTPS}" pattern="on" />
  </conditions>
  <action type="Rewrite" url="http://localhost:8080/{R:1}" appendQueryString="true" />
  <serverVariables>
    <set name="HTTP_X_FORWARDED_HOST" value="{HTTP_HOST}" />
    <set name="HTTP_X_FORWARDED_SCHEMA" value="https" />
    <set name="HTTP_X_FORWARDED_PROTO" value="https" />
  </serverVariables>
</rule>

發送以下 URL 時:

https://jenkins.mydomain/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

我注意到在觸發規則之前編碼的字元被解碼,使得 {R:1} 看起來像這樣: /administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https:/jenkins.mydomain/manage/

經過一番研究,我發現我可以在解碼之前使用**{UNENCODED_URL}而不是{R:1}**來獲取請求字元串,所以我調整了我的規則操作:

<action type="Rewrite" url="http://localhost:8080{UNENCODED_URL}" appendQueryString="false" />

不幸的是,URL Rewrite 在我的 Rewrite 之後再次對 URL 進行編碼,從而使 Jenkins 接收到的 URL 被雙重編碼:

/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%253A%252F%252Fjenkins.mydomain%252Fmanage%253F

簡短的摘要:

當您查看此 URL 時: /administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

我們擁有的是: /administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/<parameter1>

在哪裡<parameter1> = https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

中的斜杠字元經過<parameter1>編碼,以便 Jenkins 可以知道什麼是 的一部分,path什麼是<parameter1>.

這意味著,當 URL 重寫解碼 URL 時,<parameter1>會與path.

期望的結果是獲取與瀏覽器發送的 URL 完全相同但指向 localhost 的 URL:

http://localhost:8080/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F

無論如何要禁用 URL 重寫模組正在執行的解碼/編碼操作?

PS:我發現一篇關於 URL Rewrite v2.1 features 的部落格文章,它說有一個新標誌可用於禁用此行為,但我不知道如何或在何處設置它。

在 v7.1.1980 之前的 URL Rewrite 版本中,當嘗試使用 UNENCODED_URL 時,URL Rewrite 將對它進行編碼,如果原始 URL 已經編碼,則可能導致雙重編碼這違反了 RFC3986 的第 2.4 節,其中說“實現必須不要多次對同一個字元串進行百分比編碼或解碼,因為解碼已經解碼的字元串可能會導致將百分比數據八位字節誤解為百分比編碼的開頭,反之亦然,在對已經百分比編碼的情況下進行百分比編碼編碼字元串。” 它還使 UNENCODED_URL 的使用變得不切實際,尤其是在具有 ARR 的反向轉發器場景中,後端伺服器希望 URL 未經修改地傳遞。

在 v7.1.1980 中,我們添加了一個功能標誌 useOriginalURLEncoding,它允許您在設置為 true 時關閉此不兼容的 URL 編碼。預設行為將保持不變(useOriginalURLEncoding 預設為 true)。

這裡有人知道怎麼做嗎?

通過問題中引用的文章中描述的設置,我設法解決了useOriginalURLEncoding = false這個問題。

要設置標誌,IIS Manager然後選擇Configuration Editor並轉到部分system.webServer/rewrite/rules,您將在其中找到useOriginalURLEncoding標誌。

{UNENCODED_URL}將該標誌設置為 false,當使用規則中的變數時,URL 重寫將不再對 URL 進行編碼。

引用自:https://serverfault.com/questions/882132