Apache. Документация на русском


Разделы:   1      2      3    4    5    6    7    8    9    10    11    12    13    14    15    16  

Раздел 2. Использование HTTP-сервера Apache

Пункты:   6    7    8    9      10      11    12    13    14    15    16    17    18    19    20    21    22    23    24    25    26  

 <         > 
  RU            EN  

Пункт 10. Как работают разделы «Каталог», «Местоположение» и «Файлы»

Директивы в файлах конфигурации могут применяться ко всему серверу или могут применяться только к определенным каталогам, файлам, хостам или URL-адресам. В этом документе описывается, как использовать контейнеры или .htaccess файлы раздела конфигурации для изменения области действия других директив конфигурации.

Типы контейнеров разделов конфигурации

Существует два основных типа контейнеров. Большинство контейнеров оцениваются для каждого запроса. Вложенные директивы применяются только для тех запросов, которые соответствуют контейнерам. <IfDefine> С другой стороны , контейнеры , <IfModule> и <IfVersion> оцениваются только при запуске и перезапуске сервера. Если их условия истинны при запуске, то прилагаемые директивы будут применяться ко всем запросам. Если условия неверны, вложенные директивы будут проигнорированы.

Директива <IfDefine> включает в себя директивы, которые будут применяться только в том случае, если в httpd командной строке определен соответствующий параметр. Например, при следующей конфигурации все запросы будут перенаправляться на другой сайт только в том случае, если сервер запущен с использованием httpd -DClosedForNow :

 <IfDefine ClosedForNow> 
 Перенаправить "/" "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> 
 # это происходит только в версиях выше или 
 # равных 2.4.0. 
</ЕслиВерсия> 

<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> вместе с их аналогами регулярных выражений применяют директивы к частям файловой системы. Директивы, заключенные в <Directory> секцию, применяются к названному каталогу файловой системы и всем подкаталогам этого каталога (а также к файлам в этих каталогах). Тот же эффект можно получить с помощью файлов .htaccess. Например, в следующей конфигурации индексы каталогов будут включены для /var/web/dir1 каталога и всех подкаталогов.

 <Directory "/var/web/dir1"> 
 Опции +Индексы 
</Directory> 

Директивы, заключенные в <Files> секцию, применяются к любому файлу с указанным именем, независимо от того, в каком каталоге он находится. Так, например, следующие директивы конфигурации при размещении в основной секции файла конфигурации будут запрещать доступ к любому файлу с указанным именем независимо от того, в каком каталоге он находится private.html . того, где он находится.

 <Файлы "private.html"> 
 Требовать все запрещенные 
</файлы> 

Для адресации файлов, находящихся в определенной части файловой системы, разделы <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"> 
 Требовать все запрещенные 
 </Files> 
</Directory> 

Контейнеры веб-пространства

Директива <Location> и ее аналог регулярного выражения , с другой стороны, изменяют конфигурацию контента в веб-пространстве. Например, следующая конфигурация запрещает доступ к любому URL-пути, начинающемуся с /private. В частности, это будет применяться к запросам на http://yoursite.example.com/private , http://yoursite.example.com/private123 и , http://yoursite.example.com/private/dir/file.html а также к любым другим запросам, начинающимся со /private строки.

 <LocationMatch "^/private"> 
 Требовать все запрещенные 
</LocationMatch> 

Директива <Location> не должна иметь ничего общего с файловой системой. Например, в следующем примере показано, как сопоставить определенный URL-адрес с внутренним обработчиком HTTP-сервера Apache, предоставленным mod_status . Никакой вызываемый файл server-status не должен существовать в файловой системе.

 <Location "/server-status"> 
 Статус сервера SetHandler 
</Location> 

Перекрывающееся веб-пространство

Чтобы иметь два перекрывающихся URL-адреса, необходимо учитывать порядок, в котором оцениваются определенные разделы или директивы. Для <Location> этого будет:

 <Местоположение "/foo"> </ 
Местоположение> 
<Местоположение "/foo/bar"> < 
/Местоположение> 

<Alias> es, с другой стороны, отображаются наоборот:

 Псевдоним "/foo/bar" "/srv/www/uncommon/bar" 
Псевдоним "/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-совместимые регулярные выражения при выборе совпадений. Но см. раздел ниже о слиянии конфигураций, чтобы узнать, как использование разделов регулярных выражений изменит применение директив.

Раздел подстановочных знаков без регулярных выражений, который изменяет конфигурацию всех пользовательских каталогов, может выглядеть следующим образом:

 <Directory "/home/*/public_html"> 
 Индексы параметров 
</Directory> 

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

 <FilesMatch "\.(?i:gif|jpe?g|png)$"> 
 Требовать все отклоненные 
</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/*')"> 
 Требовать отклонения всех 
</If> 

Что использовать Когда

Выбор между контейнерами файловой системы и контейнерами веб-пространства на самом деле довольно прост. При применении директив к объектам, находящимся в файловой системе, всегда используйте <Directory> или <Files> . При применении директив к объектам, которые не находятся в файловой системе (например, к веб-странице, сгенерированной из базы данных), используйте <Location> .

Важно никогда не использовать <Location> при попытке ограничить доступ к объектам в файловой системе. Это связано с тем, что множество различных расположений веб-пространства (URL) могут сопоставляться с одним и тем же расположением файловой системы, что позволяет обойти ваши ограничения. Например, рассмотрим следующую конфигурацию:

 <Location "/dir/"> 
 Требовать все запрещенные 
</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 веб-сайту с помощью прокси-сервера:

 <Прокси "http://www.example.com/*"> 
 Требуется хост yournetwork.example.com 
</Proxy> 

Какие директивы разрешены?

Чтобы узнать, какие директивы разрешены в каких типах разделов конфигурации, проверьте контекст директивы. Все, что разрешено в <Directory> разделах, также синтаксически разрешено в разделах <DirectoryMatch> , <Files> , <FilesMatch> , <Location> , <LocationMatch> , <Proxy> и . <ProxyMatch> Однако есть некоторые исключения:

  • Директива AllowOverride работает только в <Directory> разделах.
  • То FollowSymLinks и SymLinksIfOwnerMatch Options работают только в <Directory> разделах или .htaccess файлах.
  • Директиву Options нельзя использовать в разделах <Files> и <FilesMatch> .

Как объединяются разделы

Разделы конфигурации применяются в особом порядке. Поскольку это может существенно повлиять на интерпретацию директив конфигурации, важно понимать, как это работает.

Порядок объединения таков:

  1. <Directory> (кроме регулярных выражений) и .htaccess выполняться одновременно (с .htaccess переопределением , если разрешено <Directory> )
  2. <DirectoryMatch> <Directory "~"> )
  3. <Files> и <FilesMatch> делается одновременно
  4. <Location> и <LocationMatch> делается одновременно
  5. <If>

Некоторые важные замечания:

  • Кроме того <Directory> , внутри каждой группы разделы обрабатываются в порядке их появления в конфигурационных файлах. Например, запрос для /foo будет соответствовать <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 управляет своей собственной конфигурацией, и каждая из его директив в apache2.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 "/"> 
 Требовать все предоставленные 
</Location> 
# Упс! Этот раздел <Directory> не будет иметь никакого эффекта 
<Directory "/"> 
 <RequireAll> 
 Требовать всех разрешенных 
 Требовать не размещать badguy.example.com 
 </RequireAll> 
</Directory> 


 <         > 

Пункты:   6    7    8    9      10      11    12    13    14    15    16    17    18    19    20    21    22    23    24    25    26  

Рейтинг@Mail.ru