Сопоставить/запретить доступ ко всем подкаталогам, используя конфигурацию сервера apache2

Как можно запретить доступ ко всем подкаталогам данного каталога? (При этом разрешено вручную изменять права доступа для отдельных элементов в дереве каталогов.)

Я пытался сделать это с помощью директив <Directory(Match)>. Конфигурация сервера (с поддержкой 000 сайтов) выглядит так:

DocumentRoot /var/www
<Directory /var/www>
    Allow from all
    Deny from none
    Order deny,allow
</Directory>
<Directory /var/www/*>
    Deny from all
</Directory>

Запрос к http://localhost/ успешно отображает /var/www/index.html, и все запросы к любым подкаталогам терпят неудачу.

Проблема в том, что любой запрос к файлу в httproot завершается ошибкой, то есть запрос http://localhost/index.html приведет к 403 Forbidden.

Кажется, что директивы <Directory(Match)> на самом деле соответствуют каталогам И файлам!?

Чтобы убедиться, что это правда, я попробовал:

<Directory /var/www/i*>
    Deny from all
</Directory>

Это запрещает доступ только к файлам/каталогам, начинающимся с «i».

Есть ли способ изменить это поведение и позволить <Directory> соответствовать только каталогам? Есть ли другой способ сделать так, чтобы все подкаталоги были запрещены? (помимо запрета на все из них вручную или включения всех файлов вручную)


person coldfix    schedule 09.03.2011    source источник
comment
Похоже на ошибку для меня. Я открыл issues.apache.org/bugzilla/show_bug.cgi?id=50926 чтобы кто-то с большим опытом работы с ядром мог взглянуть.   -  person covener    schedule 14.03.2011


Ответы (6)


в итоге решение оказывается довольно простым:

<Directory /var/www/*/>
    Allow from None
    Order allow,deny
</Directory>

Обратите внимание на завершающую косую черту / после шаблона каталога, который будет соответствовать только каталогам, а не файлам!

Это работает точно так же, как и следовало ожидать от директивы <Directory>, поскольку она запрещает доступ только к прямым подкаталогам /var/www/. Указанные подкаталоги (в любом месте дерева) по-прежнему можно повторно включить вручную с помощью директив <Directory>.

Это отличается от <DirectoryMatch>, который будет
- также соответствовать всем файлам и каталогам в дереве и
- переопределять все директивы <Files> или <Directory> для любого элемента в дерево.

person coldfix    schedule 21.03.2011
comment
Вы говорите, что он запрещает доступ только к прямым подкаталогам, но, насколько мне известно, каталог работает иначе. Это относится к именованным каталогам И к их поддеревьям. Я не могу найти какие-либо директивы, подобные каталогам, которые могут применяться ТОЛЬКО к именованным каталогам, но не к их поддеревьям. Я также не могу найти директивы, подобные каталогам, которые применяются ТОЛЬКО к поддеревьям, но не к именованным каталогам. Кажется, это ограничение Apache. - person David Spector; 06.09.2018
comment
@DavidSpector Применяется к поддеревьям только по умолчанию, потому что родительское запрещено, а это совершенно желательно. Однако вы можете свободно добавлять директивы <Directory> для любого подкаталога, чтобы снова включить их, например. <Directory /var/www/subdir/bar> переопределит указанную выше настройку. - person coldfix; 07.09.2018
comment
Извините, может я не ясно выразился. Мой комментарий был общим, где мы предполагаем, что все каталоги доступны. В таком более типичном случае я не могу найти какие-либо директивы, подобные каталогам, которые могут применяться ТОЛЬКО к именованным каталогам, но не к их поддеревьям. Я также не могу найти директивы, подобные каталогам, которые применяются ТОЛЬКО к поддеревьям, но не к именованным каталогам. Ваш комментарий тоже верен. - person David Spector; 07.09.2018

Это сделало это для меня.

<DirectoryMatch "^/var/www/(.+)/"> # don't put $ at the end
Order Allow,Deny
Deny From All
</DirectoryMatch>


ИЗМЕНИТЬ

Чтобы не запрещать подкаталоги (комментарий ниже), добавьте этот DirectoryMatch ниже указанного выше в файле конфигурации:

<DirectoryMatch "^/var/www/(.+?)/(.+)/"> # again no $, see comment
Order Deny,Allow
Allow From All
</DirectoryMatch>

person dialer    schedule 13.03.2011
comment
Я пробовал это (с $). Вы знаете, почему это не работает с $ ? Без этого он также будет соответствовать всем под-подкаталогам, а это не то, что я изначально планировал. (Я хотел, чтобы расположение серверов генерировалось файловой системой, отключив по умолчанию все подкаталоги и включив только определенные. Но теперь я вижу, что это может быть не лучший подход.) - person coldfix; 14.03.2011
comment
$ должен отсутствовать, иначе он будет соответствовать только пустым каталогам, но не файлам, включая файлы index.php. Вы можете либо послушать, что говорят другие ответы, либо увидеть правку, которую я опубликую там через минуту. - person dialer; 14.03.2011
comment
$ не работает в DirectoryMatch в версии 2.2.x из-за какого-то странного конструктивного решения. Это в руководстве. - person covener; 14.03.2011
comment
Согласно руководству, любые директивы <DirectoryMatch>[..] в любом случае будут применяться только к именованному каталогу и подкаталогам этого каталога (и файлам внутри). Что касается вашего предложения: кажется, что использование нескольких директив <DirectoryMatch> работает, но я не решаюсь использовать это, поскольку оно переопределит все настройки .htaccess или <Directory>, расположенные в любом месте дерева. @covener: Ааа.. не видел. Спасибо. - person coldfix; 14.03.2011

Использовать это:

<Directory /var/www/public>
    allow from all
</Directory>


<DirectoryMatch "^/var/www/public/(.+)/">
   deny from all
</DirectoryMatch>

Возможно, вы захотите добавить параметры и т. Д.

Хитрость заключается в том, как объединяются директивы.

person Derick Schoonbee    schedule 20.03.2011
comment
Примечание. Вы можете сделать это для виртуального хоста по умолчанию или конкретного приложения... Я тестировал это на своем компьютере с Ubuntu. Если вы разрешите перечисление (индексы), подкаталоги будут хорошо скрыты, но вы увидите все файлы в каталоге. Я считаю, что это то, что вы хотите. - person Derick Schoonbee; 20.03.2011

Лучший подход — переместить весь контент, недоступный для публики, в каталог вне корневого дерева, например, в /home/my/app/

<Directory /home/my/app>
    Order Allow,Deny
    Deny from all
</Directory>

Затем дайте разрешение на чтение пользователю Apache в этом каталоге и во всех каталогах, которые ведут к этому, скажем, /home и /my

Таким образом, нет риска утечки части этого содержимого при возникновении какой-либо ошибки конфигурации корневого каталога.

person Clodoaldo Neto    schedule 13.03.2011
comment
Если вы переместите всю конфигурацию/контент во внешнее дерево, все ваши скрипты должны знать свой корневой путь (который может измениться и привести к большому количеству повторяющейся работы). Как бы вы с этим справились? Рассмотрим также случай, когда вы хотите скрыть (HTML) контент только от некоторых пользователей, поэтому создание дополнительного дерева не вариант. - person coldfix; 14.03.2011
comment
Что вы хотите скрыть? скрипты, статические файлы? Это приложение или просто набор скриптов? В этом вся разница, потому что в приложении будет открыт только один скрипт. Этот один сценарий передаст управление другим сценариям, которые будут обрабатывать аутентификацию и авторизацию и обслуживать контент в соответствии с бизнес-правилами. В любом случае размещение запрещенного контента в корневом каталоге веб-сайта — это авария, которая может произойти. Я не понимаю ваших пунктов, таких как корневой путь и повторяющаяся работа. - person Clodoaldo Neto; 15.03.2011

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

httpd.conf:

...
Options FollowSymLinks
...

(опция "Индексы" не установлена.)

Затем поместите файл index.html или index.php в каждый конкретный подкаталог, который вы хотите сделать доступным для клиентского доступа. Если вы хотите, чтобы автоматическое индексирование было включено в каком-то конкретном каталоге, вы можете добавить файлы .htaccess в эти каталоги и поместить эту строку в файл .htaccess:

Options Indexes

Обратите внимание, что .htaccess будет рекурсивно воздействовать на свой каталог и все его подкаталоги, поэтому вам следует исключить любой рекурсивный подкаталог, для которого вы не хотите использовать этот параметр, добавив .htaccess и отключив автоматический индекс: /сильный>

Options -Indexes

Примечание. Чтобы .htaccess файлы были включены и влияли на конфигурации apache, вы должны AllowOveride All указать каталог, в котором вы хотите разместить .htaccess файл.

person 2i3r    schedule 08.04.2014

Итак, у меня есть 2 мысли, которые могут помочь (или нет).

Во-первых, местоположения могут переопределять разрешения вашего каталога. Поэтому убедитесь, что у вас их нет. Нажатие на localhost/ нажимает на то, что вы настроили как root, что, вероятно, нарушает вашу безопасность. Вот почему, если вы укажете файл напрямую, вы не сможете добраться до него. Итак, если вы не хотите, чтобы люди могли получить доступ к вашему корню, вы не должны указывать корень.

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

https://serverfault.com/questions/190447/apache-2-htaccess-matching-all-sub-directories-of-current-directory

person John Hinnegan    schedule 13.03.2011
comment
Итак, вместо того, чтобы ограничивать доступ ко всем подкаталогам, я должен инвертировать свою структуру каталогов, используя <Alias>, чтобы в основном были доступны только разрешенные каталоги? Звучит разумно. Любая подсказка, почему <Directory> соответствует файлам? - person coldfix; 14.03.2011
comment
Я думаю, что идея больше в том, что вы собираете вещи, которые ограничены, вместе в общем месте. У меня нет особого смысла настраивать схему, в которой вы можете получить доступ к /foo, но не к /foo/bar. Для меня более разумным было бы иметь доступ к /foo, но не к /bar. Я думаю, что последнее утверждение довольно субъективно, просто мои $ 0,02 - person John Hinnegan; 14.03.2011