У меня есть сервер IIS10 с ARR 3.0 и модуль перезаписи URL 2.1 который действует как обратный прокси для нескольких других веб-серверов. Другие серверы работают на других портах, поэтому сервер IIS10 предоставляет «удобные URL-адреса» на 80-м порту. Перезапись URL-адресов используется для передачи запроса внутреннему серверу.
Один из таких серверов Дженкинс.
У Jenkins есть предупреждающее сообщение, которое сообщает вам, правильно ли настроен обратный прокси (подробнее здесь), и это предупреждение помогло мне найти проблему в обратном прокси-сервере.
Проблема в том, что URL Rewrite декодирует и кодирует мои 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:
Я заметил, что закодированные символы декодируются перед запуском правила, в результате чего {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 снова кодирует URL после моей Rewrite, что делает URL, полученный Jenkins, двойным кодированием:
/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>
закодированы, чтобы Дженкинс мог знать, что является частью path
и что есть <parameter1>
.
Это означает, что когда URL Rewrite декодирует URL, <parameter1>
смешивается с остальной частью path
.
Желаемый результат - получение URL-адреса точно в том виде, в котором его отправил браузер, но с указанием на локальный хост:
http://localhost:8080/administrativeMonitor/hudson.diagnosis.ReverseProxySetupMonitor/testForReverseProxySetup/https%3A%2F%2Fjenkins.mydomain%2Fmanage%3F
Есть ли способ отключить эти операции декодирования / кодирования, которые выполняет модуль перезаписи URL?
PS: я нашел Сообщение блога относительно функций URL Rewrite v2.1, и в нем говорится, что есть новый флаг, который можно использовать для отключения этого поведения, но я понятия не имею, как и где его установить.
В версиях URL Rewrite до v7.1.1980, когда кто-то пытается использовать UNENCODED_URL, URL Rewrite закодирует его, что может привести к двойному кодированию, если исходный URL уже был закодирован. Это нарушение раздела 2.4 RFC3986, в котором говорится: «Реализации должны не кодировать или декодировать одну и ту же строку более одного раза, так как декодирование уже декодированной строки может привести к неправильной интерпретации октета процентных данных как начала процентного кодирования или наоборот в случае процентного кодирования уже процентного кодирования. закодированная строка ". Это также сделало использование UNENCODED_URL непрактичным, особенно в сценариях обратного пересылки с ARR, когда внутренние серверы ожидают, что URL-адрес будет передан без изменений.
В v7.1.1980 мы добавляем флаг функции useOriginalURLEncoding, который позволяет отключить эту несовместимую кодировку URL, если для нее установлено значение true. Поведение по умолчанию останется неизменным (для useOriginalURLEncoding по умолчанию установлено значение true).
Кто-нибудь здесь знает, как это сделать?
Мне удалось решить проблему, установив useOriginalURLEncoding = false
описано в сообщении, на которое я ссылался в вопросе.
Чтобы установить флаг IIS Manager
затем выберите Configuration Editor
и перейдите в раздел system.webServer/rewrite/rules
, где вы найдете useOriginalURLEncoding
флаг.
Установите флаг в значение false, и перезапись URL больше не будет кодировать URL-адреса при использовании {UNENCODED_URL}
переменная в правилах.