Перенаправление HTTPS иногда дает сбой в IIS

Информация о среде:

  • Windows Server 2012 R2
  • IIS 8
  • Модуль 2 перезаписи URL-адресов IIS (13/04 / 2015) 7.2.2
  • Umbraco 7.11.1

Описание конфигурации

У нас есть сайт Umbraco, который привязан к двум основным доменным именам, назовем их sitea.com и siteb.com - сайты с одинаковым исходным кодом и развертыванием, но совершенно разным содержанием. В IIS сайты также привязаны к www.sitea.com и www.siteb.com

. Кроме того, у нас есть сайты, защищенные с помощью LetsEncrypt для всех 4 доменных имен.

Сайт должен быть на HTTPS, и у нас также есть ключ umbraco для useSSL, установленный на true.

Переписать конфигурацию

У нас есть имеется ряд перенаправлений, вся конфигурация перезаписи вставлена ​​ниже, анонимно:

    <rewrite>
            <rules>
                <rule name="Allow LetsEncrypt" patternSyntax="Wildcard" stopProcessing="true">
                    <match url=".well-known/*" />
                    <action type="None" />
                </rule>
                <rule name="Remove WWW" patternSyntax="Wildcard" stopProcessing="false">
                    <match url="*" />
                    <conditions>
                        <add input="{CACHE_URL}" pattern="*://www.*" />
                    </conditions>
                    <action type="Redirect" url="{C:1}://{C:2}" redirectType="Permanent" />
                </rule>
                <rule name="HTTPS" patternSyntax="Wildcard" stopProcessing="false">
                    <match url="*" />
                    <conditions>
                        <add input="{HTTPS}" pattern="off" />
                    </conditions>
                    <action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirectType="Permanent" />
                </rule>
            </rules>
        </rewrite>

Подводя итог, есть 3 правила

  1. Правило обхода, поэтому, когда LetsEncrypt проверяет ~ /. хорошо известно, что он не перехватывается redirects
  2. Редирект, который при посещении www.sitea.com или www.siteb.com перенаправляется на {protocol}: //sitea.com в зависимости от того, по какому протоколу вы вошли на сайт
  3. . Дальнейшее перенаправление, которое определяет, включен ли HTTPS, а если нет, перенаправляет вас на https: // {domain} / {path}

Проблема

Иногда, как отмечено нашим мониторингом и ручной проверкой, если вы посещаете http://sitea.com тогда вы получите перенаправлен на https://sitea.com:80

Обратите внимание на добавление порта 80 в URL-адрес перенаправления. Это приводит к тому, что сайт не загружается, поскольку мы указываем https, но используем привязку http.

Если мы сбросим пул приложений для сайта, проблема сразу же исчезнет. Эта проблема может сохраняться в течение нескольких часов, а затем может исправиться сама собой, однако это может быть вызвано сбросом пула приложений в абсолютное время или по запросу приложения (мы не исследовали это).

Я не вижу ничего неправильного в конфигурации перенаправления, которое могло бы вызывать это, и это проблема, которая возникает только периодически. У нас есть другие веб-сайты на том же сервере в IIS с очень похожими структурами перенаправления и привязки, но они не проявляют тех же симптомов.

Если это актуально, в Umbraco есть два дерева контента, каждое из которых привязано к sitea.com и siteb.com соответственно. Я упоминаю об этом только в том случае, если проблема заключается в приложении, а не в конфигурации перезаписи URL.

Кто-нибудь видел эту ошибку раньше? Есть ли простое решение?

Настройка правила перезаписи для включения порта и FRT

Следуя предложению из комментариев по моему вопросу, я включил FRT, используя https://docs.microsoft.com/en-us / iis / extensions / url-rewrite-module / using-failed-request-tracing-to-trace-rewrite-rules

Мне сначала пришлось установить его как модуль IIS, а затем «восстановить» модуль перезаписи URL, чтобы получить параметры трассировки будут доступны. Я настроил это с ответами 300-301.

Я подождал, пока проблема повторится, а затем проверил журналы.

Я вижу, что есть REDIRECT_FROM_CACHE_ACTION как часть данных перезаписи URL с помощью CachedRedirectedUrl значение https://sitea.com:80/ в запросах после возникновения ошибки. Это объясняет, почему проблема начинается, а затем не разрешается автоматически до тех пор, пока не будет сброшен пул приложений, выходные данные перенаправления кэшируются, а сброс очищает кеш. Cached redirect

Проверка предыдущих журналов FRT (чтобы узнать, откуда был кэширован запрос) приводит меня к следующему: Failing redirect

Здесь мы видим, что оценка правила HTTPS начинается, совпадает, но полученный URL перенаправления после замены токенов в равно https://sitea.com:80 (запись № 28, RedirectURL)

Я изменил правила перезаписи так, чтобы правило HTTPS читалось как

<rule name="HTTPS" patternSyntax="Wildcard" stopProcessing="false">
          <match url="*" />
          <conditions>
            <add input="{HTTPS}" pattern="off" />
          </conditions>
          <action type="Redirect" url="https://{HTTP_HOST}:443{REQUEST_URI}" redirectType="Permanent" />
        </rule>

Это не похоже на необходимость, поскольку порт должен выводиться из протокола, если он не указан, но, возможно, это ошибка при перезаписи URL? Через несколько дней возникла исходная проблема, на этот раз с перенаправлением для https://sitea.com:80:443/ (что является недопустимым перенаправлением с двумя портами). **

Изменить 1: Я взял исходный код для u7.11.1 и проверил использование umbracoUseSSL, и, похоже, он используется только внутри бэк-офиса, некоторых уведомлений и маршрутов api. Отрисовка передней страницы не проверяет эту переменную и не пытается перенаправить https. Таким образом, это говорит о том, что проблема связана с приложением.

Редактировать 2: Слияние предложенного мной ответа с исходным вопросом, потому что это не решило проблему (только усугубило ситуацию)

1
задан 4 March 2019 в 22:42
1 ответ

Переменная сервера {HTTP_HOST} включает номер порта. Вместо этого вы можете попробовать {SERVER_NAME} или написать условие регулярного выражения, которое захватывает только имя хоста переменной {HTTP_HOST} . Вот пример последнего. Убедитесь, что trackAllCaptures = "true"

<rewrite>
        <rules>
            <rule name="Allow LetsEncrypt" patternSyntax="Wildcard" stopProcessing="true">
                <match url=".well-known/*" />
                <action type="None" />
            </rule>
            <rule name="Remove WWW" patternSyntax="Wildcard" stopProcessing="false">
                <match url="*" />
                <conditions>
                    <add input="{CACHE_URL}" pattern="*://www.*" />
                </conditions>
                <action type="Redirect" url="{C:1}://{C:2}" redirectType="Permanent" />
            </rule>
            <rule name="HTTPS" patternSyntax="Wildcard" stopProcessing="false">
                <match url="*" />
                <conditions trackAllCaptures="true">
                    <add input="{HTTPS}" pattern="off" />
                    <add input="{HTTP_HOST}" pattern="(.*):?\d*" />
                </conditions>
                <action type="Redirect" url="https://{C:1}{REQUEST_URI}" redirectType="Permanent" appendQueryString="false" />
            </rule>
        </rules>
    </rewrite>

Также добавлено appendQueryString = "false" , потому что {REQUEST_URI} уже включает строку запроса.

0
ответ дан 4 December 2019 в 03:12

Теги

Похожие вопросы