Как Apache объединяет несколько соответствующих разделов Location
Я работаю над некоторой базовой конфигурацией Apache, но я не понимаю точно, как Apache объединяет разные <Location>
разделы, когда несколько из них соответствуют URL входящих запросов. Документация apache в главе "Как объединяются разделы" немного сбивает с толку, когда дело касается порядка / приоритета нескольких соответствующих разделов одного типа.
Например, представьте следующую конфигурацию apache (игнорируйте, имеет ли смысл фактическое содержимое, меня интересует только порядок применения каждого правила / раздела):
<Location / >
ProxyPass http://backend.com/
Order allow,deny
Satisfy any
</Location>
<Location /sub/foo>
Order allow,deny
</Location>
<Location /sub >
Order deny,allow
Require valid-user
Satisfy all
</Location>
<Location /doesnt/match >
ProxyPass !
</Location>
Теперь, если клиент делает запрос /sub/foobar
какая окончательная конфигурация будет применена к этому запросу?
Является ли примененная конфигурация эквивалентом:
# All the directives contained in all the matchin Locations in declaration order
ProxyPass http://backend.com/
Order allow,deny
Satisfy any
Order allow,deny
Order deny,allow
Require valid-user
Satisfy all
или, может быть
# same as above, but with longest matching path last
ProxyPass http://backend.com/
Order allow,deny
Satisfy any
Order deny,allow
Require valid-user
Satisfy all
Order allow,deny
или что-то совершенно другое.
Спасибо за вашу помощь, я действительно запутался.
2 ответа
Порядок слияния довольно сложен, и его легко обнаружить с помощью исключений... Документ Apache " Как объединяются разделы"
Согласно этой документации, порядок объединения разделов выполняется путем обработки всех соответствующих записей для каждого типа соответствия в том порядке, в котором они встречаются в файлах конфигурации, а затем перехода к следующему типу (за исключением
Порядок типов Directory
, DirectoryMatch
, Files
, и наконец Location
, Более поздние совпадения перезаписывают более ранние совпадения. (*ProxyPass и Alias снова обрабатываются по-разному, см. Примечание в конце)
И есть несколько важных исключений из этих правил, которые применяются к использованию ProxyPass и ProxyPass в разделе
Итак, из приведенного выше примера запрос http://somehost.com/sub/foobar с помощью следующей конфигурации;
<Location / >
ProxyPass http://backend.com/
Order allow,deny
Satisfy any
</Location>
<Location /sub/foo>
Order allow,deny
</Location>
<Location /sub >
Order deny,allow
Require valid-user
Satisfy all
</Location>
<Location /doesnt/match >
ProxyPass !
</Location>
Это будет накапливать следующие директивы....
ProxyPass http://backend.com/
Order allow,deny
Satisfy any
Order allow,deny
Order deny,allow
Require valid-user
Satisfy all
С последующими совпадениями удаляются предыдущие дубликаты, в результате чего;
ProxyPass http://backend.com/
Order deny,allow
Require valid-user
Satisfy all
объяснение
Более поздние совпадения перезаписывают более ранние совпадения, за исключением <Directory>
где совпадения обрабатываются в порядке: от самого короткого компонента каталога до самого длинного.
Так, например,
<Directory /var/web/dir>
будет обработан раньше<Directory /var/web/dir/subdir>
независимо от того, в каком порядке эти директивы были указаны в конфигурации, выигрывает более конкретное совпадение.
Любое соответствие Location
директива всегда будет переопределять ранее соответствующий Directory
директивы.
Основная идея заключается в том, что для запроса, как GET /some/http/request.html
внутренне он будет переведен в местоположение в файловой системе через Alias
, ScriptAlias
или для нормального расположения файла под DocumentRoot
для VirtualHost, что соответствует.
Таким образом, запрос будет иметь следующие свойства, которые он использует для сопоставления:Location: /some/http/request.html
File: /var/www/html/mysite/some/http/request.html
Directory: /var/www/html/mysite/some/http
Apache затем будет применять по очереди все Directory
совпадает, в порядке специфичности каталога, от конфигурации, а затем, в свою очередь, применяется DirectoryMatch
, Files
, и наконец Location
соответствует в том порядке, в котором они встречаются.
Так Location
Переопределение Files
, который переопределяет DirectoryMatch
с сопоставлением путей Directory
на самом низком приоритете. Следовательно, в вашем примере выше, запрос /sub/foobar
будет соответствовать первым 3 местоположениям по порядку, следовательно, последний выигрывает для конфликтующих директив.
(Вы правы, что из документов неясно, как решаются некоторые крайние случаи, возможно, что любой allow from *
директивы типа будут связаны с Order allow,deny
, но я этого не проверял. Также, что произойдет, если вы соответствуете Satisfy Any
но вы ранее собрали Allow from *
...)
Интересная заметка про ProxyPass и Alias
Просто чтобы быть раздражающим, ProxyPass
а также Alias
кажется, работает в другом направлении....;-) Это в основном поражает первый матч, затем останавливается и использует это!
Ordering ProxyPass Directives The configured ProxyPass and ProxyPassMatch rules are checked in the order of configuration. The first rule that matches wins. So usually you should sort conflicting ProxyPass rules starting with the longest URLs first. Otherwise later rules for longer URLS will be hidden by any earlier rule which uses a leading substring of the URL. Note that there is some relation with worker sharing. For the same reasons exclusions must come before the general ProxyPass directives.
поэтому в основном необходимо указывать директивы Alias и ProxyPass, в первую очередь, наиболее конкретные;
Alias "/foo/bar" "/srv/www/uncommon/bar"
Alias "/foo" "/srv/www/common/foo"
а также
ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On
Однако, как указал @orev. Вы можете иметь директиву ProxyPass в директиве Location, поэтому более конкретный ProxyPass в локации превзойдет любой ранее найденный ProxyPass.
Если вы вкладываете раздел (например. ): вложенные разделы объединяются после невложенных разделов того же типа. Это означает, что если вы добавите блок в невложенную конфигурацию, ваш последний соответствующий раздел изменится.