Переопределение HTTP-заголовков и URL-адресов с помощью Шлюза приложений Azure
Шлюз приложений позволяет перезаписывать выделенное содержимое запросов и ответов. С помощью этой функции можно перевести URL-адреса, параметры строки запроса и изменить заголовки запросов и ответов. Она также позволяет добавить условия для того, чтобы указанные заголовки перезаписывались только при соблюдении выбранных параметров. Эти условия основываются на сведениях о запросе и ответе.
Функции перезаписи заголовков HTTP и URL-адресов доступны только для SKU Шлюз приложений версии 2.
Заголовки запросов и ответов
Шлюз приложений позволяет добавлять, удалять или обновлять заголовки HTTP-запросов и ответов при перемещении пакетов запросов и ответов между клиентскими и внутренними пулами. HTTP-заголовки позволяют клиенту и серверу передавать дополнительную информацию вместе с запросом или ответом. Переписывая эти заголовки, вы сможете выполнять важные задачи, такие как добавление полей заголовка, связанных с безопасностью (например, HSTS/X-XSS-Protection), удаление полей заголовка ответа, которые могут раскрывать конфиденциальную информацию, а также удаление сведений о портах заголовков типа "Х был перенаправлен на" (X-Forwarded-For).
Вы можете переписать все заголовки в запросах и ответах, за исключением Connection
заголовков и Upgrade
заголовков. Вы также можете использовать шлюз приложений для создания пользовательских заголовков и добавления их в запросы и ответы, которые направляются через него. Дополнительные сведения о перезаписи заголовков запросов и ответов с помощью шлюза приложений через портал Azure см. здесь.
URL-путь и строка запроса
Возможность повторного создания URL-адресов в шлюзе приложений позволяет:
Перезаписать имя узла, путь и строку запроса URL-адреса запроса
Выберите перезаписать URL-адрес всех запросов прослушивателя или только те запросы, которые соответствуют одному или нескольким заданным условиям. Эти условия основаны на свойствах запроса (переменные заголовка запроса и сервера).
Выбрать маршрутизацию запроса (с выбором внутреннего пула) на основе исходного URL-адреса или перезаписанного URL-адреса
Чтобы узнать, как переопределить URL-адрес с помощью шлюза приложений, используя портал Azure, см. необходимые сведения здесь.
Общие сведения о перезаписи в Шлюз приложений
Набор перезаписи — это коллекция правил маршрутизации, условия и действия.
Сопоставление правил маршрутизации запросов: конфигурация перезаписи связана с прослушивателем источника с помощью правила маршрутизации. При использовании правила маршрутизации типа Basic конфигурация перезаписи связана с прослушивателем и работает как глобальная перезапись. При использовании правила маршрутизации на основе пути конфигурация перезаписи определяется в соответствии с картой ПУТИ URL-адреса. В последнем случае он применяется только к определенной области пути сайта. Можно применить перезапись к нескольким правилам маршрутизации, но правило маршрутизации может иметь только одну перезапись.
Условие перезаписи. Это необязательная конфигурация. На основе заданных условий Шлюз приложений будет оценивать содержимое запросов и ответов HTTP(S). Последующие действия перезаписи будут возникать, если запрос ИЛИ ответ HTTP(S) соответствует этому условию. При связывании более одного условия с действием оно выполняется только при соблюдении всех условий. Другими словами, это логическая операция AND. Для оценки содержимого запросов и ответов HTTP(S) можно использовать условия перезаписи. Эта необязательная конфигурация позволяет выполнять перезапись только при выполнении одного или нескольких условий. Шлюз приложений использует представленные ниже типы переменных для вычисления содержимого запросов и ответов:
Для поиска условия можно выбрать следующие типы:
- Заголовок HTTP (запрос и ответ)
- Поддерживаемые переменные сервера
Условие позволяет оценить, существует ли указанный заголовок или переменная путем сопоставления значений с помощью текста или шаблона Regex. Для расширенных конфигураций перезаписи можно также записать значение переменной заголовка или сервера для последующего использования в разделе "Действие перезаписи". Узнайте больше о шаблоне и захвате.
Действие перезаписи: набор действий перезаписи позволяет переписать заголовки (запрос или ответ) или компоненты URL-адреса.
Действие может иметь следующие типы значений или их сочетания:
- Текст.
- Значение заголовка запроса. Чтобы использовать значение заголовка записанного запроса, укажите синтаксис как
{http_req_headerName}
. - Значение заголовка ответа . Чтобы использовать значение заголовка записанного ответа из предыдущего условия, укажите синтаксис как
{http_resp_headerName}
. Вы можете использовать{capt_header_value_matcher}
, если значение записывается из заголовка ответа Set-Cookie набора действий. Дополнительные сведения о захвате в группе действий. - Переменная сервера. Чтобы использовать переменную сервера, укажите синтаксис как
{var_serverVariable}
. Список поддерживаемых переменных сервера.
Примечание.
Использование поля сопоставления значений заголовка {capt_header_value_matcher} в настоящее время не поддерживается через портал. Поэтому при использовании этого поля необходимо продолжать использовать метод, отличный от портала, для любых операций PUT.
При использовании действия для перезаписи URL-адреса поддерживаются следующие операции:
- URL-путь: новое значение, которое должно быть задано в качестве пути.
- Строка запроса URL: новое значение, в которое должна быть перезаписана строка запроса.
- Повторное вычисление карты пути. Укажите, должна ли карта пути URL-адреса повторно оцениваться после перезаписи. Если флажок не установлен, исходный URL-адрес будет использоваться для сопоставления шаблона пути на карте URL-пути. Если задано значение "true", сопоставление пути URL-адреса будет перепроверено на соответствие с перезаписанным путем. Включение этого параметра помогает в маршрутизации запроса к другому внутреннему пулу после перезаписи.
Сопоставление шаблонов и запись
Сопоставление и запись patten поддерживаются в разделе "Условие" и "Действие" (в разделе "Действие" поддерживается только для определенного заголовка).
Сопоставление шаблонов
Шлюз приложений использует регулярные выражения для сопоставления шаблонов. При написании синтаксиса сопоставления шаблонов следует использовать совместимые выражения регулярного выражения 2 (RE2).
Вы можете использовать сопоставление шаблонов как в условии, так и в действии.
- Условие: используется для сопоставления значений для переменной заголовка или сервера. Чтобы соответствовать шаблону в разделе "Условия", используйте свойство pattern.
- Действие. Сопоставление шаблонов в группе действий доступно только для заголовка ответа Set-Cookie. Чтобы соответствовать шаблону для Set-Cookie в действии, используйте свойство HeaderValueMatcher. При захвате его значение можно использовать как {capt_header_value_matcher}. Так как может быть несколько set-Cookie, шаблон, соответствующий здесь, позволяет искать определенный файл cookie. Пример. Для определенной версии агента-пользователя необходимо переписать заголовок ответа set-cookie для cookie2 с максимальным возрастом=3600 (один час). В этом случае можно использовать
- Условие — тип: заголовок запроса, имя заголовка: user-agent, шаблон для сопоставления: *2.0
- Действие — перезапись типа: заголовок ответа, тип действия: Set, Имя заголовка: Set-Cookie, Значение значения заголовка: cookie2=(.*), значение заголовка: cookie2={capt_header_value_matcher_1}; Max-Age=3600
Примечание.
Если вы используете Шлюз приложений Брандмауэр веб-приложений (WAF) с набором основных правил 3.1 или более ранней версии, при использовании совместимых с Perl регулярных выражений (PCRE) при выполнении утверждений lookahead и lookbehind (отрицательных или положительных) может возникнуть проблема.
Синтаксис для записи
Шаблоны также можно использовать для записи подстроки для последующего использования. Поместите круглые скобки вокруг подшаблоны в определении regex. Первая пара скобок хранит свою подстроку в 1, вторую пару в 2 и т. д. Вы можете использовать столько круглых скобок, сколько пожелаете. Perl просто будет определить больше числовых переменных для представления этих захваченных строк. Пример можно найти в этом руководстве по программированию Perl.
- (\d)(\d) # Сопоставление двух цифр, захват их в группы 1 и 2
- (\d+) # Сопоставление одной или нескольких цифр, захватив их в группу 1
- (\d)+ # Сопоставление цифры один или несколько раз, захватив последний в группу 1
После записи их можно использовать в значении набора действий с помощью следующего формата:
- Для захвата заголовка запроса необходимо использовать {http_req_headerName_groupNumber}. Например, {http_req_User-Agent_1} или {http_req_User-Agent_2}
- Для захвата заголовка ответа необходимо использовать {http_req_headerName_groupNumber}. Например, {http_resp_Location_1} или {http_resp_Location_2}. В то время как для заголовка ответа Set-Cookie, записанного с помощью свойства HeaderValueMatcher, необходимо использовать {capt_header_value_matcher_groupNumber}. Например, {capt_header_value_matcher_1} или {capt_header_value_matcher_2}.
- Для серверной переменной необходимо использовать {var_serverVariableName_groupNumber}. Например, {var_uri_path_1} или {var_uri_path_2}
Примечание.
- Использование префикса и суффикса в шаблоне не должно быть указано в шаблоне для сопоставления значений. Например, (\d)(\d) будет соответствовать двум цифрам. /(\d)(\d)/ не соответствует двум цифрам.
- Случай переменной условия должен соответствовать регистру переменной записи. Например, если моя переменная условия — User-Agent, моя переменная записи должна быть для user-agent (т. е. {http_req_User-Agent_2}). Если переменная условия определена как пользователь-агент, переменная записи должна быть для агента пользователя (т. е. {http_req_user-agent_2}).
- Если вы хотите использовать целое значение, не следует упоминать это число. Просто используйте формат {http_req_headerName} и т. д. без groupNumber.
Переменные сервера
Шлюз приложений использует переменные сервера для хранения полезной информации о сервере, подключении к клиенту и текущем запросе к соединению. Примеры хранимых сведений включают IP-адрес клиента и тип веб-браузера. Переменные сервера изменяются динамически, например при загрузке новой страницы или при публикации формы. Эти переменные можно использовать для вычисления условий перезаписи и перезаписи заголовков. Чтобы использовать значение переменных сервера для перезаписи заголовков, необходимо указать эти переменные в синтаксисе {var_serverVariableName}
Шлюз приложений поддерживает перечисленные ниже переменные сервера:
Имя переменной | Description |
---|---|
add_x_forwarded_for_proxy | Поле заголовка X-Forwarded-For в запросе клиента с переменной client_ip (см. описание далее в этой таблице) добавляется к ней в формате IP1, IP2, IP3 и т. д. Если в заголовке запроса клиента нет поля X-Forwarded-For, значение переменной add_x_forwarded_for_proxy будет равно значению переменной $client_ip . Эта переменная полезна, если вы хотите перезаписать заголовок X-Forwarded-For, заданный Шлюз приложений, чтобы заголовок содержал только IP-адрес без сведений о порту. |
ciphers_supported | Возвращает список шифров, поддерживаемых клиентом. |
ciphers_used | Возвращает строку шифров, которая используется для установленного соединения TLS. |
client_ip | IP-адрес клиента, от которого шлюз приложений получил запрос. Если перед шлюзом приложений и источником клиента есть обратный прокси-сервер, client_ip возвращает IP-адрес обратного прокси-сервера. |
client_port | Порт клиента. |
client_tcp_rtt | Сведения о TCP-подключении клиента. Доступно для систем, поддерживающих дополнительный сокет TCP_INFO. |
client_user | При использовании проверки подлинности HTTP эта переменная будет содержать имя пользователя, передаваемое для проверки подлинности. |
host | В следующем порядке значимости: имя узла из строки запроса, имя узла из поля "Host" в заголовке запроса или имя сервера, соответствующее запросу. Пример. В запросе http://contoso.com:8080/article.aspx?id=123&title=fabrikam значение узла равно contoso.com |
cookie_name | Имя файла cookie. |
http_method | Метод, используемый для выполнения запроса URL-адреса. Например, GET или POST. |
http_status | Статус сеанса. Например, 200, 400 или 403. |
http_version | Протокол запроса. Обычно это бывает HTTP/1.0, HTTP/1.1 или HTTP/2.0. |
query_string | Список пар "переменная-значение", которые следуют за "?" в запрошенном URL-адресе. Пример. В запросе http://contoso.com:8080/article.aspx?id=123&title=fabrikam значение query_string id=123&title=fabrikam |
received_bytes | Длина запроса (включая строку запроса, заголовок и текст запроса). |
request_query | Аргументы в строке запроса. |
request_scheme | Схема запроса: HTTP или HTTPS. |
request_uri | Полный исходный код URI запроса (с аргументами). Пример: в запросе http://contoso.com:8080/article.aspx?id=123&title=fabrikam* значение request_uri /article.aspx?id=123&title=fabrikam |
sent_bytes | Количество отправленных клиенту байтов. |
server_port | Порт сервера, принявшего запрос. |
ssl_connection_protocol | Протокол установленного подключения TLS. |
ssl_enabled | Значение "Включено", если подключение работает в режиме TLS. В противном случае — пустая строка. |
uri_path | Определяет конкретный ресурс на узле, к которому требуется доступ из веб-клиента. Переменная ссылается на исходный путь URL-адреса до любой манипуляции. Это часть URI запроса без аргументов. Например, в запросе http://contoso.com:8080/article.aspx?id=123&title=fabrikam значение uri_path./article.aspx |
Переменные сервера взаимной проверки подлинности
Шлюз приложений поддерживает следующие переменные сервера для взаимной проверки подлинности. Используйте эти серверные переменные так же, как и при работе с другими переменными сервера.
Имя переменной | Description |
---|---|
client_certificate | Сертификат клиента для установленного SSL-соединения в формате PEM. |
client_certificate_end_date | Дата окончания действия сертификата клиента. |
client_certificate_fingerprint | Отпечаток SHA1 сертификата клиента для установленного SSL-соединения. |
client_certificate_issuer | Значение строки "issuer DN" сертификата клиента для установленного SSL-соединения. |
client_certificate_serial | Серийный номер сертификата клиента для установленного SSL-соединения. |
client_certificate_start_date | Дата начала действия сертификата клиента. |
client_certificate_subject | Значение строки "subject DN" сертификата клиента для установленного SSL-соединения. |
client_certificate_verification | Результат проверки сертификата клиента: SUCCESS, FAILED:<reason> или NONE, если сертификат отсутствует. |
Распространенные сценарии для перезаписи заголовков
Удаление информации о портах из заголовков X-Forwarded-For
Шлюз приложений вставляет заголовок X-Forwarded-For во все запросы перед их перенаправлением в серверную часть. Этот заголовок представляет собой разделенный запятыми список IP-портов. Могут возникнуть сценарии, в которых серверные серверы должны содержать только заголовки, чтобы содержать IP-адреса. Можно использовать перезапись заголовка для удаления сведений о портах из заголовка X-Forwarded-For. Один из способов сделать это — задать в качестве заголовка переменную сервера add_x_forwarded_for_proxy. Также можно использовать переменную client_ip:
Изменение URL-адреса перенаправления
Изменение URL-адреса перенаправления может оказаться полезным при определенных обстоятельствах. Например, клиенты были первоначально перенаправлены на путь, например "/blog", но теперь должны отправляться в "/updates" из-за изменения структуры содержимого.
Предупреждение
Иногда требуется изменить URL-адрес перенаправления в контексте конфигурации, в которой Шлюз приложений настроено переопределение имени узла на серверную часть. Имя узла, как показано серверной частью, отличается от имени узла, как показано в браузере. В этой ситуации перенаправление не будет использовать правильное имя узла. Такую конфигурацию использовать не рекомендуется.
Ограничения и последствия такой конфигурации описаны в разделе "Сохранить исходное имя узла HTTP" между обратным прокси-сервером и серверным веб-приложением. Рекомендуемая настройка для Служба приложений — следовать инструкциям в разделе "Пользовательский домен (рекомендуется)" в разделе "Настройка Служба приложений с помощью Шлюз приложений". Перезапись заголовка расположения в ответе, как описано в приведенном ниже примере, следует считать обходным решением и не устранять первопричину.
При отправке ответа перенаправления служба приложений использует то же имя узла в заголовке расположения своего ответа, что и в запросе, полученном от шлюза приложений. Таким образом, клиент выполняет запрос непосредственно contoso.azurewebsites.net/path2
, чтобы не проходить через шлюз приложений (contoso.com/path2
). Обход шлюза приложений нежелателен.
Эту проблему можно устранить, установив параметр имени узла в заголовке расположения в значение доменного имени шлюза приложений.
Ниже приведены действия по замене имени узла.
Создайте правило перезаписи с условием, которое оценивает наличие в заголовке расположения фрагмента "azurewebsites.net". Введите шаблон
(https?):\/\/.*azurewebsites\.net(.*)$
.Выполните перезапись заголовка расположения так, чтобы в нем было указано имя узла шлюза приложений. Для этого введите в
{http_resp_Location_1}://contoso.com{http_resp_Location_2}
качестве значения заголовка. Кроме того, можно также использовать переменную сервераhost
, чтобы задать имя узла в соответствии с исходным запросом.
Реализация безопасности заголовков HTTP для предотвращения возникновения уязвимостей
Вы можете устранить ряд уязвимостей системы безопасности, реализовав необходимые заголовки в ответе приложения. К этим заголовкам относятся X-XSS-Protection, Strict-Transport-Security и Content-Security-Policy. Задать эти заголовки для всех ответов можно с помощью шлюза приложений.
Удаление ненужных заголовков
Вам может понадобиться удалить заголовки, которые раскрывают конфиденциальную информацию из HTTP-ответа. Например, может потребоваться удалить такие сведения, как имя внутреннего сервера, операционная система или сведения о библиотеке. Для удаления этих заголовков можно использовать шлюз приложений:
Невозможно создать правило перезаписи для удаления заголовка узла. Если вы пытаетесь создать правило перезаписи с типом действия, заданным для удаления, и заголовок, заданный для узла, это приведет к ошибке.
Проверка наличия заголовка
Вы можете оценить HTTP-запрос или заголовок ответа на наличие заголовка или переменной сервера. Эта оценка будет полезна, если требуется выполнить перезапись заголовка только при наличии определенного заголовка.
Распространенные сценарии для переопределения URL-адресов
Выбор пути на основе параметров
Для выполнения сценариев, в которых необходимо выбрать внутренний пул на основе значения заголовка, части URL-адреса или строки запроса в запросе, можно использовать сочетание возможностей переопределения URL-адресов и маршрутизации на основе пути.
Для этого создайте набор перезаписи с условием, который проверяет наличие определенного параметра (строки запроса, заголовка и т. д.), а затем выполняет действие, в котором он изменяет URL-путь (убедитесь, что включена схема пути повторного вычисления). Затем набор перезаписи должен быть связан с правилом на основе пути. Правило на основе пути должно содержать те же URL-пути, которые указаны в наборе перезаписи и соответствующем серверном пуле.
Таким образом, набор перезаписи позволяет пользователям проверять определенный параметр и назначать ему новый путь, а правило на основе пути позволяет пользователям назначать серверные пулы этим путям. Если включена карта пути повторного определения, маршруты трафика зависят от пути, указанного в наборе перезаписи.
Пример использования с помощью строк запроса см. в разделе "Маршрут трафика" с помощью выбора пути на основе параметров на портале.
Перепись параметры строки запроса на основе URL-адреса
Рассмотрим сценарий веб-сайта для покупок, где видимая пользователю ссылка должна быть простой и удобочитаемой, но на внутреннем сервере требуются параметры строки запроса для отображения правильного содержимого.
В этом случае шлюз приложений может записывать параметры из URL-адреса и добавлять пары "ключ-значение" для строки запроса из URL-адреса. Предположим, что пользователю требуется переписать https://www.contoso.com/fashion/shirts
на https://www.contoso.com/buy.aspx?category=fashion&product=shirts
. Это можно сделать с помощью следующей конфигурации переопределения URL-адреса.
Условие — если переменная сервера uri_path
равна шаблону /(.+)/(.+)
Действие — задать URL-путь в значение buy.aspx
, а строку запроса — в значение category={var_uri_path_1}&product={var_uri_path_2}
Пошаговые инструкции по выполнению описанного выше сценария см. в статье Перезапись URL-адреса с помощью шлюза приложений на портале Azure
Распространенные ошибки конфигурации перезаписи
Включение сопоставления путей повторного выбора не допускается для основных правил маршрутизации запросов. Это позволяет предотвратить бесконечный цикл оценки для базового правила маршрутизации.
Необходимо иметь по крайней мере 1 правило условной перезаписи или 1 правило перезаписи, которое не включает функцию "Переоценка пути" для правил маршрутизации на основе путей, чтобы предотвратить бесконечный цикл оценки для правила маршрутизации на основе пути.
Входящие запросы будут завершаться кодом ошибки 500, если цикл создается динамически на основе входных данных клиента. Шлюз приложений продолжает обслуживать другие запросы без каких-либо ухудшений в таком сценарии.
Использование переопределения URL-адреса или перезаписи заголовка узла с брандмауэром веб-приложения (WAF_v2 SKU)
При настройке перезаписи URL-адресов или перезаписи заголовка узла оценка WAF происходит после изменения параметров заголовка запроса или URL-адреса (после перезаписи). При удалении конфигурации перезаписи URL-адреса или перезаписи заголовка узла в Шлюз приложений оценка WAF выполняется перед перезаписи заголовка (предварительной перезаписи). Этот порядок гарантирует, что правила WAF применяются к окончательному запросу, который будет получен внутренним пулом.
Например, предположим, что у вас есть следующее правило перезаписи заголовка для заголовка "Accept" : "text/html"
. Если значение заголовка "Accept"
равно "text/html"
, значение будет переписано на "image/png"
.
Здесь настроена только перезапись заголовков, в этом случае выполняется "Accept" : "text/html"
оценка WAF. Но при настройке перезаписи URL-адресов или перезаписи заголовка узла выполняется "Accept" : "image/png"
оценка WAF.
Сравнение переопределения URL-адреса и перенаправления URL-адреса
Для перезаписи URL-адреса Шлюз приложений перезаписывает URL-адрес перед отправкой запроса в серверную часть. Это не изменит то, что пользователи видят в браузере, так как изменения скрыты от пользователя.
Для перенаправления URL-адресов Шлюз приложений отправляет клиенту ответ перенаправления с новым URL-адресом. Это, в свою очередь, требует, чтобы клиент повторно отправлял свой запрос на новый URL-адрес, указанный в перенаправлении. URL-адрес, который пользователь видит в браузере, обновляет новый URL-адрес.
Ограничения
- Перезаписи не поддерживаются, если шлюз приложений настроен для перенаправления запросов или отображения пользовательской страницы ошибок.
- Имена заголовков запросов могут содержать буквенно-цифровые символы и дефисы. Имена заголовков, содержащих другие символы, будут удалены при отправке запроса на серверный целевой объект.
- Имена заголовков ответа могут содержать любые буквенно-цифровые символы и определенные символы, как определено в RFC 7230.
- Заголовки подключения и обновления не подлежат перезаписи
- Перезаписи не поддерживаются для ответов 4xx и 5xx, созданных непосредственно из Шлюз приложений