Разделы конфигурации
Директивы в файлах конфигурации могут применяться ко всему серверу или быть ограничены для применения только к определённым каталогам, файлам, хостам или URL-адресам. Этот документ описывает, как использовать контейнеры разделов конфигурации или .htaccess файлы для изменения области действия других директив конфигурации.
Типы контейнеров разделов конфигурации
| Связанные модули | Связанные директивы |
|---|---|
Существует два основных типа контейнеров. Большинство контейнеров оцениваются для каждого запроса. Заключённые директивы применяются только для запросов, которые соответствуют контейнерам. Контейнеры <IfDefine>, <IfModule>, и <IfVersion>, с другой стороны, оцениваются только при запуске и перезапуске сервера. Если их условия истинны при запуске, то заключённые директивы будут применяться ко всем запросам. Если условия ложны, заключённые директивы будут проигнорированы.
Директива <IfDefine> заключает директивы, которые будут применяться только в том случае, если соответствующий параметр определён в командной строке httpd. Например, при следующей конфигурации все запросы будут перенаправлены на другой сайт только в том случае, если сервер запущен с помощью httpd -DClosedForNow.
<IfDefine ClosedForNow>
Redirect "/" "http://otherserver.example.com/"
</IfDefine> Директива <IfModule> очень похожа, за исключением того, что она заключает директивы, которые будут применяться только в том случае, если определённый модуль доступен на сервере. Модуль должен быть либо статически скомпилирован в сервер, либо он должен быть динамически скомпилирован, и его строка LoadModule должна стоять ранее в файле конфигурации. Эту директиву следует использовать только в том случае, если вам нужно, чтобы ваш файл конфигурации работал, независимо от того, установлены ли определённые модули. Её не следует использовать для заключения директив, которые вы хотите использовать всегда, так как она может подавлять полезные сообщения об ошибках, связанные с отсутствующими модулями.
В следующем примере директива MimeMagicFile будет применена только в том случае, если mod_mime_magic доступен.
<IfModule mod_mime_magic.c>
MimeMagicFile "conf/magic"
</IfModule> Директива <IfVersion> очень похожа на <IfDefine> и <IfModule>, за исключением того, что она заключает директивы, которые будут применяться только в том случае, если выполняется определённая версия сервера. Этот модуль предназначен для использования в наборах тестов и больших сетях, которые должны работать с различными версиями httpd и различными конфигурациями.
<IfVersion >= 2.4>
# this happens only in versions greater or
# equal 2.4.0.
</IfVersion> <IfDefine>, <IfModule>, и <IfVersion> могут применять отрицательные условия, предваряя их тест символом "!". Кроме того, эти разделы могут быть вложены для достижения более сложных ограничений.
Файловая система, веб-пространство и булевы выражения
Наиболее часто используемые контейнеры разделов конфигурации — те, которые изменяют конфигурацию определённых мест в файловой системе или веб-пространстве. Во-первых, важно понимать разницу между ними. Файловая система — это представление ваших дисков, как их видит ваша операционная система. Например, при стандартной установке Apache httpd находится по адресу /usr/local/apache2 в файловой системе Unix или "c:/Program Files/Apache Group/Apache2" в файловой системе Windows. (Обратите внимание, что косые черты должны всегда использоваться в качестве разделителя путей в файлах конфигурации Apache httpd, даже для Windows.) В отличие от этого, веб-пространство — это представление вашего сайта, как он предоставляется веб-сервером и отображается клиенту. Так что путь /dir/ в веб-пространстве соответствует пути /usr/local/apache2/htdocs/dir/ в файловой системе при стандартной установке Apache httpd на Unix. Веб-пространство необязательно должно отображаться напрямую на файловой системе, так как веб-страницы могут динамически генерироваться из баз данных или других мест.
Контейнеры файловой системы
Директивы <Directory> и <Files> вместе со своими аналогами regex применяют директивы к частям файловой системы. Директивы, заключённые в раздел <Directory> , применяются к указанному каталогу файловой системы и всем его подкаталогам (а также к файлам в этих каталогах). Тот же эффект можно получить с помощью файлов .htaccess. Например, в следующей конфигурации индексы каталогов будут включены для каталога /var/web/dir1 и всех его подкаталогов.
<Directory "/var/web/dir1">
Options +Indexes
</Directory> Директивы, заключённые в разделе <Files> , применяются ко всем файлам с указанным именем, независимо от того, в каком каталоге они находятся. Таким образом, например, следующие директивы конфигурации, помещённые в основной раздел файла конфигурации, запретят доступ к любому файлу с именем private.html независимо от его расположения.
<Files "private.html">
Require all denied
</Files> Для обращения к файлам, находящимся в определённой части файловой системы, разделы <Files> и <Directory> могут быть объединены. Например, следующая конфигурация запретит доступ к /var/web/dir1/private.html, /var/web/dir1/subdir2/private.html, /var/web/dir1/subdir3/private.html и любым другим экземплярам private.html , найденным в каталоге /var/web/dir1/.
<Directory "/var/web/dir1">
<Files "private.html">
Require all denied
</Files>
</Directory> Контейнеры веб-пространства
Директива <Location> и её аналог regex , с другой стороны, изменяют конфигурацию для содержимого в веб-пространстве. Например, следующая конфигурация предотвращает доступ к любому URL-пути, начинающемуся с /private. В частности, она будет применяться к запросам http://yoursite.example.com/private, http://yoursite.example.com/private123, http://yoursite.example.com/private/dir/file.html и любым другим запросам, начинающимся с строки /private.
<LocationMatch "^/private">
Require all denied
</LocationMatch> Директива <Location> может не иметь никакого отношения к файловой системе. Например, следующий пример показывает, как сопоставить определённый URL-адрес с внутренним обработчиком Apache HTTP Server, предоставленным mod_status. Файл с именем server-status не обязательно должен существовать в файловой системе.
<Location "/server-status">
SetHandler server-status
</Location> Перекрывающиеся веб-пространства
Для того, чтобы иметь два перекрывающихся URL, необходимо учесть порядок оценки определённых разделов или директив. Для <Location> это будет:
<Location "/foo"> </Location> <Location "/foo/bar"> </Location>
<Alias> с другой стороны, сопоставляются наоборот:
Alias "/foo/bar" "/srv/www/uncommon/bar" Alias "/foo" "/srv/www/common/foo"
То же самое относится к директивам ProxyPass.
ProxyPass "/special-area" "http://special.example.com" smax=5 max=10 ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On
Подстановочные знаки и регулярные выражения
Директивы <Directory>, <Files>, и <Location> могут использовать символы подстановки в стиле оболочки, как в fnmatch из стандартной библиотеки C. Символ "*" соответствует любой последовательности символов, "?" соответствует любому одиночному символу, а "[seq]" соответствует любому символу в seq. Символ "/" не будет сопоставлен ни одним подстановочным знаком; он должен быть указан явно.
Если требуется более гибкое соответствие, каждый контейнер имеет аналог регулярного выражения (regex) <DirectoryMatch>, <FilesMatch>, и <LocationMatch> , которые позволяют использовать совместимые с Perl регулярные выражения для выбора соответствий. Но см. раздел ниже о слиянии конфигурации, чтобы узнать, как использование разделов regex изменит способ применения директив.
Раздел с подстановочными знаками без регулярных выражений, который изменяет конфигурацию всех каталогов пользователей, может выглядеть следующим образом:
<Directory "/home/*/public_html">
Options Indexes
</Directory> Используя разделы регулярных выражений, мы можем запретить доступ к множеству типов файлов изображений одновременно:
<FilesMatch "\.(?i:gif|jpe?g|png)$">
Require all denied
</FilesMatch> Регулярные выражения, содержащие **именованные группы и обратные ссылки**, добавляются в среду с соответствующим именем в верхнем регистре. Это позволяет ссылаться на элементы путей имен файлов и URL-адресов внутри выражений и модулей, таких как mod_rewrite.
<DirectoryMatch "^/var/www/combined/(?<SITENAME>[^/]+)">
Require ldap-group "cn=%{env:MATCH_SITENAME},ou=combined,o=Example"
</DirectoryMatch> Булевы выражения
Директива <If> изменяет конфигурацию в зависимости от условия, которое может быть выражено булевым выражением. Например, следующая конфигурация запрещает доступ, если заголовок HTTP Referer не начинается с "http://www.example.com/".
<If "!(%{HTTP_REFERER} -strmatch 'http://www.example.com/*')">
Require all denied
</If> Когда использовать что
Выбор между контейнерами файловой системы и контейнерами веб-пространства достаточно прост. При применении директив к объектам, которые находятся в файловой системе, всегда используйте <Directory> или <Files>. При применении директив к объектам, которые не находятся в файловой системе (например, веб-страница, сгенерированная из базы данных), используйте <Location>.
Важно никогда не использовать <Location> при попытке ограничить доступ к объектам в файловой системе. Это связано с тем, что несколько различных мест веб-пространства (URL) могут отображаться на одно и то же место в файловой системе, что позволяет обойти ваши ограничения. Например, рассмотрите следующую конфигурацию:
<Location "/dir/">
Require all denied
</Location> Это работает нормально, если запрос направлен на http://yoursite.example.com/dir/. Но что, если вы работаете с файловой системой без учёта регистра? Тогда ваше ограничение можно легко обойти, запросив http://yoursite.example.com/DIR/. Директива <Directory>, в отличие от неё, будет применяться к любому содержимому, предоставляемому из этого местоположения, независимо от того, как оно вызывается. (Исключением являются ссылки на файловую систему. Один и тот же каталог может быть помещён в несколько частей файловой системы с помощью символических ссылок. Директива <Directory> будет следовать за символической ссылкой, не сбрасывая путь. Поэтому для максимальной безопасности символические ссылки следует отключить с помощью соответствующей директивы Options.)
Если вы думаете, что всё это не относится к вам, потому что вы используете файловую систему, чувствительную к регистру, помните, что есть много других способов отобразить несколько мест веб-пространства на одно и то же место в файловой системе. Поэтому вы всегда должны использовать контейнеры файловой системы, когда это возможно. Однако есть одно исключение из этого правила. Размещение ограничений конфигурации в разделе <Location "/"> совершенно безопасно, потому что этот раздел будет применяться ко всем запросам независимо от конкретного URL-адреса.
Вложение разделов
Некоторые типы секций могут быть вложены в другие типы секций. С одной стороны, <Files> может использоваться внутри <Directory>. С другой стороны, <If> может использоваться внутри секций <Directory>, <Location>, и <Files> (но не внутри другой <If>). Регулярные выражения, соответствующие именованным секциям, ведут себя аналогично.
Вложенные секции объединяются после невложенных секций того же типа.
Виртуальные хосты
Контейнер <VirtualHost> включает директивы, которые применяются к определённым хостам. Это полезно при обслуживании нескольких хостов с одного компьютера с разной конфигурацией для каждого. Для получения дополнительной информации см. Документацию по виртуальным хостам.
Прокси
Контейнеры <Proxy> и <ProxyMatch> применяют включённые директивы конфигурации только к сайтам, доступ к которым осуществляется через прокси-сервер mod_proxy, соответствующие указанному URL. Например, следующая конфигурация позволит только подмножеству клиентов получить доступ к сайту www.example.com через прокси-сервер:
<Proxy "http://www.example.com/*">
Require host yournetwork.example.com
</Proxy> Какие директивы разрешены?
Чтобы узнать, какие директивы разрешены в каких типах секций конфигурации, проверьте контекст директивы. Всё, что разрешено в секциях <Directory>, также синтаксически разрешено в секциях <DirectoryMatch>, <Files>, <FilesMatch>, <Location>, <LocationMatch>, <Proxy>, и <ProxyMatch>. Однако есть некоторые исключения:
- Директива
AllowOverrideработает только в секциях<Directory>. - Директивы
FollowSymLinksиSymLinksIfOwnerMatchOptionsработают только в секциях<Directory>или файлах.htaccess. - Директива
Optionsне может использоваться в секциях<Files>и<FilesMatch>.
Объединение секций
Секции конфигурации применяются в очень определённом порядке. Поскольку это может существенно повлиять на то, как интерпретируются директивы конфигурации, важно понять, как это работает.
Порядок объединения:
-
<Directory>(кроме регулярных выражений) и.htaccessвыполняются одновременно (с.htaccess, если разрешено, переопределяющие<Directory>). -
<DirectoryMatch>(и<Directory "~">). -
<Files>и<FilesMatch>выполняются одновременно. -
<Location>и<LocationMatch>выполняются одновременно. -
<If>.
Некоторые важные замечания:
- Помимо
<Directory>, в каждой группе секции обрабатываются в порядке их появления в файлах конфигурации. Например, запрос к /foo/bar будет соответствовать<Location "/foo/bar">и<Location "/foo">(группа 4 в данном случае): обе секции будут оценены, но в порядке их появления в файлах конфигурации. -
<Directory>(группа 1 выше) обрабатывается в порядке от самого короткого до самого длинного компонента каталога. Например,<Directory "/var/web/dir">будет обработана до<Directory "/var/web/dir/subdir">. - Если несколько секций
<Directory>применяются к одному каталогу, они обрабатываются в порядке следования в файле конфигурации. - Конфигурации, включенные с помощью директивы
Include, будут обрабатываться так, как будто они находятся внутри файла включения в месте директивыInclude. - Секции внутри секций
<VirtualHost>применяются после соответствующих секций вне определения виртуального хоста. Это позволяет виртуальным хостам переопределять основную конфигурацию сервера. - Когда запрос обрабатывается
mod_proxy, контейнер<Proxy>занимает место контейнера<Directory>в порядке обработки.
Техническое примечание
На самом деле выполняется последовательность<Location>/<LocationMatch>, непосредственно перед фазой перевода имён (где Aliases и DocumentRoots используются для сопоставления URL с именами файлов). Результаты этой последовательности полностью отбрасываются после завершения перевода. Взаимосвязь между модулями и секциями конфигурации
Часто возникает вопрос о том, как и когда обрабатываются директивы конкретных модулей, таких как mod_rewrite, после прочтения о том, как объединяются секции конфигурации. Ответ нетривиален и требует некоторого введения. Каждый модуль httpd управляет собственной конфигурацией, и каждая его директива в httpd.conf задаёт один фрагмент конфигурации в конкретном контексте. httpd не выполняет команду при её чтении.
Во время выполнения ядро httpd перебирает определённые секции конфигурации в описанном выше порядке, чтобы определить, какие из них применимы к текущему запросу. Когда первая секция соответствует, она считается текущей конфигурацией для этого запроса. Если последующая секция также соответствует, то каждый модуль с директивой в любой из секций получает возможность объединить свою конфигурацию между двумя секциями. Результатом является третья конфигурация, и процесс продолжается, пока не будут обработаны все секции конфигурации.
После этого шага начинается «реальная» обработка HTTP-запроса: каждый модуль получает возможность выполнить любые задачи. Они могут получить свою окончательную объединённую конфигурацию из ядра httpd, чтобы определить, как им следует действовать.
Пример поможет визуализировать весь процесс. Следующая конфигурация использует директиву Header модуля mod_headers для установки определённого HTTP-заголовка. Какое значение httpd установит в заголовке CustomHeaderName для запроса к /example/index.html?
<Directory "/">
Header set CustomHeaderName one
<FilesMatch ".*">
Header set CustomHeaderName three
</FilesMatch>
</Directory>
<Directory "/example">
Header set CustomHeaderName two
</Directory> -
Directory"/" соответствует, и создаётся начальная конфигурация для установки заголовкаCustomHeaderNameсо значениемone. -
Directory"/example" соответствует, и так какmod_headersуказывает в своём коде на переопределение при объединении, создаётся новая конфигурация для установки заголовкаCustomHeaderNameсо значениемtwo. -
FilesMatch".*" соответствует, и возникает ещё один момент объединения, что приводит к установке заголовкаCustomHeaderNameсо значениемthree. - В конечном итоге, на следующих этапах обработки HTTP-запроса,
mod_headersбудет вызван и получит конфигурацию для установки заголовкаCustomHeaderNameсо значениемthree.mod_headersобычно использует эту конфигурацию для выполнения своей задачи, а именно для установки заголовка foo. Это не означает, что модуль не может выполнить более сложные действия, например, отбрасывать директивы, так как они не нужны или устарели, и т. д.
Это справедливо и для .htaccess, поскольку они имеют тот же приоритет, что и Directory в порядке объединения. Важно понять, что секции конфигурации, такие как Directory и FilesMatch не сравнимы с директивами конкретных модулей, такими как Header или RewriteRule, так как они действуют на разных уровнях.
Некоторые полезные примеры
Ниже приведён искусственный пример, демонстрирующий порядок объединения. Предполагая, что все они применяются к запросу, директивы в этом примере будут применены в порядке A > B > C > D > E.
<Location "/">
E
</Location>
<Files "f.html">
D
</Files>
<VirtualHost *>
<Directory "/a/b">
B
</Directory>
</VirtualHost>
<DirectoryMatch "^.*b$">
C
</DirectoryMatch>
<Directory "/a/b">
A
</Directory> Для более конкретного примера рассмотрим следующее. Независимо от любых ограничений доступа, установленных в секциях <Directory>, секция <Location> будет оценена последней и позволит неограниченный доступ к серверу. Другими словами, порядок объединения важен, поэтому будьте осторожны!
<Location "/">
Require all granted
</Location>
# Whoops! This <Directory> section will have no effect
<Directory "/">
<RequireAll>
Require all granted
Require not host badguy.example.com
</RequireAll>
</Directory>
© 2018 The Apache Software Foundation
Licensed under the Apache License, Version 2.0.
https://httpd.apache.org/docs/2.4/en/sections.html