我有一台带有 ARR 3.0和URL重写模块2.1 的IIS10服务器,它充当其他几个Web服务器的反向代理。其他服务器在不同的端口上运行,因此IIS10服务器提供了友好的URL'在端口80上.URR重写用于将请求发送到后端服务器。
一个这样的服务器是Jenkins。
Jenkins有一条警告消息,告诉您逆向代理是否配置良好(more details here),此警告消息帮助我在反向代理中发现问题。
问题在于,网址重写正在解码和编码我的网址,当他们到达詹金斯时,他们与浏览器请求的不同。
示例:
网址重写规则:
<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>
发送以下网址时
我注意到编码的字符在触发规则之前被解码,使得{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
简短摘要:
当您查看此网址时:
/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>
是什么。
这意味着,当网址重写解码网址时,<parameter1>
会与path
的其余部分混在一起。
所需的结果是获取与浏览器发送的URL完全相同但指向localhost的URL:
http://localhost:8080/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F
无论如何都要禁用URL Rewrite Module正在执行的解码/编码操作吗?
PS:我找到了一个关于URL Rewrite v2.1功能的blog post,它说有一个新的标志可用于禁用此行为,但我不清楚如何设置或在何处设置它
在v7.1.1980之前的URL重写版本中,当尝试使用时 UNENCODED_URL,URL Rewrite将对其进行编码,这可能导致双倍 编码如果原始URL已被编码这是违反的 RFC3986的2.4节,其中说&#34;实现不得 对数字进行百分比编码或解码不止一次,作为解码 已解码的字符串可能会导致错误解释百分比数据 八位字节作为百分比编码的开头,反之亦然 百分比编码已经百分比编码的字符串的情况。&#34;它也是 使用UNENCODED_URL是不切实际的,特别是反过来 具有ARR的转发器方案,后端服务器期望URL 没有修改地通过。
在v7.1.1980中,我们添加了一个功能标志useOriginalURLEncoding 允许您在设置时关闭此不合规的URL编码 为真。默认行为将保持不变 (默认情况下,useOriginalURLEncoding为true。)
这里有没有人知道怎么做?
答案 0 :(得分:1)
我设法通过设置问题中引用的帖子中描述的useOriginalURLEncoding = false
来解决问题。
要将标记设置为IIS Manager
,然后选择Configuration Editor
并转到system.webServer/rewrite/rules
部分,您会在其中找到useOriginalURLEncoding
标记。
将标志设置为false,并且在规则中使用{UNENCODED_URL}
变量时,URL Rewrite将不再对URL进行编码。
答案 1 :(得分:0)
您可以使用UrlEncode
功能实现此目的。将您的规则更改为:
<action type="Rewrite" url="http://localhost:8080/{UrlEncode:{R:1}}" appendQueryString="true" />
<强>更新强>: 另一种解决问题的方法
<rule name="Jenkins Rewrite" stopProcessing="true">
<match url="(.*)" />
<conditions>
<add input="{UNENCODED_URL}" pattern="(.*)" />
<add input="{HTTP_HOST}" pattern=".*jenkins.mydomain.*" />
<add input="{HTTPS}" pattern="on" />
</conditions>
<action type="Rewrite" url="http://localhost:8080{C: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>