Сохранение исходного имени узла HTTP между обратным прокси-сервером и серверным веб-приложением

Cлужба управления Azure API
Служба приложений Azure
Шлюз приложений Azure
Azure Front Door
Azure Spring Apps

Рекомендуется сохранить исходное имя узла HTTP при использовании обратного прокси-сервера перед веб-приложением. Наличие другого имени узла на обратном прокси-сервере может привести к файлам cookie или перенаправления URL-адресов, которые не работают должным образом. Например, состояние сеанса может быть потеряно, проверка подлинности может завершиться ошибкой или непреднамеренно предоставляться конечным пользователям. Эти проблемы можно избежать, сохранив имя узла начального запроса, чтобы сервер приложений видел тот же домен, что и веб-браузер.

Это руководство особенно относится к приложениям, размещенным на платформе как услуга (PaaS), таким как приложение Azure Service и Azure Spring Apps. В этой статье содержатся конкретные рекомендации по реализации Шлюз приложений Azure, Azure Front Door и Azure Управление API, которые обычно используют обратные прокси-службы.

Примечание.

Веб-API обычно менее чувствительны к проблемам, вызванным несоответствием имени узла. Обычно они не зависят от файлов cookie, если вы не используете файлы cookie для защиты обмена данными между одностраничным приложением и его серверным API, например, в шаблоне, известном как серверные серверы для интерфейсов. Веб-API часто не возвращают абсолютные URL-адреса обратно в себя, за исключением определенных стилей API, таких как OData и HATEOAS. Если реализация API зависит от файлов cookie или создает абсолютные URL-адреса, применяется руководство, указанное в этой статье.

Если требуется сквозное подключение TLS/SSL (подключение между обратным прокси-сервером и серверной службой использует HTTPS), серверная служба также нуждается в сопоставленном сертификате TLS для исходного имени узла. Это требование повышает операционную сложность при развертывании и продлении сертификатов, но многие службы PaaS предлагают бесплатные сертификаты TLS, которые полностью управляются.

Контекст

Узел HTTP-запроса

Во многих случаях сервер приложений или какой-либо компонент в конвейере запросов нуждается в доменном имени Интернета, используемом браузером для доступа к нему. Это узел запроса. Это может быть IP-адрес, но обычно это имя contoso.com (которое браузер затем разрешает в IP-адрес с помощью DNS). Значение узла обычно определяется из компонента узла URI запроса, который браузер отправляет приложению в качестве заголовка HostHTTP.

Важно!

Никогда не используйте значение узла в механизме безопасности. Это значение предоставляется браузером или другим агентом пользователя и может легко управляться конечным пользователем.

В некоторых сценариях, особенно если в цепочке запросов есть обратный прокси-сервер HTTP, исходный заголовок узла может измениться, прежде чем он достигнет сервера приложений. Обратный прокси-сервер закрывает сеанс клиентской сети и настраивает новое подключение к серверной части. В этом новом сеансе он может перенести исходное имя узла сеанса клиента или задать новый. В последнем случае прокси-сервер часто отправляет исходное значение узла в других заголовках HTTP, например Forwarded или X-Forwarded-Host. Это значение позволяет приложениям определять исходное имя узла, но только если они кодируются для чтения этих заголовков.

Почему веб-платформы используют имя узла

Многотенантные службы PaaS часто требуют зарегистрированного и проверенного имени узла для маршрутизации входящего запроса на внутренний сервер клиента. Это связано с тем, что обычно существует общий пул подсистем балансировки нагрузки, который принимает входящие запросы для всех клиентов. Клиенты обычно используют входящее имя узла для поиска правильной серверной части клиента.

Чтобы упростить работу, эти платформы обычно предоставляют домен по умолчанию, предварительно настроенный для маршрутизации трафика в развернутый экземпляр. Для Служба приложений это домен azurewebsites.netпо умолчанию. Каждое создаваемое веб-приложение получает собственный поддомен, например contoso.azurewebsites.net. Аналогичным образом домен по умолчанию предназначен azuremicroservices.io для Spring Apps и azure-api.net для Управление API.

Для рабочих развертываний эти домены по умолчанию не используются. Вместо этого вы предоставляете собственный домен для согласования с фирменной символикой вашей организации или приложения. Например, contoso.com может разрешиться за кулисами веб-приложения contoso.azurewebsites.net на Служба приложений, но этот домен не должен быть видимым для конечного пользователя, посещающего веб-сайт. Однако это пользовательское contoso.com имя узла должно быть зарегистрировано в службе PaaS, поэтому платформа может определить серверный сервер, который должен отвечать на запрос.

Diagram that illustrates host-based routing in App Service.

Почему приложения используют имя узла

Две распространенные причины, по которым серверу приложений требуется имя узла, — создавать абсолютные URL-адреса и выдавать файлы cookie для определенного домена. Например, если код приложения должен:

  • Возвращает абсолютный, а не относительный URL-адрес в ответе HTTP (хотя обычно веб-сайты обычно отображают относительные ссылки по возможности).
  • Создайте URL-адрес, который будет использоваться вне ответа HTTP, где относительные URL-адреса нельзя использовать, например для отправки ссылки на веб-сайт пользователю.
  • Создайте абсолютный URL-адрес перенаправления для внешней службы. Например, в службу проверки подлинности, например идентификатор Microsoft Entra, чтобы указать, где он должен вернуть пользователя после успешной проверки подлинности.
  • Проблема с HTTP-файлами cookie, которые ограничены определенным узлом, как определено в атрибуте файла cookieDomain.

Все эти требования можно выполнить, добавив ожидаемое имя узла в конфигурацию приложения и используя это статически определенное значение вместо имени входящего узла в запросе. Однако этот подход усложняет разработку и развертывание приложений. Кроме того, одна установка приложения может обслуживать несколько узлов. Например, одно веб-приложение можно использовать для нескольких клиентов приложений, имеющих собственные уникальные имена узлов (например tenant1.contoso.com , и tenant2.contoso.com).

Иногда имя входящего узла используется компонентами за пределами кода приложения или по промежуточного слоя на сервере приложений, над которым у вас нет полного контроля. Ниже приведено несколько примеров:

  • В Служба приложений можно применить ПРОТОКОЛ HTTPS для веб-приложения. Это приводит к тому, что HTTP-запросы, которые не защищены для перенаправления на HTTPS. В этом случае имя входящего узла используется для создания абсолютного URL-адреса заголовка Location ПЕРЕНАПРАВЛЕНия HTTP.
  • Spring Apps использует аналогичную функцию для принудительного применения HTTPS. Он также использует входящий узел для создания URL-адреса HTTPS.
  • Служба приложений имеет Параметр сопоставления ARR для включения липких сеансов, чтобы запросы из одного экземпляра браузера всегда обслуживались тем же сервером серверной части. Это выполняется интерфейсными Служба приложений, которые добавляют файл cookie в http-ответ. Для входящего узла задано значение файла cookie Domain .
  • Служба приложений предоставляет возможности проверки подлинности и авторизации, чтобы пользователи могли легко входить и получать доступ к данным в API.

Почему вам может потребоваться переопределить имя узла

Предположим, вы создаете веб-приложение в Служба приложений с доменом contoso.azurewebsites.netпо умолчанию. (Или в другой службе, например Spring Apps.) Вы не настроили личный домен на Служба приложений. Чтобы поместить обратный прокси-сервер, например Шлюз приложений (или любую аналогичную службу) перед этим приложением, необходимо задать запись DNS для contoso.com разрешения IP-адреса Шлюз приложений. Поэтому он получает запрос из браузера и настраивается для пересылки этого запроса contoso.com в IP-адрес, contoso.azurewebsites.net который разрешается: это окончательная серверная служба для запрошенного узла. Однако в этом случае Служба приложений не распознает личный contoso.com домен и отклоняет все входящие запросы для этого имени узла. Он не может определить, куда маршрутизировать запрос.

Это может показаться простым способом сделать эту работу конфигурации, чтобы переопределить или перезаписать Host заголовок HTTP-запроса в Шлюз приложений и задать его значениеcontoso.azurewebsites.net. Если вы делаете, исходящий запрос от Шлюз приложений делает это похоже на исходный запрос действительно предназначен contoso.azurewebsites.net вместоcontoso.com:

Diagram that illustrates a configuration with the host name overridden.

На этом этапе Служба приложений распознает имя узла и принимает запрос, не требуя настройки имени личного домена. На самом деле, Шлюз приложений упрощает переопределение заголовка узла с узлом внутреннего пула. Azure Front Door даже делает это по умолчанию.

Однако проблема с этим решением заключается в том, что это может привести к различным проблемам, когда приложение не видит исходное имя узла.

Потенциальные проблемы

Неправильные абсолютные URL-адреса

Если исходное имя узла не сохраняется, а сервер приложений использует входящее имя узла для создания абсолютных URL-адресов, серверный домен может быть раскрыт конечным пользователем. Эти абсолютные URL-адреса могут быть созданы кодом приложения или, как отмечалось ранее, функциями платформы, такими как поддержка перенаправления HTTP-to-HTTPS в Служба приложений и Spring Apps. На этой схеме показана проблема:

Diagram that illustrates the problem of incorrect absolute URLs.

  1. Браузер отправляет запрос contoso.com обратному прокси-серверу.
  2. Обратный прокси перезаписывает имя contoso.azurewebsites.net узла в запросе на серверное веб-приложение (или на аналогичный домен по умолчанию для другой службы).
  3. Приложение создает абсолютный URL-адрес, основанный на имени входящего contoso.azurewebsites.net узла, например https://contoso.azurewebsites.net/.
  4. Браузер следует этому URL-адресу, который переходит непосредственно в серверную службу, а не обратно на обратный прокси-сервер contoso.com.

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

Важно!

Из-за этого риска безопасности необходимо убедиться, что серверное веб-приложение принимает только сетевой трафик из обратного прокси-сервера (например, с помощью ограничений доступа в Служба приложений). Если вы делаете это, даже если создается неверный абсолютный URL-адрес, по крайней мере он не работает и не может использоваться злоумышленником для обхода брандмауэра.

Неправильные URL-адреса перенаправления

Распространенный и более конкретный случай предыдущего сценария возникает при создании абсолютных URL-адресов перенаправления. Эти URL-адреса требуются службами удостоверений, такими как Идентификатор Microsoft Entra, при использовании протоколов удостоверений на основе браузера, таких как OpenID Подключение, OAuth 2.0 или SAML 2.0. Эти URL-адреса перенаправления могут создаваться самим сервером приложений или по промежуточному слоям или, как отмечалось ранее, функциями платформы, такими как возможности проверки подлинности и авторизации Служба приложений. На этой схеме показана проблема:

Diagram that illustrates the problem of incorrect redirect URLs.

  1. Браузер отправляет запрос contoso.com обратному прокси-серверу.
  2. Обратный прокси перезаписывает имя contoso.azurewebsites.net узла на запрос на серверное веб-приложение (или на аналогичный домен по умолчанию для другой службы).
  3. Приложение создает абсолютный URL-адрес перенаправления, основанный на имени входящего contoso.azurewebsites.net узла, например https://contoso.azurewebsites.net/.
  4. Браузер переходит к поставщику удостоверений для проверки подлинности пользователя. Запрос содержит созданный URL-адрес перенаправления, чтобы указать, где вернуть пользователя после успешной проверки подлинности.
  5. Поставщики удостоверений обычно требуют, чтобы URL-адреса перенаправления регистрировались заранее, поэтому на этом этапе поставщик удостоверений должен отклонить запрос, так как указанный URL-адрес перенаправления не зарегистрирован. (Он не должен был использоваться.) Если по какой-то причине URL-адрес перенаправления зарегистрирован, поставщик удостоверений перенаправляет браузер на URL-адрес перенаправления, указанный в запросе проверки подлинности. В этом случае URL-адрес имеет значение https://contoso.azurewebsites.net/.
  6. Браузер следует этому URL-адресу, который переходит непосредственно в серверную службу, а не обратно на обратный прокси-сервер.

Сломанные файлы cookie

Несоответствие имени узла также может привести к проблемам, когда сервер приложений выдает файлы cookie и использует входящее имя узла для создания Domain атрибута файла cookie. Атрибут домена гарантирует, что файл cookie будет использоваться только для этого конкретного домена. Эти файлы cookie можно создать с помощью кода приложения или, как отмечалось ранее, функциями платформы, такими как параметр сопоставления ARR Служба приложений. На этой схеме показана проблема:

Diagram that illustrates an incorrect cookie domain.

  1. Браузер отправляет запрос contoso.com обратному прокси-серверу.
  2. Обратный прокси перезаписывает имя узла, которое должно находиться contoso.azurewebsites.net в запросе на серверное веб-приложение (или на аналогичный домен по умолчанию для другой службы).
  3. Приложение создает файл cookie, использующий домен на основе входящего contoso.azurewebsites.net имени узла. В браузере хранятся файлы cookie для этого конкретного домена, а не contoso.com домен, который пользователь фактически использует.
  4. Браузер не включает файл cookie в любой последующий запрос contoso.com , так как домен файла cookie contoso.azurewebsites.net не соответствует домену запроса. Приложение не получает файл cookie, выданный ранее. В результате пользователь может потерять состояние, которое должно находиться в файле cookie, или функции, такие как сходство ARR, не работают. К сожалению, ни одна из этих проблем не создает ошибку или напрямую отображается для конечного пользователя. Это затрудняет устранение неполадок.

Руководство по реализации общих служб Azure

Чтобы избежать потенциальных проблем, рассмотренных здесь, рекомендуется сохранить исходное имя узла в вызове обратного прокси-сервера и внутреннего сервера приложений:

Diagram that shows a configuration in which the host name is preserved.

Конфигурация серверной части

Многие платформы размещения веб-сайтов требуют явной настройки разрешенных имен узлов. В следующих разделах описывается реализация этой конфигурации для наиболее распространенных служб Azure. Другие платформы обычно предоставляют аналогичные методы настройки пользовательских доменов.

Если вы размещаете веб-приложение в Служба приложений, вы можете подключить имя личного домена к веб-приложению и избежать использования имени узла по умолчанию azurewebsites.net к серверной части. При присоединении личного домена к веб-приложению не нужно изменять разрешение DNS: вы можете проверить домен с помощью TXT записи , не влияя на обычные CNAME или A записи. (Эти записи по-прежнему разрешаются в IP-адрес обратного прокси-сервера.) Если вам нужен сквозной протокол TLS/SSL, можно импортировать существующий сертификат из Key Vault или использовать сертификат Служба приложений для личного домена. (Обратите внимание, что бесплатный Служба приложений управляемый сертификат нельзя использовать в этом случае, так как требуется, чтобы запись DNS домена разрешала непосредственно в Служба приложений, а не обратный прокси-сервер.)

Аналогичным образом, если вы используете Spring Apps, вы можете использовать личный домен для приложения , чтобы избежать использования azuremicroservices.io имени узла. Вы можете импортировать существующий или самозаверяющий сертификат, если требуется сквозной протокол TLS/SSL.

Если у вас есть обратный прокси-сервер перед Управление API (который также выступает в качестве обратного прокси-сервера), можно настроить личный домен в экземпляре Управление API, чтобы избежать использования azure-api.net имени узла. Вы можете импортировать существующий или бесплатный управляемый сертификат, если требуется сквозной протокол TLS/SSL. Как отмечалось ранее, API-интерфейсы менее чувствительны к проблемам, вызванным несоответствием имени узла, поэтому эта конфигурация может быть не столь важна.

Если вы размещаете приложения на других платформах, например Kubernetes или непосредственно на виртуальных машинах, встроенные функции не зависят от имени входящего узла. Вы несете ответственность за использование имени узла в самом сервере приложений. Рекомендация по сохранению имени узла обычно применяется для всех компонентов в приложении, которые зависят от него, если приложение не учитывает обратные прокси-серверы и учитываете forwarded заголовки или X-Forwarded-Host заголовки, например.

Обратная конфигурация прокси-сервера

При определении серверной части обратного прокси-сервера можно по-прежнему использовать домен по умолчанию серверной службы, например https://contoso.azurewebsites.net/. Этот URL-адрес используется обратным прокси-сервером для разрешения правильного IP-адреса серверной службы. Если вы используете домен платформы по умолчанию, IP-адрес всегда будет правильным. Как правило, вы не можете использовать общедоступный домен, например, так как contoso.comон должен разрешаться в IP-адрес обратного прокси-сервера. (Если вы не используете более сложные методы разрешения DNS, например DNS с разделением горизонта.

Важно!

Если у вас есть брандмауэр следующего поколения, например Брандмауэр Azure Premium между обратным прокси-сервером и конечной серверной частью, может потребоваться использовать DNS с разделенным горизонтом. Этот тип брандмауэра может явно проверка, разрешается ли заголовок HTTP Host в целевой IP-адрес. В таких случаях исходное имя узла, используемое браузером, должно разрешаться в IP-адрес обратного прокси-сервера при доступе из общедоступного Интернета. Однако с точки зрения брандмауэра имя узла должно разрешаться на IP-адрес конечной серверной службы. Дополнительные сведения см. в разделе "Сеть нулевого доверия" для веб-приложений с Брандмауэр Azure и Шлюз приложений.

Большинство обратных прокси-серверов позволяют настроить имя узла, переданное в серверную службу. В следующих сведениях объясняется, как убедиться, что для наиболее распространенных служб Azure используется исходное имя узла входящего запроса.

Примечание.

Во всех случаях можно также переопределить имя узла явным образом определенным личным доменом, а не принимать его из входящего запроса. Если приложение использует только один домен, этот подход может работать нормально. Если одно развертывание приложения принимает запросы из нескольких доменов (например, в мультитенантных сценариях), невозможно статически определить один домен. Необходимо принять имя узла из входящего запроса (опять же, если приложение явно не закодировано для учета дополнительных заголовков HTTP). Поэтому общая рекомендация заключается в том, что не следует переопределять имя узла вообще. Передайте имя входящего узла, не измененное в серверную часть.

Шлюз приложений

Если вы используете Шлюз приложений в качестве обратного прокси-сервера, вы можете убедиться, что исходное имя узла сохраняется, отключив переопределение с новым именем узла в параметре HTTP серверной части. Это отключает имя узла выбора из внутреннего адреса и переопределения с определенным доменным именем. (Оба этих параметра переопределяют имя узла.) В свойствах Azure Resource Manager для Шлюз приложений эта конфигурация соответствует настройке hostName свойства в null значение и pickHostNameFromBackendAddress значение false.

Так как пробы работоспособности отправляются вне контекста входящего запроса, они не могут динамически определять правильное имя узла. Вместо этого необходимо создать настраиваемую пробу работоспособности, отключить имя узла выбора из параметров HTTP серверной части и явно указать имя узла. Для этого имени узла также следует использовать соответствующий личный домен для согласованности. (Однако вы можете использовать домен по умолчанию для платформы размещения, так как пробы работоспособности игнорируют неправильные файлы cookie или перенаправление URL-адресов в ответе.)

Azure Front Door

Если вы используете Azure Front Door, можно избежать переопределения имени узла, оставив заголовок внутреннего узла пустым в определении внутреннего пула. В определении Resource Manager серверного пула эта конфигурация соответствует параметру backendHostHeadernull.

Если вы используете Azure Front Door Standard или Premium, можно сохранить имя узла, оставив заголовок узла источника пустым в определении источника. В определении источника Resource Manager эта конфигурация соответствует параметру originHostHeadernull.

Управление API

По умолчанию Управление API переопределяет имя узла, которое отправляется в серверную часть с помощью компонента узла URL-адреса веб-службы API (который соответствует serviceUrl значению определения Resource Manager API).

Вместо этого можно принудительно Управление API использовать имя узла входящего запроса, добавив inboundполитику заголовка Set HTTP следующим образом:

<inbound>
  <base />
  <set-header name="Host" exists-action="override">
    <value>@(context.Request.OriginalUrl.Host)</value>
  </set-header>
</inbound>

Как отмечалось ранее, API-интерфейсы менее чувствительны к проблемам, вызванным несоответствием имени узла, поэтому эта конфигурация может быть не столь важна.

Следующие шаги