Ошибка 403 Forbidden при открытии сайта на Apache2 в Ubuntu — классика, с которой сталкивается каждый, кто начинает работать с веб-сервером. В девяти случаях из десяти проблема не в конфигурации виртуального хоста, а в правах доступа к файлам и каталогам. Мелкая оплошность с владельцем, группой или флагом x на директории — и Apache молча отказывается отдавать страницу. Я сам, когда только осваивал администрирование в Бугульме, не раз ловил 403 из-за того, что после переноса сайта забывал поправить группу на www-data или не давал каталогу право на вход.
Хорошая новость: если понять логику, настройка становится предсказуемой и безопасной. В этой статье разберём, какие права нужны файлам сайта, как их выдать без лишней щедрости, чем отличаются владелец и группа, какие команды использовать для типового сайта в /var/www и как проверить, что Apache действительно видит нужные каталоги и файлы. Все примеры — из реальной практики, без абстрактных «рекомендаций».
Что Apache2 должен уметь делать с файлами сайта
В Ubuntu Apache по умолчанию работает от системного пользователя www-data. Именно от его имени веб-сервер пытается прочитать файлы, когда приходит HTTP-запрос. Чтобы успешно отдать страницу, процессу нужны три вещи:
- возможность прочитать сам файл — для этого достаточно права
rна файле; - возможность пройти по всей цепочке каталогов до файла — здесь требуется право
x(вход) на каждом каталоге в пути; - иногда — запись в специально отведённые директории, например
uploads,cacheилиtmp, если сайт загружает изображения, кеширует данные или ведёт логи.
Для статической HTML-страницы первых двух пунктов достаточно. Для CMS вроде WordPress, самописных PHP-приложений или форм загрузки правила ужесточаются: запись нужна, но давать её всему дереву сайта — грубая ошибка. Важно точечно открывать только те папки, куда действительно пишет веб-приложение.
Отдельно замечу: если вы используете PHP-FPM, процессы могут работать от другого пользователя (например, от имени владельца сайта). Но в классической связке с mod_php внутри Apache — это всегда www-data. Дальше будем рассматривать именно этот, самый частый сценарий.
Базовая логика прав
- Файл должен быть как минимум читаемым для Apache.
- Каталог должен быть доступен на проход (иметь
x), иначе файл внутри не откроется, даже если у него права644. - Запись даём только там, где она действительно нужна, и только тем, кому она нужна.
- Владельца и группу выбираем осознанно, а не ставим везде
777«чтобы заработало».
Что означают права rwx простыми словами
В Linux права на файлы и каталоги записываются тремя символами: r (read — чтение), w (write — запись), x (execute — выполнение). Для обычного файла x означает возможность запустить его как программу или скрипт. Но для каталога смысл меняется: x — это не запуск, а право войти в каталог и пройти дальше по дереву. Без этого флага Apache не сможет «заглянуть» внутрь директории, даже если у него есть права на чтение самого каталога.
Новички часто путают: видят, что на каталоге стоят права rw-r--r-- (644), и думают, что Apache сможет прочитать файлы внутри. Но без x вход закрыт. Поэтому каталогам всегда нужно давать x для тех пользователей, которые должны по ним перемещаться.
Примеры типовых прав
| Объект | Права | Что это значит |
|---|---|---|
| Файл | 644 |
владелец может читать и писать, остальные только читать |
| Каталог | 755 |
владелец может всё, остальные могут заходить и читать содержимое |
| Каталог с совместной записью | 775 |
владелец и группа могут писать, остальные только читать |
| Опасный вариант | 777 |
писать может любой пользователь, обычно это плохая идея |
Для сайта в большинстве случаев безопасная база выглядит так:
- каталоги:
755; - файлы:
644.
Если сайт генерирует контент через PHP, то папки, куда идёт запись, дополнительно получают 775 и группу www-data.
Типовая схема для сайта в /var/www
Самый частый сценарий в Ubuntu: сайт лежит в /var/www/example, Apache читает файлы от пользователя www-data, администратор редактирует файлы под своим обычным пользователем (например, user), а запись веб-серверу нужна только в отдельные каталоги. Для такого варианта я обычно использую связку:
- владелец — мой пользователь (или
root, если сайт разворачивается из-под рута, но лучше избегать); - группа —
www-data, чтобы Apache мог читать всё без лишних ограничений; - права на каталоги и файлы —
755и644соответственно.
Такая схема удобна тем, что я могу редактировать файлы без постоянного sudo, а веб-сервер при этом спокойно читает контент. Запись для Apache открывается точечно на уровне конкретных папок.
Когда этого достаточно
- сайт статический;
- вы редактируете файлы вручную по SSH;
- PHP не должен создавать файлы в основном дереве сайта;
- записи нужны только в отдельных папках (uploads, cache).
Когда этого мало
Понадобится допуск на запись для Apache, если:
- сайт загружает изображения или другие файлы через веб-интерфейс;
- используется кеширование на уровне приложения (Twig, Blade, файловый кеш);
- CMS создаёт временные файлы или логи внутри веб-доступной структуры;
- есть автоматические обновления плагинов или тем, которые пишут в файловую систему.
В таких случаях мы не меняем владельца всего сайта на www-data, а точечно даём группе www-data права на запись в нужные каталоги. Это безопаснее и не ломает привычный процесс ручного администрирования.
Практическая схема настройки
Ниже — безопасный и понятный вариант для типового сайта, который я применяю на своих серверах. Все команды выполняются от root или через sudo.
1. Посмотреть текущие права
ls -la /var/www/example
Эта команда покажет владельца, группу и права для каждого объекта в корне сайта. Обратите внимание на первый столбец: если каталоги не имеют x для группы или остальных, Apache не сможет в них войти.
Если нужен подробный просмотр по всему дереву:
find /var/www/example -exec ls -ld {} \;
Но такой вывод может быть избыточным. Чаще достаточно проверить ключевые каталоги и несколько файлов.
2. Назначить владельца и группу
Если сайт обслуживается вами, а Apache должен иметь доступ на чтение через группу:
chown -R user:www-data /var/www/example
Здесь user — ваш обычный пользователь, под которым вы заходите по SSH. После этого все файлы и каталоги будут принадлежать вам, но группа www-data сможет их читать (при условии, что права на чтение для группы установлены).
Если сайт полностью под управлением веб-сервера и запись от имени сервера действительно нужна (например, автообновления), можно использовать www-data:www-data, но только осознанно. В этом случае вам придётся либо работать под www-data через sudo, либо добавить своего пользователя в группу www-data и дать права на запись группе. Я предпочитаю первый вариант — он проще и прозрачнее.
3. Выдать правильные права на каталоги и файлы
Рекурсивно выставляем права, но раздельно для каталогов и файлов. Так мы избежим случайного присвоения флага выполнения обычным файлам (картинкам, CSS, PHP-скриптам, которым x не нужен).
find /var/www/example -type d -exec chmod 755 {} \;
find /var/www/example -type f -exec chmod 644 {} \;
Это одна из самых надёжных базовых схем. После выполнения проверьте результат на паре каталогов и файлов:
ls -la /var/www/example
ls -la /var/www/example/index.html
Убедитесь, что каталоги имеют drwxr-xr-x, а файлы — -rw-r--r--.
4. Дать запись только нужным каталогам
Например, для папки uploads:
chmod 775 /var/www/example/uploads
chown :www-data /var/www/example/uploads
Если писать должны и вы, и Apache, удобнее также правильно выставить группу и, возможно, добавить setgid-бит, чтобы новые файлы внутри наследовали группу www-data:
chmod 2775 /var/www/example/uploads
Теперь любой файл, созданный в этой папке (даже вами), автоматически получит группу www-data, и Apache сможет с ним работать. Это решает классическую проблему, когда вы загружаете файл через SSH, а веб-приложение потом не может его прочитать или изменить.
Как понять, что Apache упирается именно в права
Если сайт открывается с ошибкой 403 Forbidden, не спешите сразу менять конфиг виртуального хоста. Сначала проверьте по порядку:
- существует ли каталог и файл;
- может ли Apache пройти по цепочке каталогов (права
xна каждом уровне); - читает ли он сам файл (права
r); - нет ли запрета в
.htaccessили конфиге виртуального хоста; - не мешает ли AppArmor (в Ubuntu он активен по умолчанию и может ограничивать доступ Apache к каталогам вне
/var/www/).
Быстрая диагностика
namei -l /var/www/example/index.html
Эта команда показывает права на каждый каталог по пути к файлу. Вывод выглядит примерно так:
drwxr-xr-x root root /
drwxr-xr-x root root var
drwxr-xr-x root root www
drwxr-xr-x user www-data example
-rw-r--r-- user www-data index.html
Если на каком-то уровне отсутствует x для пользователя www-data (или для «остальных», если Apache не входит в группу-владельца), доступ оборвётся именно там. Очень полезно, когда файл вроде бы читаемый, а сайт всё равно не открывается.
Также стоит посмотреть журналы Apache:
tail -f /var/log/apache2/error.log
В логах часто прямо написано Permission denied с указанием пути к файлу или каталогу. Ищите строки с (13)Permission denied — это верный признак проблемы с правами.
Отдельно упомяну AppArmor. В Ubuntu для Apache есть профиль, который по умолчанию разрешает чтение только из /var/www/ и некоторых других мест. Если ваш сайт лежит в нестандартном каталоге (например, /home/user/site), AppArmor может молча блокировать доступ, даже если права выставлены верно. Проверить статус можно командой aa-status. Для диагностики можно временно перевести профиль Apache в режим жалоб (aa-complain /usr/sbin/apache2) и повторить запрос. Если 403 исчезла — дело в AppArmor, и нужно корректировать профиль, а не права.
Частые ошибки
Ошибка 1. Ставить 777 на весь сайт
Это самый вредный «быстрый фикс». Да, сайт может заработать. Но любой локальный пользователь на сервере (включая потенциально скомпрометированного) получит возможность менять файлы. Если злоумышленник найдёт уязвимость в соседнем сервисе и получит shell, он сможет беспрепятственно модифицировать ваш сайт. Кроме того, 777 маскирует настоящую причину ошибки, и вы никогда не узнаете, что именно было настроено неправильно.
Ошибка 2. Давать запись всему дереву сайта
Если PHP или другой процесс может писать во все файлы, риск повреждения сайта резко возрастает. Достаточно одной уязвимости в плагине — и злоумышленник зальёт веб-шелл в корень сайта. Записываемыми должны быть только нужные каталоги, и желательно с минимально необходимыми правами.
Ошибка 3. Менять только права файла, забывая про каталог
Файл может быть 644, но если у родительского каталога нет x для Apache, веб-сервер его не прочитает. Новички часто грешат тем, что смотрят только на права index.php, а про каталог забывают. Проверяйте всю цепочку с помощью namei -l.
Ошибка 4. Не учитывать группу
Часто владелец правильный, а группа нет. Например, после копирования файлов через scp группа может остаться от старого сервера. В результате пользователь редактирует сайт, а Apache не видит часть файлов, потому что права для группы (или остальных) не дают доступа. Всегда проверяйте, что группа на файлах и каталогах — www-data (или та, от которой работает Apache), и что права для группы включают чтение и, где нужно, запись.
Ошибка 5. Переносить сайт и не пересмотреть права
После копирования проекта с другого сервера могут остаться чужие владельцы (например, root:root или пользователь, которого нет на новом сервере), странные ACL или права, которые на старом хостинге работали, а на Ubuntu уже нет. Всегда после переноса прогоняйте chown и chmod заново, ориентируясь на целевую схему.
Когда менять владельца, а когда достаточно группы
Это важный практический вопрос, от которого зависит удобство ежедневной работы.
Оставить владельцем себя, группу дать Apache
Подходит, если:
- вы вручную ведёте сайт по SSH;
- Apache должен только читать;
- запись нужна лишь в отдельных папках.
Плюс: удобно редактировать файлы без постоянного sudo. Вы остаётесь хозяином кода, а веб-сервер — только читатель. Это мой стандартный выбор для большинства проектов.
Сделать владельцем www-data
Подходит, если:
- сайт сам создаёт много файлов (например, кеш, сгенерированные изображения);
- процесс веб-сервера — основной писатель;
- управление идёт через веб-приложение (админка, автообновления).
Минус: не всегда удобно администрировать вручную. Чтобы отредактировать файл, придётся либо использовать sudo -u www-data vim, либо временно менять владельца. Кроме того, легко случайно отдать серверу слишком много полномочий: если злоумышленник проэксплуатирует уязвимость в веб-приложении, он получит права www-data на всё дерево сайта.
Практический совет
Для большинства обычных сайтов в Ubuntu безопаснее держать основное дерево сайта под своим пользователем, а запись разрешать точечно через группу www-data и права 775 на конкретных папках. Если приложение требует более широких прав, лучше разобраться, какие именно каталоги ему нужны, и открыть только их. Например, для WordPress достаточно дать запись на wp-content/uploads и, возможно, wp-content/cache, но не на весь wp-content и тем более не на корень.
Рекомендуемые значения прав для разных типов каталогов
| Элемент | Рекомендуемые права | Комментарий |
|---|---|---|
| Основной каталог сайта | 755 |
Apache должен проходить внутрь |
| HTML/PHP-файлы | 644 |
чтение для всех, запись только у владельца |
| Папка загрузок | 775 |
если пишет владелец и группа |
| Временные файлы | 775 или по задаче |
зависит от приложения |
| Конфиги с секретами | 640 |
если их не должен читать лишний пользователь; владелец — вы, группа — www-data (если нужно чтение веб-сервером) |
Обратите внимание на конфиги с паролями и ключами: часто они лежат за пределами document root, но если всё же находятся внутри, ставьте 640 и владельца root:www-data или user:www-data, чтобы Apache мог прочитать, а посторонние локальные пользователи — нет.
Пошаговый чек-лист настройки
Перед изменениями
- [ ] Определить, кто должен редактировать сайт (вы, несколько администраторов, только веб-приложение).
- [ ] Проверить, где лежит document root (обычно
/var/www/example). - [ ] Найти каталоги, в которые нужен режим записи (uploads, cache, tmp, логи).
- [ ] Посмотреть текущие владельцы и права (
ls -la). - [ ] Проверить, активен ли AppArmor для Apache (
aa-status | grep apache), и не ограничивает ли он доступ к нестандартным путям.
После изменений
- [ ] Убедиться, что каталоги доступны на проход (
namei -l /путь/к/файлу). - [ ] Проверить, что файлы читаются (хотя бы один статический файл открыть в браузере).
- [ ] Открыть сайт в браузере, проверить главную и несколько внутренних страниц.
- [ ] Посмотреть
/var/log/apache2/error.log, если что-то не так. - [ ] Протестировать загрузку файлов, если сайт это поддерживает.
- [ ] Убедиться, что права не сброшены деплой-скриптом или системой контроля версий.
Минимальный рабочий пример
Допустим, сайт лежит в /var/www/blog, и нужно сделать его читаемым для Apache, а папку загрузок — записываемой. Я обычно выполняю такую последовательность:
chown -R user:www-data /var/www/blog
find /var/www/blog -type d -exec chmod 755 {} \;
find /var/www/blog -type f -exec chmod 644 {} \;
chmod 775 /var/www/blog/uploads
chmod g+s /var/www/blog/uploads
Последняя команда устанавливает setgid-бит, чтобы все новые файлы в uploads создавались с группой www-data. Это особенно удобно, если вы иногда загружаете файлы вручную.
Если загрузки всё ещё не работают, проверьте:
ls -la /var/www/blog/uploads
Убедитесь, что владелец-группа и права соответствуют ожидаемым. Также посмотрите, не переопределяет ли что-то .htaccess в этой папке (например, запрет на выполнение PHP-скриптов — это правильно, но иногда там могут быть лишние ограничения).
Что делать, если сайт всё равно не открывается
Если права вроде бы выставлены правильно, а ошибка остаётся, проверьте по порядку:
- правильность
DocumentRootв конфиге виртуального хоста — возможно, Apache смотрит не в тот каталог; - наличие
Directory-блока с разрешениемRequire all granted(для Apache 2.4+) — без этого доступ будет запрещён на уровне конфигурации, независимо от файловых прав; - наличие индексного файла (
index.html,index.php) — если его нет, а листинг каталогов запрещён, Apache вернёт 403; - логи Apache —
error.logчасто содержит точную причину; - корректность пути к файлам — нет ли опечатки в конфиге;
- не перезаписывает ли права деплой-скрипт (Ansible, git hook) — иногда после пуша права сбрасываются на значения по умолчанию;
- права на родительский каталог
/var/www— он должен быть доступен на проход дляwww-data. Обычно там755и владелецroot, но если кто-то поставил750, Apache не сможет войти в/var/wwwи, соответственно, в ваш сайт; - AppArmor — как уже говорил, проверьте
aa-statusи при необходимости настройте профиль или переместите сайт в/var/www/.
Иногда проблема вообще не в правах на файл, а в правах на родительский каталог или в неверной настройке самого виртуального хоста. Поэтому не зацикливайтесь только на chmod — смотрите на картину целиком.
Итоги
Права доступа в Apache2 на Ubuntu проще всего настраивать по принципу минимальной достаточности: каталогам нужен проход (x), файлам — чтение (r), запись — только там, где она действительно нужна. Для большинства сайтов хорошая база — 755 для директорий и 644 для файлов, а отдельные папки для загрузок и кеша настраиваются точечно через группу www-data и права 775. Не поддавайтесь соблазну поставить 777 — это не решение, а замаскированная проблема. Проверяйте цепочку каталогов с помощью namei -l, читайте логи и помните про AppArmor. Тогда 403 Forbidden перестанет быть загадкой и превратится в понятную диагностическую задачу.
FAQ
Почему Apache не открывает файл, хотя у него права 644?
Чаще всего проблема в родительском каталоге: у него нет права x для пользователя www-data, либо неверно задан владелец, группа или путь в виртуальном хосте. Проверьте всю цепочку командой namei -l /путь/к/файлу. Если на каком-то уровне вместо x стоит прочерк, Apache не пройдёт дальше. Также убедитесь, что в конфиге виртуального хоста нет запретов типа Require all denied.
Можно ли ставить 777, если это временно?
Технически можно, но лучше не делать этого даже временно. Такой подход слишком рискованный: любой локальный процесс сможет изменить файлы, а вы не узнаете истинную причину ошибки. Кроме того, временное часто становится постоянным — забудете исправить, и сайт останется уязвимым. Лучше сразу разобраться, каких именно прав не хватает, и дать их прицельно.
Нужно ли делать весь сайт владельцем www-data?
Нет, если веб-серверу нужен только доступ на чтение. Обычно безопаснее оставить владельцем себя, а группу дать www-data. Это позволяет редактировать файлы без sudo и ограничивает потенциальный ущерб от взлома веб-приложения. Передавать владельца www-data стоит только в том случае, когда сервер действительно должен писать во многие каталоги, и вы осознаёте все риски.
Какие права ставить на папку uploads?
Обычно 775, если писать должны владелец и группа. Но конкретная схема зависит от того, от имени какого пользователя работает загрузка. Если загрузка идёт через PHP внутри Apache (mod_php), процесс работает от www-data, поэтому папка должна принадлежать группе www-data с правами rwx для группы. Рекомендую также установить setgid-бит (chmod g+s uploads), чтобы новые файлы наследовали группу и не возникало проблем с правами.
Как быстро проверить путь к проблемному файлу?
Используйте namei -l /путь/к/файлу — эта команда показывает права на каждом уровне каталога и помогает быстро найти узкое место. Вывод наглядно демонстрирует, где именно отсутствует доступ. Дополнительно смотрите /var/log/apache2/error.log — там часто указан конкретный файл или каталог с ошибкой Permission denied.
