#Симптом и границы применимости
После изменения владельца или прав каталога Apache возвращает 403 на изображения, CSS и другие статические файлы, хотя PHP-страница открывается. Причиной могут быть как Unix-разрешения каталогов, так и директивы Require/Options либо SELinux; разрешение 777 не требуется.
#Возможные причины и как их отличить
| Возможная причина | Как узнать | Что делать |
|---|---|---|
| Недоступен один из родительских каталоговApache должен проходить по всем родительским каталогам. | В error_log Permission denied при правильных правах файла | Проверить x на каждом уровне пути |
| Правила Apache запрещают чтениеUnix-права могут быть корректными, но сервер блокирует доступ. | В error_log client denied by server configuration | Проверить <Directory> и Require |
| Отказ SELinux/AppArmor или неверный aliasКонтекст безопасности и фактический root/alias важны наряду с chmod. | 403 сохраняется после проверки прав | Проверить защитные журналы и реальное разрешение пути |
#Пошаговая диагностика и исправление
- Определите точный файл и код ответаОткройте страницу в браузере, нажмите F12 → «Сеть», обновите её и щёлкните один запрос к CSS или изображению со статусом 403. Запишите его адрес без персональных параметров. Проверьте curl, чтобы исключить кэш и понять, отдаёт ли код Apache или предыдущий прокси.Linux · Терминал (Bash)Команда
curl -sSI https://example.com/assets/site.css
- Найдите фактический путь к файлуПо SSH посмотрите DocumentRoot или Alias нужного VirtualHost, затем убедитесь, что запрошенный файл действительно находится там. При Alias путь URL может отличаться от пути на диске; не пытайтесь исправлять его созданием файла в другом каталоге.
- Пример для Debian; учитывайте конфигурацию панели и защищайте выводLinux · Терминал (Bash)КомандаНужен sudoПример для Debian; учитывайте конфигурацию панели и защищайте вывод.
sudo apache2ctl -S; sudo grep -R -nE "DocumentRoot|Alias |<Directory|Require " /etc/apache2/sites-enabled
- Проверьте проход по каталогамВыполните namei -l с фактическим абсолютным путём к файлу. Каталогам нужен проход x для пользователя Apache или соответствующей группы; файлу — право чтения. На Debian пользователь часто www-data, но выясните фактический по настройке User/Group.Linux · Терминал (Bash)КомандаПути примерные; никаких прав команда не меняет.
namei -l /var/www/example.com/public/assets/site.css; ls -l /var/www/example.com/public/assets/site.css
- Проверьте журнал причин запретаВ том же временном интервале откройте ErrorLog сайта. Строка client denied by server configuration указывает скорее на Require или .htaccess, а Permission denied — на систему файлов либо политику безопасности. Для SELinux отдельно смотрите аудит; не отключайте его для диагностики на боевом сервере.
- Исправьте только нужное разрешениеСохраните текущие права и владельца перед точечной правкой. Для файла со статикой, доступного только через Apache, назначьте корректного владельца и группу в соответствии с устройством сайта, а не массово меняйте права всего /var/www. Если проблема в Require all denied внутри конкретного Directory — согласуйте политику доступа перед заменой. Закрытые файлы конфигурации должны остаться закрытыми.
- Проверяйте изменение безопасноЕсли меняли конфигурацию Apache, проверьте её синтаксис и перечитайте службу. Если меняли только разрешения файла, перезапуск не требуется. Запросите CSS снова и отдельно попробуйте URL приватного каталога: он должен остаться недоступным.
- Только для подтверждённой правки конфигурации, с резервной копиейLinux · Терминал (Bash)С осторожностьюНужен sudoТолько для подтверждённой правки конфигурации, с резервной копией.
sudo apache2ctl configtest && sudo systemctl reload apache2Команда может изменить состояние системы или её настройки. Проверьте параметры и последствия перед запуском.
#Как проверить результат
Проверяемый статический URL возвращает 200 и правильный тип содержимого, браузер перестал сообщать об ошибке загрузки CSS, а закрытые каталоги по-прежнему не открываются.
#Если проблема не устранена
Если файл читается Unix-пользователем сервера, но 403 остаётся, проверьте Directory/Location, Alias, .htaccess и политику SELinux/AppArmor. Не маскируйте проблему рекурсивным chmod 777.