Spec-Zone.ru › Apache HTTP Server

Переменные окружения в Apache

На работу HTTP-сервера Apache влияют два вида переменных окружения.

Во-первых, существуют переменные окружения, которыми управляет базовая операционная система. Они задаются до запуска сервера. Их можно использовать при подстановке значений в файлах конфигурации, а также при необходимости передавать сценариям CGI и SSI с помощью директивы PassEnv.

Во-вторых, HTTP-сервер Apache предоставляет механизм хранения информации в именованных переменных, которые также называются переменными окружения. Эту информацию можно использовать для управления различными операциями, например ведением журналов или контролем доступа. Переменные также служат механизмом обмена данными с внешними программами, такими как сценарии CGI. В этом документе рассматриваются различные способы работы с этими переменными и их использования.

Хотя эти переменные называются переменными окружения, они отличаются от переменных окружения, которыми управляет базовая операционная система. Вместо этого они хранятся и обрабатываются во внутренней структуре Apache. Они становятся настоящими переменными окружения операционной системы только при передаче сценариям CGI и Server Side Include. Если требуется изменить окружение операционной системы, в котором работает сам сервер, необходимо использовать стандартные средства управления окружением, предоставляемые оболочкой операционной системы.

Задание переменных окружения

Связанные модули Связанные директивы
  • mod_cache
  • mod_env
  • mod_rewrite
  • mod_setenvif
  • mod_unique_id
  • BrowserMatch
  • BrowserMatchNoCase
  • PassEnv
  • RewriteRule
  • SetEnv
  • SetEnvIf
  • SetEnvIfNoCase
  • UnsetEnv

Основные операции с переменными окружения

Самый простой способ задать переменную окружения в Apache — использовать безусловную директиву SetEnv. Переменные также можно передавать из окружения оболочки, запустившей сервер, с помощью директивы PassEnv.

Условные настройки для каждого запроса

Для большей гибкости директивы, предоставляемые mod_setenvif, позволяют задавать переменные окружения отдельно для каждого запроса в зависимости от его характеристик. Например, переменную можно задать, только если запрос отправляет определённый браузер (User-Agent), либо только при наличии определённого заголовка Referer [sic]. Ещё больше возможностей предоставляет mod_rewrite: его RewriteRule использует параметр [E=...] для задания переменных окружения.

Уникальные идентификаторы

Наконец, mod_unique_id задаёт для каждого запроса переменную окружения UNIQUE_ID, значение которой гарантированно уникально среди «всех» запросов при весьма специфических условиях.

Стандартные переменные CGI

Помимо всех переменных окружения, заданных в конфигурации Apache и переданных из оболочки, сценарии CGI и страницы SSI получают набор переменных окружения с метаинформацией о запросе, предусмотренной спецификацией CGI.

Некоторые предостережения

  • Директивы управления окружением не позволяют переопределять или изменять стандартные переменные CGI.
  • При использовании suexec для запуска сценариев CGI перед их запуском окружение очищается и в нём остаётся только набор безопасных переменных. Список безопасных переменных определяется во время компиляции в suexec.c.
  • Для обеспечения переносимости имена переменных окружения могут содержать только буквы, цифры и символ подчёркивания. Кроме того, имя не может начинаться с цифры. Символы, не соответствующие этому ограничению, при передаче сценариям CGI и страницам SSI заменяются символом подчёркивания.
  • Особый случай — заголовки HTTP, которые передаются сценариям CGI и подобным им программам через переменные окружения (см. ниже). Они преобразуются в верхний регистр, а дефисы заменяются символами подчёркивания; если заголовок содержит любой другой (недопустимый) символ, он отбрасывается без уведомления. Способ обхода этого ограничения см. ниже.
  • Директива SetEnv выполняется на позднем этапе обработки запроса, поэтому такие директивы, как SetEnvIf и RewriteCond, не увидят заданные ею переменные.
  • Когда сервер выполняет поиск пути с помощью внутреннего подзапроса, например при поиске DirectoryIndex или создании списка каталога с помощью mod_autoindex, переменные окружения, заданные для текущего запроса, не наследуются подзапросом. Кроме того, директивы SetEnvIf не вычисляются отдельно в подзапросе из-за этапов API, на которых действует mod_setenvif.

Использование переменных окружения

Связанные модули Связанные директивы
  • mod_authz_host
  • mod_cgi
  • mod_ext_filter
  • mod_headers
  • mod_include
  • mod_log_config
  • mod_rewrite
  • Require
  • CustomLog
  • Allow
  • Deny
  • ExtFilterDefine
  • Header
  • LogFormat
  • RewriteCond
  • RewriteRule

Сценарии CGI

Одно из основных назначений переменных окружения — передача информации сценариям CGI. Как упоминалось выше, окружение, передаваемое сценариям CGI, включает стандартную метаинформацию о запросе, а также любые переменные, заданные в конфигурации Apache. Подробнее см. в руководстве по CGI.

Страницы SSI

Документы, обрабатываемые сервером (SSI) с помощью фильтра INCLUDES модуля mod_include, могут выводить переменные окружения с помощью элемента echo, а также использовать их в элементах управления потоком, чтобы показывать части страницы в зависимости от характеристик запроса. Apache также предоставляет страницам SSI стандартные переменные окружения CGI, упомянутые выше. Подробнее см. в руководстве по SSI.

Контроль доступа

Доступ к серверу можно контролировать на основе переменных окружения с помощью директив Require env и Require not env. В сочетании с SetEnvIf это позволяет гибко управлять доступом к серверу в зависимости от характеристик клиента. Например, с помощью этих директив можно запретить доступ определённому браузеру (User-Agent).

Условное ведение журнала

Переменные окружения можно записывать в журнал доступа с помощью параметра %e директивы LogFormat. Кроме того, решение о том, записывать ли запросы в журнал, можно принимать на основе значений переменных окружения, используя условную форму директивы CustomLog. В сочетании с SetEnvIf это позволяет гибко управлять тем, какие запросы записываются в журнал. Например, можно не записывать запросы к файлам, имена которых заканчиваются на gif, или записывать только запросы от клиентов за пределами вашей подсети.

Условные заголовки ответа

Директива Header может проверять наличие или отсутствие переменной окружения, чтобы определить, следует ли добавлять определённый заголовок HTTP в ответ клиенту. Это позволяет, например, отправлять определённый заголовок ответа только в том случае, если соответствующий заголовок получен в запросе клиента.

Активация внешних фильтров

Внешние фильтры, настроенные с помощью mod_ext_filter и директивы ExtFilterDefine, можно активировать при наличии переменной окружения, используя параметры disableenv= и enableenv=.

Перезапись URL

Форма %{ENV:variable} для TestString в RewriteCond позволяет механизму перезаписи mod_rewrite принимать решения на основе переменных окружения. Обратите внимание, что переменные, доступные в mod_rewrite без префикса ENV:, на самом деле не являются переменными окружения. Это специальные переменные mod_rewrite, к которым другие модули доступа не имеют.

Переменные окружения специального назначения

Проблемы совместимости привели к появлению механизмов, позволяющих изменять поведение Apache при взаимодействии с определёнными клиентами. Чтобы сделать эти механизмы максимально гибкими, они активируются заданием переменных окружения, обычно с помощью BrowserMatch, хотя, например, можно также использовать SetEnv и PassEnv.

downgrade-1.0

Заставляет обрабатывать запрос как запрос HTTP/1.0, даже если он использует более позднюю версию протокола.

force-gzip

Если активирован фильтр DEFLATE, эта переменная окружения заставит сервер игнорировать настройку accept-encoding браузера и всегда отправлять сжатый вывод.

force-no-vary

Заставляет удалить все поля Vary из заголовка ответа перед его отправкой клиенту. Некоторые клиенты неправильно интерпретируют это поле; задание этой переменной позволяет обойти проблему. Задание этой переменной также подразумевает force-response-1.0.

force-response-1.0

Заставляет отправлять ответ HTTP/1.0 клиентам, отправившим запрос HTTP/1.0. Изначально эта возможность была реализована из-за проблемы с прокси-серверами AOL. Некоторые клиенты HTTP/1.0 могут работать некорректно при получении ответа HTTP/1.1; этот параметр позволяет обеспечить с ними совместимость.

gzip-only-text/html

Если задать для этой переменной значение "1", выходной фильтр DEFLATE, предоставляемый mod_deflate, будет отключён для типов содержимого, отличных от text/html. Если вместо этого вы хотите использовать статически сжатые файлы, mod_negotiation также проверяет значение переменной (не только для gzip, но и для всех кодировок, отличных от "identity").

no-gzip

Если эта переменная задана, фильтр DEFLATE модуля mod_deflate отключается, а mod_negotiation перестаёт передавать закодированные ресурсы.

no-cache

Доступно в версиях 2.2.12 и новее

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

nokeepalive

Если эта переменная задана, KeepAlive отключается.

prefer-language

Эта переменная влияет на поведение mod_negotiation. Если она содержит языковой тег (например, en, ja или x-klingon), mod_negotiation пытается отправить вариант на этом языке. Если такого варианта нет, применяется обычный процесс согласования содержимого.

redirect-carefully

Заставляет сервер проявлять большую осторожность при отправке перенаправления клиенту. Обычно этот параметр используется, если известно, что у клиента возникают проблемы с обработкой перенаправлений. Изначально он был реализован из-за проблем программного обеспечения Microsoft WebFolders, которое некорректно обрабатывает перенаправления для ресурсов каталогов при использовании методов DAV.

suppress-error-charset

Доступно в версиях новее 2.0.54

Когда Apache перенаправляет клиента в ответ на его запрос, ответ содержит текст, который отображается, если клиент не может (или не пытается) перейти по перенаправлению автоматически. Обычно Apache указывает для этого текста используемую кодировку символов — ISO-8859-1.

Однако если перенаправление ведёт на страницу с другой кодировкой символов, некоторые неисправленные версии браузеров пытаются использовать кодировку текста перенаправления, а не целевой страницы. Например, из-за этого греческий текст может отображаться неправильно.

Задание этой переменной окружения заставляет Apache не указывать кодировку символов для текста перенаправления, и такие неисправленные браузеры будут корректно использовать кодировку целевой страницы.

Примечание по безопасности

Отправка страниц ошибок без указанной кодировки символов может позволить выполнить межсайтовую скриптовую атаку в браузерах (MSIE), которые не следуют спецификации HTTP/1.1 и пытаются «угадать» кодировку по содержимому. Такие браузеры легко обмануть и заставить использовать кодировку UTF-7; содержимое UTF-7 из входных данных (например, из URI запроса) не будет экранировано обычными средствами, предназначенными для защиты от межсайтовых скриптовых атак.

force-proxy-request-1.0, proxy-nokeepalive, proxy-sendchunked, proxy-sendcl, proxy-chain-auth, proxy-interim-response, proxy-initial-not-pooled

Эти директивы изменяют поведение протокола mod_proxy. Дополнительные сведения см. в документации mod_proxy и mod_proxy_http.

ap_trust_cgilike_cl

Доступно в версии 2.4.59 и новее

Эта переменная позволяет сценарию, работающему в модуле типа CGI, передавать собственный заголовок HTTP-ответа Content-Length. Её следует задавать только в разделах конфигурации, содержащих доверенные сценарии.

Примеры

Передача некорректных заголовков сценариям CGI

Начиная с версии 2.4 Apache строже обрабатывает преобразование заголовков HTTP в переменные окружения в mod_cgi и других модулях: ранее любые недопустимые символы в именах заголовков просто заменялись символами подчёркивания. Это создавало потенциальную возможность межсайтовых скриптовых атак путём внедрения заголовков (см. необычные веб-ошибки, слайды 19–20).

Если необходимо поддерживать клиента, который отправляет некорректные заголовки и которого нельзя исправить, простой обходной способ с использованием mod_setenvif и mod_headers позволит принимать эти заголовки:

#
# The following works around a client sending a broken Accept_Encoding
# header.
#
SetEnvIfNoCase ^Accept.Encoding$ ^(.*)$ fix_accept_encoding=$1
RequestHeader set Accept-Encoding %{fix_accept_encoding}e env=fix_accept_encoding

Изменение поведения протокола для некорректно работающих клиентов

В более ранних версиях для устранения известных проблем клиентов рекомендовалось добавить следующие строки в httpd.conf. Поскольку такие клиенты больше не встречаются, эта настройка, вероятно, уже не нужна.

#
# The following directives modify normal HTTP response behavior.
# The first directive disables keepalive for Netscape 2.x and browsers that
# spoof it. There are known problems with these browser implementations.
# The second directive is for Microsoft Internet Explorer 4.0b2
# which has a broken HTTP/1.1 implementation and does not properly
# support keepalive when it is used on 301 or 302 (redirect) responses.
#
BrowserMatch "Mozilla/2" nokeepalive
BrowserMatch "MSIE 4\.0b2;" nokeepalive downgrade-1.0 force-response-1.0

#
# The following directive disables HTTP/1.1 responses to browsers which
# are in violation of the HTTP/1.0 spec by not being able to understand a
# basic 1.1 response.
#
BrowserMatch "RealPlayer 4\.0" force-response-1.0
BrowserMatch "Java/1\.0" force-response-1.0
BrowserMatch "JDK/1\.0" force-response-1.0

Не записывать запросы изображений в журнал доступа

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

SetEnvIf Request_URI \.gif image-request
SetEnvIf Request_URI \.jpg image-request
SetEnvIf Request_URI \.png image-request
CustomLog "logs/access_log" common env=!image-request

Защита от «кражи изображений»

В этом примере показано, как запретить пользователям с других серверов использовать изображения с вашего сервера в качестве встроенных изображений на своих страницах. Эта конфигурация не рекомендуется, но может быть полезна в ограниченных случаях. Предполагается, что все изображения находятся в каталоге /web/images.

SetEnvIf Referer "^http://www\.example\.com/" local_referal
# Allow browsers that do not send Referer info
SetEnvIf Referer "^$" local_referal
<Directory "/web/images">
    Require env local_referal
</Directory>

Дополнительные сведения об этом способе см. в руководстве «Как не позволить другим сайтам использовать ваши изображения» на ServerWatch.

© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/env.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API