Изменить

Поделиться через


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

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

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

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

Заметка

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

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

Контекст

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

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

Важный

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

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

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

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

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

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

схема, демонстрирующая маршрутизацию на основе узла в службе приложений.

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

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

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

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

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

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

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

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

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

схема, демонстрирующая конфигурацию с переопределенным именем узла.

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

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

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

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

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

диаграмме, иллюстрируемой проблемой неправильных абсолютных URL-адресов.

  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 Connect, Open Authorization (OAuth) 2.0 или SAML 2.0. Эти URL-адреса перенаправления могут создаваться самим сервером приложений или по промежуточному слоям или, как отмечалось ранее, функциями платформы, такими как служба приложений, возможности проверки подлинности и авторизации. На этой схеме показана проблема:

диаграмме, иллюстрируемой проблемой неправильных URL-адресов перенаправления.

  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. На этой схеме показана проблема:

диаграмме, иллюстрируемой неправильным доменом cookie.

  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

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

диаграмме, в которой отображается конфигурация, в которой сохраняется имя узла.

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

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

Если веб-приложение размещено вслужбы приложений , вы можете подключить имя личного домена к веб-приложению и избежать использования имени узла по умолчанию к серверной части. При присоединении личного домена к веб-приложению не нужно изменять разрешение 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 для шлюза приложенийэта конфигурация соответствует настройке свойства hostNamenull и pickHostNameFromBackendAddress для false.

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

Azure Front Door

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

Управление API

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

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

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

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

Дальнейшие действия