Материалы для WEB разработки на LAMP
Контроль доступа клиента в Apache

В статье описаны наиболее распространенные и часто используемые варианты реализации контроля доступа клиента к web серверу Apache на основе анализа разнообразных характеристик запроса. Представлен синтаксис и примеры директив Require, Allow, Deny, Order, RequireAll, RequireAny, RequireNone и подробно расписаны типы и виды аргументов для этих директив. Приведены примеры для ограничения доступа к сайту или его части по IP, названию хоста, агенту пользователя и другие.

Директивы управления доступом

Управление доступом клиента к web серверу на основе значений хоста и других параметров запроса реализуется в Apache при помощи директив Require, Allow, Deny, Order из соответствующих модулей web сервера. Основное предназначение этого функционала в том, что Apache позволяет выполнять ограничения доступа клиента к web серверу на основе анализа разных характеристик запроса клиента, от которого получен запрос. На деле это позволяет блокировать или разрешать доступ к серверу по доменному имени (hostname) или по IP адресу хоста клиента, сделавшего текущий запрос, и по многим другим параметрам. Этот подход является одним из нескольких вариантов по реализации ограничения и короля доступа, предоставляемых web сервером Apache и здесь использование директивы Require с методами проверки хоста, является частным случаем применения этой директивы.

 Директивы Allow, Deny, Order модуля mod_access_compat нежелательны к использованию и считаются устаревшими, хотя и поддерживаются еще в версиях Apache 2.3 и 2.4, но в следующих версиях они будут удалены.

Теперь, вместо устаревших директив Allow, Deny, Order, начиная с версии Apache 2.3, этот функционал реализуется директивой Require из модуля mod_authz_core с дополнительным методом проверки авторизации на основе значений хоста из нового модуля mod_authz_host. Нужно так же заметить, что директива Require как с базовыми методами, так и дополнительными предоставляет намного более гибкий функционал по контролю доступа к web серверу, чем устаревшие директивы.

Если посмотреть хронологию директив Allow, Deny, Order в разных версиях Apache, то можно вспомнить, что в Apache версии 2.2 и более старых эти директивы были реализованы в модуле mod_access и активно использовались для короля доступа. Начиная с версии Apache 2.3 эти директивы стали выводиться из обращения и, реализуемый ими функционал, стал предоставляться теперь директивой Require. Для этого директива была расширена новым модулем mod_authz_host, который был добавлен в Apache начиная с версии 2.3 и призван в дальнейшем обеспечивать этот функционал управления доступом на основе значений хоста клиента как частный случай использования директивы Require, взамен устаревших модулей и директив. Поэтому функционал устаревающих директив Allow, Deny, Order был перенесен в модуль mod_access_compat, который появился в Apache начиная с версии 2.3 (он есть и в 2.4 версии) для поддержки совместимости со старыми сайтами (их конфигами), которые еще применяют для конфигурации Apache устаревшие директивы.Однако, несмотря на то, что директива Require теперь заменяет функционал директив Allow, Deny, Order, применение этого функционала, вид и форматы аргументов остались неизменными.

Директивы Require, Allow, Deny, Order предназначены для управления доступом на уровне директорий (каталогов) сайта и могут применяться в конфигурационных файлах Apache внутри тегов (директив) <Directory>, <Files> или <Location>, или напрямую, без этих тегов, в файле .htaccess, позволяя детально контролировать и управлять доступом к тем или иным разделам и папкам сайта на web сервере. Директивы-теги <Directory>, <Files>, <Location> используются в глобальном конфиге или в конфиге виртуального хоста Apache для задания локализации (директории сайта с распространением действия на вложенные подкаталоги) применения заключенных в них директив. Эти директивы не используются в .htaccess, так как этот файл сам по себе уже является локализованным каталогом, в котором он помещен.

Соблюдайте осторожность при установке директив авторизации в <Location  "URL-path|URL"> секциях, URL аргумент которых перекрывается с файловым путем в файловой системе вашего Linux сервера. Это связано с тем, что по умолчанию <Location> перезаписывает конфигурации <Directory> и <Files>, так как <Location> секции обрабатываются в порядке их появления в файле конфигурации, после того как <Directory>, <Files> и .htaccess уже прочитаны Apache.

Применять же директиву <Location> нужно только для контента, который находиться вне пределов файловой системы сервера, так как эта директива принимает URL как аргумент, а не путь в файловой системе. Исключение из этого может быть вариант применение директивы в виде  <Location "/">, который является легким способом применить конфигурацию сразу ко всему серверу Apache.

#Пример из конфига виртуального хоста
<Directory "/www/example">
    #Будут действовать только для указанного каталога
    Require entity-name ...
    Require entity-name ...
</Directory>

 

По умолчанию, все эти директивы ограничения доступа применяются ко всем типам запроса - GET, PUT, POST, и т.д, что удобно и оптимально для большинства случаев. Однако, можно ограничить применение этих директив только на нужных вам методах запроса посредством помещения директивы (директив) в тег <Limit>.

<Limit POST>
  #Здесь директивы будут работать только для POST типа запроса,
  #Другие типы запросов будут выполняться без ограничений
  Require ip entity-name ...
  Require ip entity-name ...
  ...
</Limit>

Если Require авторизация применена для каталога при помощи секций <Directory>, <Files>, <Location> или напрямую в файле .htaccess, то она по умолчанию наследуется каждой последующей секцией конфигурации для этого каталога и подкаталогов, если иной набор директив Require авторизации не указан для них. Такое поведение по умолчанию определяется директивой AuthMerging  со значением по умолчанию равным AuthMerging Off. Именно директива AuthMerging задает логику переопределения директив авторизации. Если она установлена как AuthMerging And, то директивы Require секций будут объединяться, как если бы они были заключены в <RequireAll>. Если AuthMerging Or, то директивы Require из секций будут объединяться, как если бы они были заключены в <RequireAny>.

 

Общий синтаксис директивы Require:

  • Описание: Проверяет, прошел ли аутентифицированный (распознанный) пользователь авторизацию посредством указанного в директиве для этого метода;
  • Синтаксис: Require [not] entity-name [entity-name] ...;
  • Контекст применения директивы:    directory, .htaccess;
  • Переопределение директивы: что бы директива Require была доступна в .htaccess файле сайта/каталога она должна быть разрешена в конфигурационном файле более высокого уровня (конфиг виртуального хоста или глобальный конфиг Apache) для этого каталога (каталогов) выражением: AllowOverride AuthConfig или выражением AllowOverride All

Например:

<Directory /home/mysite/www>
        #Пример из конфига виртуального хоста
        ...
        AllowOverride AuthConfig
        # или
        #AllowOverride All
        ...
</Directory>
  • Статус:  директива Require является базовым функционалам и входит в состав Apache по умолчанию;
  • Модуль Apache: директива предоставляется модулем mod_authz_core  ;

 

Общее описание директивы Require:

Директива Require проверяет аутентифицированного (распознанного) пользователя текущего запроса на предмет успешного прохождения им авторизации в соответствии с конкретным, заданным в ней методом авторизации и указанных ограничений и условий. В результате чего, если такая проверка прошла успешно, то доступ разрешатся к сайту, его части или каталогу. По другому можно сказать так, что сама по себе директива Require - это всегда принятие решения о предоставлении клиенту доступа к сайту или его части. Если директива исполняется, то доступ текущему клиенту разрешается, если директива не исполняется, то доступ запрещается. Директива Require исполняется и доступ клиенту разрешается, если метод проверки авторизации, указанный в этой директиве (суммарное выражение из аргументов директивы - все, что справа от названия директивы) в общем итоге возвращает истину. Если метод проверки суммарно возвращает ложь, то директива не исполняется и доступ клиенту запрещается. Это базовая логика работы отдельно взятой директивы. Однако, директива Require может применяться не только в виде одиночного варианта, а возможно одновременное использование нескольких вызовов этой директивы (несколько записей). Так же несколько вызовов директивы можно сгруппировать дополнительными группирующими директивами (они выглядят как теги) <RequireAll>, <RequireAny>, <RequireNone>. Заключенные (обернутые) внутри этих тегов несколько директив Require работаю как одно целое, и решение о доступе принимается уже на уровне группы директив по логике устанавливаемой групповой оберточной директивой (тегом). Директивы <RequireAll>, <RequireAny> и <RequireNone>, так же как и Require, работают в контексте каталога, и так же предоставляются модулем mod_authz_core.

 

Принцип работы директивы Require

Более развернуто синтаксис можно представить так (но это не все возможные варианты):

Require [not] all|env|method|expr|user|group|host|ip|local entity-name [entity-name] ...

Как видно и представленного синтаксиса, директива Require состоит из двух частей. Первая, это объявление самой директивы через ключевое слово Require и вторая часть, все что справа от объявления директивы, именно которая и определяет метод выполнения проверки авторизации и аргументы передаваемые этому методу. Задание нужного метода проверки авторизации, для использования его директивой при принятии решения о доступе, выполняется путем указания, после объявления самой директивы, следующих ключевых слов -  all|env|method|expr|user|group|host|ip|local, каждое из которых соответствует определенному методу. Заданный директиве метод может иметь и принимать много разных аргументов, которые, в свою очередь, могут быть разного типа и вида, и по разному сочетаться, для каждого конкретного метода. Например, аргументы могут быть ключевыми, зарезервированными словами (ключами) и фразами, могут быть логическим выражением (доступно начиная с v2.4.8), и т.д. Если в директиве для метода указано через пробел несколько аргументов, которые не являются зарезервированными ключевыми словами, а представляют собой значения для сравнения указанным методом, то все такие аргументы воспринимаются объединенными логически [или] и достаточно, что бы одни из таких аргументов получил соответствие в методе проверки, что бы  метод суммарно вернул истину, как результат проверки, и директива сработала, и доступ был предоставлен. Метод проверки авторизации, указанный в директиве, всегда суммарно возвращает истину или ложь, соответственно если истина, директива исполняется и доступ разрешается. Но возможно изменить логику срабатывание директивы на противоположную при помощи необязательного оператора not, который используется сразу после объявления директивы. В случае его использования директива срабатывает, когда ее метод суммарно возвращает ложь.

Директива Require может быть указана многократно, каждая следующая с новой строки. Так же директивы Require могут быть сгруппированы в секции при помощи тегов-директив <RequireAll>, <RequireAny>, <RequireNone>. Если в конфигурационном файле присутствует несколько директив Require без группирующих тегов, то в этом случае все такие директивы считаются по умолчанию обернутыми в групповой тег <RequireAny>, а это значит, что доступ будет разрешен, если хотя бы одна из таких директив исполниться. И в этом случае все остальные директивы, после первой исполненной, будут проигнорированы. Это нужно понимать и помнить, т.к. в этом случае порядок следования директив будет иметь значение. Более детально, всегда необходимо смотреть документацию по соответствующему модулю в каждом конкретном случае использования директивы.

Как видим директива Require, несмотря на то, что сама по себе она решает только одни вопрос - предоставлять доступ или нет на основе результата метода, является достаточно универсальной. И такая универсальность и гибкость возможна именно благодаря возможности использовать в директиве самые разнообразные методы проверки авторизации. Базовые, основные методы проверки, как и сами директивы Require, <RequireAll>, <RequireAny>, <RequireNone> реализованы в базовом модуле Apache mod_authz_core. Дополнительные методы проверки авторизации для использования с директивой Require предоставляются уже другими модулями Apache, такими как mod_authz_user , mod_authz_host , и mod_authz_groupfile  и т.д.

 

Примеры использования директивы Require

Примеры и синтаксис Require c общими методами авторизации из модуля Apache mod_authz_core:

Require all

Общий синтаксис для Require all. После all может быть только ключевое слово granted или denied

Require all granted|denied

Пример разрешения доступа всем без ограничений, что аналогично устаревшей Allow from all

Require all granted

Пример запрещения доступа всем, что аналогично устаревшей Deny from all

Require all denied

 

Require env

Синтаксис примера для разрешения доступа только, если одна из указанных переменных окружения установлена, где env метод проверки (проверяет существование переменной), env-var имя переменной. Здесь, в примере для .htaccess использована установка через директиву SetEnvIfNoCase  переменной окружения с именем let_me_in по условию, когда строка User-Agent клиента начинается с My_secret_User_Agent. Затем, в директиве Require проверяется существование этой переменной, и если такая переменная была установлена, то доступ разрешается.

#Общий вид
Require env env-var [env-var] ...

#Пример для .htaccess
SetEnvIfNoCase User-Agent ^My_secret_User_Agent let_me_in
Require env let_me_in

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

Require not env env-var [env-var] ...

 

Require method

Синтаксис примера для разрешения доступа только для указанного метода или методов запроса. Аргумент http-method - это метод запроса вида GET, POST и др. Для клиентов, выполнившие запрос к серверу другими методами, не указанными в аргументах директивы, доступ будет запрещен. Это может быть удобно, если необходимо, например, для некоторых разделов сайта разрешить доступ только для GET запросов.

Require method http-method [http-method] ...

 

Require expr

Синтаксис примера для разрешения доступа на основе проверки по логическому выражению (доступно начиная с v2.4.8). Аргумент expression это логическое выражение в формате синтаксиса Apache , которое в итоге возвращает ИСТИНУ или ЛОЖЬ. Доступ клиенту разрешается, если выражение возвращает ИСТИНУ.

Require expr expression

Пример разрешения доступа на основе логического выражения. Здесь, доступ разрешается для всех клиентов, у которых значение USER_AGENT не содержит фразу 'BadBot':

Require expr %{HTTP_USER_AGENT} != 'BadBot'

 

Require с If, ElseIf, Else

Пример использования Require совместно с директивами-тегами условий <If> , <ElseIf>, <Else> и т.д, которые доступны для применения в глобальном конфиге, в конфиге виртуального хоста, в секциях локализации (directory) в конфигах, и в .htaccess файле.

#Пример на основе USER_AGENT
<If "%{HTTP_USER_AGENT} == 'BadBot'">
    Require all denied
</If>

#Пример на основе диапазона IP
#Если удаленный IP в диапазоне 10.1.0.0/16
<If "-R '10.1.0.0/16'">
  Require ...
</If>
#ИначеЕсли удаленный IP лежит в диапазоне 10.0.0.0/8
<ElseIf "-R '10.0.0.0/8'">
  Require ...
</ElseIf>
#Иначе удаленный IP НЕ в диапазоне 10.1.0.0/16 и 10.0.0.0/8
<Else>
  Require ...
</Else>

 

Require с RequireAll, RequireAny, RequireNone

Синтаксис примера <RequireAll> директивы-тега. Эта групповая директива требует, что бы все, заключенные внутри нее, директивы Require были исполнены, и только в этом случае <RequireAll> исполниться, и доступ будет предоставлен. В приведенном примере клиентам, приходящим с IP 192.168.48.185 или с домена host.example.com, доступ будет запрещен, а всем остальным доступ будет разрешен.

<RequireAll>
    Require all granted
    Require not ip 192.168.48.185
    Require not host host.example.com
</RequireAll>

Синтаксис примера <RequireAny> директивы-тега. Эта групповая директива требует, что бы хотя бы одна из заключенных внутри нее директив Require была исполнена, только в этом случае <RequireAny> исполниться и доступ будет предоставлен. Поэтому внутри <RequireAny>, все последующие директивы Require, следующие после первой исполненной, уже игнорируются. В данном примере доступ будет предоставлен только клиентам, выполнившим запрос методом GET или POST, или только клиентам, прошедшим авторизацию по пользователю и паролю методом заданным директивой AuthType.

<RequireAny>
     Require method GET POST
     Require valid-user
</RequireAny>

Синтаксис примера применения группой директивы <RequireNone>. Эта групповая директива требует, что бы ВСЕ заключенные внутри нее директивы Require были НЕ исполненные, только в этом случае <RequireNone> исполниться и доступ будет предоставлен. В примере, доступ клиента к каталогу "/www/doc" будет предоставлен только в том случае, если ВСЕ директивы Require внутри группой директивы-тега <RequireNone> НЕ исполняться. Этот пример для конфига виртуального хоста. В файле .htaccess используйте этот код без тега <Directory>.

#Пример из конфига виртуального хоста
<Directory "/www/doc">
    <RequireNone>
        Require ip entity-name ...
        Require not ip entity-name ...
    </RequireNone>
</Directory>

Условный пример комбинированного использования директивы Require c группирующими директивами для конфига виртуального хоста.

<Directory "/www/doc">
    <RequireAll>
        <RequireAny>
            Require ...
            <RequireAll>
                Require ...
                Require ...
                <RequireAny>
                    Require ...
                    Require ...
                </RequireAny>
            </RequireAll>
        </RequireAny>
        <RequireNone>
            Require ...
            Require ...
        </RequireNone>
    </RequireAll>
</Directory>

 

Require инверсия условия

Логику срабатывания директивы Require можно изменить на противоположную путем использования:

  • not - необязательного первого аргумента в директиве Require, наличие которого приведет к инверсии срабатывания директивы. Оператор not работает на уровне одной директивы и не является false, а представляет собой опцию указывавшую серверу на изменение логики обработки директивы.
  • <RequireNone> - групповой тег (директива), если расположить одну или несколько директив Require внутри тега <RequireNone>, то это приведет к групповой инверсии срабатывания директив внутри этого контейнера. Для того, что бы директива <RequireNone> была успешно выполнена, ВСЕ расположенные внутри нее директивы Require должны быть НЕ успешными (не исполненными), и только в этом случае групповая директива <RequireNone> будет успешно исполнена и доступ будет разрешен.

 

Примеры и синтаксис Require с дополнительными методы авторизации из модулей mod_authz_user, mod_authz_groupfile:

Require user, group

Синтаксис примера для разрешения доступа на основе проверки пользователя по его логину. Доступ разрешается только пользователям с логинами указанными в аргументе userid директивы.

Require user userid [userid] ...

Синтаксис примера для разрешения доступа на основе проверки пользователя на принадлежность указанным в аргументе group-name группе. Доступ разрешен только пользователям из указанных групп.

Require group group-name [group-name] ...

 

Require valid-user

Синтаксис примера для разрешения доступа пользователям, успешно прошедшим авторизацию (валидацию), например, AuthType Basic http авторизацию. Здесь, доступ разрешен только пользователям прошедшим валидацию. Метод валидации указывается отдельными директивами, например, AuthType

Require valid-user

Пример использования директивы Require с базовой http авторизацией по паролю, предоставляемой модулем mod_authn_core . В примере доступ к директории сайта "/www/doc" будет разрешен только пользователям, успешно прошедшим базовую http авторизацию по паролю. Этот пример для конфига виртуального хоста. В файле .htaccess используйте этот код без тега <Directory>.

#Пример из конфига виртуального хоста
#Защита паролем директории "/www/doc"
<Directory "/www/doc">
    AuthType Basic
    AuthName Documents
    AuthBasicProvider file
    #Путь к файлу с хэшами паролей
    AuthUserFile "/usr/local/apache/passwd/passwords"
    Require valid-user
</Directory>

#Отмена наследования защиты паролем для вложенной директории
<Directory "/www/doc/public">
    AuthType None
    Require all granted
</Directory>

 

 

Доступом на основе значений хоста

Организация короля доступа к сайту и его частям директивой Require на основе дополнительных методов анализа значений хоста клиента из модуля mod_authz_host является одним из часто применяемых на практике вариантов использования директивы Require. В этом варианте авторизация выполняется на основе проверки соответствия значения хоста клиента аргументам метода директивы, заданным в виде: 'ip', 'hostname' или 'local'. Такой же функционал предоставляют и устаревшие директивы Allow, Deny, которые в ранних версиях Apache в основном выполняли эту роль. Здесь, нужно заметить, что смысл, виды и форматы аргументов для методов, выполняющих проверку и сравнение значений хоста в директивах Require, Allow, Deny одинаковы для всех директив. Поэтому, представленное ниже описания этих аргументов, применимо для всех этих директив.

 

Require host, ip, local

Синтаксис использования директивы Require с методом проверки по значению хоста:

Require [not] host|ip|local value1 [value2]...

где:

  • [not] - необязательный аргумент, который выполняет инверсию обработки условия и директива исполниться только если хост не соответствует аргументам;
  • host|ip|local -аргумент ключ, сообщающий директиве, какой конкретно метод проверки аргументов value нужно использовать, т.е. указание на то, какой тип значения используется в аргументах value:
    • host - указывает, что value содержит имя хоста в виде полного или частичного доменного имени. Можно через пробел указать несколько value, которые будут считаться объединенными через логическое [или]. Директивы в таком варианте сработают для доменов, полные компоненты которых будут заканчиваться на строку в аргументе value. Подбор и проверка строки имени домена, сделавшего запрос, будет выполняться по полным компонентам. Например для example.com будут пропускаться домен example.com и любые под домены этого домина вида foo.example.com, но домен вида myexample.com будет отклонен. Такой вариант задания аргумента сравнения значения хоста в виде полной части доменного имени обяжет Apache выполнить обратный DNS запрос для IP адреса клиента, что бы получить связанное с ним доменное имя хоста. Затем Apache, выполнит уже прямой DNS запрос, что бы убедиться, что полученное обратным запросом доменное имя действительно соответствует IP адресу запроса. Только, если оба эти запроса - обратный и прямой укажут на одно и тоже доменное имя и это доменное имя будет соответствовать/совпадать строке аргумента value, при сравнении с конца строки по полным компонентам доменного имени, директива исполниться. Такой функционал double-reverse DNS lookup обеспечивается возможностями ядра apache и управляется директивой HostnameLookups , которая по умолчанию имеет значение Off для экономии трафика. Эта директива разрешает выполнение DNS-запросов, и имена хостов могут быть переданы как REMOTE_HOST значение. Однако, ВНЕ ЗАВИСИМОСТИ ОТ НАСТРОЙКИ HostnameLookups, КОГДА MOD_AUTHZ_HOST используется для контроля доступа по имени хоста, двойной DNS запрос будет выполнен, потому, что это необходимо для обеспечения безопасности, так как речь идет о короле доступа. Начиная с версии Apache  v2.4.8, в Require host value... в аргументах value поддерживаются различные логические выражения, что дает еще большую гибкость в задании условий проверки хоста по его имени (см. выше примеры для Require expr).
    • ip - указывает, что value содержит IP-адрес или диапазон IP, как часть ip, как network/netmask, network/nnn CIDR. Можно через пробел указать несколько value, которые будут считаться объединенными через логическое [или].
    • local -указывает, что проверку хоста клиента делать на соответствие локальному хосту. С этим ключом не нужно указывать аргументы value, т.к. Apache сам их получит от локального хоста. Для этого варианта будет выполнена проверка на то, что хост клиента, выполнившего запрос является (или не является, при использовании [not]) локальным хостом. Проверка на соответствие локальному хосту будет выполняться по следующим пунктам, все из которых должны быть истинными:
      • IP4 находиться в диапазоне 127.0.0.0/8
      • IP6 ::1
      • адрес клиента и адрес сервера одинаковы

Однако, если у вас установлен прокси сервер и apache получил запрос не от клиента напрямую, а от прокси сервера, то для apache уже значение хоста клиента будет прокси сервер, а не первоначальный клиент. Для решения вопроса правильного контроля доступа в этом случае нужно воспользоваться модулем mod_remoteip .

  • value1 [value2]... - аргументы для использования в методе проверки и сравнения в соответствии указанным типом значения. Можно через пробел указать несколько value, которые будут считаться объединенными через логическое [или]. Нужно сказать, что этот аргумент директивы Require задается и обрабатывается по такому же принципу как и в директивах Allow, Deny и детально он будет описан ниже.

 

Allow и Deny с all, host, env

Пример общего синтаксиса директив Allow  и Deny . Директивы Allow и Deny применяются на уровне каталога, поэтому в глобальном конфиге Apache и в конфиге виртуальных хостов они должны быть заключены внутрь тегов-директив локализации <Directory>, <Files>, <Location>  и т.п., а в файле .htaccess указываются уже напрямую. Можно написать несколько директив подряд, каждая с новой строки. В этом случае директивы объединяются логическим [или].

Allow from all|host|env=[!]env-variable [host|env=[!]env-variable] ...
Deny from all|host|env=[!]env-variable [host|env=[!]env-variable] ...

где:

  • all - ключевое слово, что значит для всех запросов. Соответственно, после All последующие аргументы не задаются;
  • host - это аргумент для проверки значения хоста. Может быть задан, как ip, диапазон ip, имя хоста. Вид аргумента такой же, как и у директивы Require
  • env-variable - имя переменной окружения для проверки, что такая переменная установлена ([!] - не установлена). Этот функционал аналогичен функционалу предоставляемому директивой Require env env-var [env-var] ...

Для расширения функционала Allow и Deny директив используется директива Order, которая устанавливает порядок обработки директив и предоставляет два варианта организации контроля доступа:

  • Order Allow,Deny - сначала обрабатываются все Allow директивы, среди которых, как минимум одна должна исполниться, иначе доступ сразу запрещается и следующие директивы уже игнорируются. Если на предыдущем шаге была хотя бы одна исполненная директива Allow, то далее начинают обрабатываться директивы Deny. Если хотя бы одна из директив Deny будет исполнена, то доступ будет запрещен и следующие директивы будут уже проигнорированы. Иначе говоря, что бы доступ клиенту был предоставлен необходимо, в этом варианте, что бы хотя бы одна директива Allow была исполнена и все директивы Deny были НЕ исполнены;
  • Order Deny,Allow - сначала обрабатываются все директивы Deny, и если какая либо их них исполниться, то доступ будет запрещен, если при этом же запрос не приведет к исполнению Allow директивы. Любые запросы, которые не соответствуют ни одной директиве Allow или Deny будут разрешены. Иначе горя, в этом варианте вы сначала ставите запрещающие условия в Deny, а затем в Allow ставите исключения для того что указали в Deny.

В примере доступ будет разрешен только хостам принадлежащих домену example.org, т.е. example.org и foo.example.org

Order Deny,Allow
Deny from all
Allow from example.org

В примере доступ будет предоставлен только хосту с домена example.org, за исключением его под доменов.

Order Allow,Deny
Allow from example.org
Deny from foo.example.org

По умолчанию, директива Order имеет установку как Order Deny,Allow, поэтому нужно быть внимательным при указании Order без последующего указания директив Allow или Deny, и наоборот, при указании этих директив без предварительного задания директивы Order. В примере ниже продемонстрировано, как это может привести к не ожидаемому результату. В примере из конфига виртуального хоста указана только директива Order Allow,Deny, но после нее не указаны директивы Allow или Deny. Это приведет к тому, что доступ к "/www" каталогу будет запрещен, так как поведение по умолчанию deny.

<Directory /www>
    Order Allow,Deny
    # Ошибка, не указаны директивы Allow или Deny
    # Поэтому доступ будет запрещен т.к. по умолчанию deny
</Directory>

 

 

Примеры директив для методов проверки хоста

Использование Require, Allow, Deny с именем хоста

Аргументы для метода проверки хоста, могут быть так же представлены в виде полного или частичного доменного имени. Однако, всегда нужно помнить, что в этом варианте сервер будет делать прямой и обратный DNS запросы, что является накладной операцией и делать это постоянно, для всех запросов не совсем разумно. Если уж есть необходимость делать такую проверку, то лучше вызвать ее по предварительному условию, например на основе анализа значения HTTP_USER_AGENT запроса.

#Разрешать example.com и все foo.example.com
Require host example.com
# или
Allow from example.com

#Разрешать все foo.com, example.ru и все foo.example.ru
Require host .com example.ru
# или
Allow from .com example.ru

 

Использование Require, Allow, Deny с IP

Как полный IP-адрес

Синтаксис примера для проверки хоста по полному IP адресу. Директивы сработают только для указанных IP. В этом варианте все просто, директива будет срабатывать только если IP адрес запроса будет точно совпадать с указанным или указанными в директиве аргументами в виде строки полного IP.

#Разрешать только для 10.1.1.1
Require ip 10.1.1.1
# или
Allow from 10.1.1.1

#Разрешать только для 192.168.0.100 или 192.168.0.205
Require ip 192.168.0.100 192.168.0.205
# или
Allow from 192.168.0.100 192.168.0.205

 

Как IP диапазон

Как частичный IP-адрес задающий диапазон (диапазоны) IP, для ограничения подсети (подсетей). Директивы сработают для всех IP, лежащих в пределах указанных диапазонов.

#Первые 2 байта IP для ограничения подсети
Require ip 10.1
# или
Allow from 10.1

#Первые 1 - 3 байта IP-адреса для ограничения подсети
Require ip 10 172.10 192.168.1
# или
Allow from 10 172.10 192.168.1

 

Как IP network/netmask

Как network/netmask пара задающая диапазон ограничения подсети.

Require ip 10.1.0.0/255.255.0.0 network/netmask ...
# или
Allow from 10.1.0.0/255.255.0.0 network/netmask ...

 

Как IP network/nnn CIDR

Как network/nnn CIDR пара задающая диапазон ограничения подсети. Достаточно удобный вариант задания параметров проверки хоста. Для преобразования IP диапазонов в CIDR формат можно воспользоваться сервисом - ip2cidr.com .

Require ip 5.248.128.0/23 network/nnn ...
# или
Allow from 5.248.128.0/23 network/nnn ...

 

Адреса IPv6

Адреса IPv6 и подсети IPv6 могут быть определены как показано в примере ниже:

Require ip 2001:db8::a00:20ff:fea7:ccea
# или
Allow from 2001:db8::a00:20ff:fea7:ccea

Require ip 2001:db8::a00:20ff:fea7:ccea/10
# или
Allow from 2001:db8::a00:20ff:fea7:ccea/10

 

Использование Require local

Разрешать только локальным клиентам:

Require local

Или с отрицанием, всем кроме локальных клиентов:

Require not local

Полезные ссылки:

Apache HTTP Server Version 2.4 Documentation

 

Андрей Болдырев