AH01630: client denied by server configuration / AH01276: Cannot serve directory: No matching DirectoryIndex
#Причины 403 в Apache 2.4
В Apache 2.4 изменилась система доступа: вместо старых Order allow,deny и Allow from all используется Require. Если для каталога нет Require all granted (и нет унаследованного правила), доступ запрещён. Другие причины: у каталогов или родительских путей нет права на выполнение/чтение для пользователя веб-сервера, нет индексного файла при выключенном листинге (Options -Indexes), SELinux блокирует доступ к нестандартному каталогу, правило в .htaccess запрещает доступ, файл принадлежит другому пользователю.
#Причины 403
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Нет Require all grantedКонфиг для 2.2. | AH01630 в журнале. | Добавьте Require. |
| Нет прав на родительские каталоги/home/user закрыт. | Права 700 на пути. | chmod +x по цепочке. |
| Нет индексного файлаПустой каталог. | AH01276. | Создайте index или включите листинг. |
| SELinuxНеверный контекст. | Только на RHEL-системах. | chcon/semanage. |
| Правило в .htaccessDeny from all. | Закрыт каталог. | Исправьте файл. |
| Запрет по IP или модулю безопасностиModSecurity, fail2ban. | 403 для части пользователей. | Проверьте журнал аудита. |
#Порядок
- Найдите в журнале точную причину отказа HTTP 403Подключитесь к Apache по SSH и найдите исходный запрос в
error.log: на Debian/Ubuntu это часто/var/log/apache2/error.log, на RHEL —/var/log/httpd/error_log, в панели хостинга путь иной. Выполнитеsudo grep "AH01630" /реальный/путь/error.log | tail -n 20. Запишите точный URL, путь и время;AH01630говорит об отказе правил доступа, а не об отсутствии index-файла. - Проверьте блок <Directory> вашего сайта на наличие Require all grantedВыполните
apachectl -S(на Debian такжеapache2ctl -S) и найдите виртуальный хост для домена. Откройте его конфигурацию и соответствующий блок<Directory /фактический/каталог>; проверьтеRequire all granted,Require ip,Require all deniedи ограничения.htaccess. Не добавляйтеRequire all grantedк закрытым папкам/admin/резервным копиям. - Проверьте права на весь путь к каталогу сайтаЕсли журнал говорит
Permission denied/AH00035, выполнитеnamei -l /путь/к/index.php, чтобы увидеть владельцев и доступ к каждому родительскому каталогу. Сначала проверьте пользователя Apache и владельца PHP-FPM, затем исправляйте права только там, где нарушение доказано. Массовыеchmod 755/644по всем файлам могут открыть секретные файлы и испортить права загрузок. - Проверьте индексный файл и правила DirectoryIndexЕсли журнал говорит
directory index forbidden/AH01276, проверьте, что в документ-корне существуетindex.phpилиindex.htmlи в конфигурации задан корректныйDirectoryIndex. Не включайте листинг содержимого закрытых каталогов, чтобы обойти 403: это создаёт риск раскрытия файлов. - Проверьте SELinuxНа системах RHEL/AlmaLinux/Rocky с SELinux выполните
getenforceиsudo ausearch -m AVC -ts recentи сравните время отказа с запросом. Если отказ действительно вызван контекстом, задайте правильный тип черезsemanage fcontextиrestoreconдля конкретного каталога. Не отключайте SELinux и не выполняйте рекурсивныйchconбез подтверждения причины. - Проверьте .htaccess на директивы Deny, Require all deniedПроверьте файл
.htaccessв каталоге сайта и родителях, если в Apache разрешёнAllowOverride. ИщитеRequire all denied,Require ipи старыеOrder/Deny/Allow, влияние которых зависит от модулей. Перед изменением сохраните файл; если директива нужна для ограничения доступа, сохраните ограничение и исправьте только нужный URL. - Команды для отдельных ситуацийВыберите только подходящий вариант. Это не одна последовательность: часть команд диагностирует проблему, а часть меняет настройки или данные.
- После изменений проверьте синтаксис и перезагрузите конфигурациюПосле минимальной правки выполните
sudo apachectl configtest(либоapache2ctl configtest), убедитесь вSyntax OK, затемsudo systemctl reload apache2на Debian илиhttpdна RHEL. Откройте исходный URL и проверьте, что он доступен только предполагаемым пользователям, а закрытые ресурсы по-прежнему защищены.
#Старый синтаксис
Если в конфигурации остались Order allow,deny и Allow from all, модуль mod_access_compat обеспечивает совместимость, но смешивать старые и новые директивы нельзя. Замените их на Require all granted (открыть) или Require ip 203.0.113.0/24 (ограничить по сети), чтобы избежать неожиданных запретов.