nginx 403 Forbidden и Permission denied на файлы сайта
Ошибка 403 при отдаче статики почти всегда про права. Рабочие процессы nginx работают от непривилегированного пользователя, и им нужен доступ не только к файлу, но и ко всем каталогам по пути — включая домашний каталог, если сайт лежит там.
Вероятные причины
По порядку: сверху то, что встречается чаще.
-
Нет права на вход в каталог по пути
Сайт в домашнем каталоге пользователя с правами 0700 недоступен рабочим процессам nginx. Права на сам файл при этом могут быть верными.
-
Файлы принадлежат другому пользователю без прав на чтение
После выгрузки сайта под root файлы могут оказаться с правами 0600. Для nginx они недоступны.
-
Нет индексного файла, а листинг каталога отключён
При запросе каталога без index.html и без
autoindex onnginx отдаёт 403. Это не про права, хотя код тот же. -
Запрещает SELinux или AppArmor
На системах с SELinux файлы сайта должны иметь подходящую метку. Стандартные права при этом в порядке, и причина не видна.
Диагностика
Команды идут в том порядке, в котором их стоит выполнять: каждая следующая проверяет то, что осталось после предыдущей.
Точное сообщение: отказ в доступе, отсутствие индекса или запрет модуля безопасности.
sudo tail -20 /var/log/nginx/error.logПрава на каждом уровне пути — быстрее, чем перебирать каталоги вручную.
namei -l /путь/к/файлу/сайтаПроверка от имени пользователя рабочих процессов nginx.
sudo -u www-data test -r /путь/к/файлу && echo читается || echo отказРешение
Решение своё для каждой причины. Сначала определите, какая из них ваша, — иначе правки наложатся друг на друга.
- Почему происходит
- Сайт в домашнем каталоге пользователя с правами 0700 недоступен рабочим процессам nginx. Права на сам файл при этом могут быть верными.
- Как проверить
-
Пройдите по пути от корня.
namei -l /home/user/site/index.html
- Как исправить
-
Дайте право на вход в каталоги по пути (бит x) или перенесите сайт в /var/www, где такой проблемы нет.
sudo chmod o+x /home/user /home/user/site
- Почему происходит
- После выгрузки сайта под root файлы могут оказаться с правами 0600. Для nginx они недоступны.
- Как проверить
-
Посмотрите права на файлы сайта.
ls -l /var/www/site | head sudo -u www-data test -r /var/www/site/index.html && echo читается || echo отказ
- Как исправить
-
Выставьте права 0644 на файлы и 0755 на каталоги, владельцем оставьте того, кто выкладывает сайт.
sudo find /var/www/site -type f -exec chmod 644 {} + && sudo find /var/www/site -type d -exec chmod 755 {} +
- Почему происходит
- При запросе каталога без index.html и без
autoindex onnginx отдаёт 403. Это не про права, хотя код тот же.
- Как проверить
-
Посмотрите, что в каталоге, и настройку индекса.
ls /var/www/site/ | head sudo nginx -T 2>/dev/null | grep -E "index|autoindex"
- Как исправить
- Добавьте индексный файл или включите листинг каталога, если он действительно нужен.
- Почему происходит
- На системах с SELinux файлы сайта должны иметь подходящую метку. Стандартные права при этом в порядке, и причина не видна.
- Как проверить
-
Посмотрите отказы модуля безопасности.
sudo ausearch -m avc -ts recent 2>/dev/null | tail -10 ls -Z /var/www/site/index.html 2>/dev/null
- Как исправить
-
Разметьте каталог сайта нужным типом и восстановите контексты.
sudo semanage fcontext -a -t httpd_sys_content_t "/var/www/site(/.*)?" && sudo restorecon -R /var/www/site
Пример вывода
Сайт в домашнем каталоге недоступен рабочим процессам. Пример показательный: он собран на тестовой машине специально для этой страницы, а не взят из чужого журнала.
2026/09/15 15:02:41 [error] 1121#1121: *12 open() "/home/user/site/index.html" failed (13: Permission denied), client: <адрес>, server: example.org, request: "GET / HTTP/1.1"
Связанные ошибки
- Permission denied в журнале службы Отказ в доступе у службы systemd: права на файл, каталоги по пути, пользователь службы, параметры изоляции, SELinux и AppArmor.
- No such file or directory в журнале службы Служба не находит файл или каталог. Разбор: путь, момент запуска, изоляция unit-файла, символические ссылки, приватный /tmp.
- MySQL: Can't open the mysql.plugin table и повреждение системных таблиц MySQL не запускается: недоступны или повреждены системные таблицы. Права на каталог данных, версия схемы, восстановление.
- PostgreSQL: data directory has invalid permissions Кластер PostgreSQL не запускается из-за прав на каталог данных. Требование 0700 или 0750 и как вернуть владельца.
- nginx 502 Bad Gateway: connect() failed к приложению nginx работает, а приложение недоступно: connect() failed, connection refused, no such file or directory для сокета. Разбор 502.
- nginx 504 Gateway Time-out: upstream timed out nginx не дождался ответа приложения. Разбор таймаутов proxy_read_timeout и fastcgi_read_timeout, поиск медленных мест.
- nginx reload не применяет изменения Перезагрузка nginx прошла, а изменения не действуют: правка не в том файле, файл не включён, кеш, старые рабочие процессы.
- nginx: [emerg] host not found in upstream nginx не запускается: не разрешается имя узла из upstream или proxy_pass. Разбор порядка запуска и работы с именами.
Где встречается чаще всего
Источники
- Документация nginx: директивы index и autoindex
-
Воспроизведено на тестовой машине, systemd 255 (Ubuntu 24.04)
Воспроизведено сайтом в домашнем каталоге с правами 0700.