Выберите продукт

Debian/Ubuntu: как исправить Permission denied между Nginx и PHP-FPM через Unix socket

Ошибка connect() to unix failed (13: Permission denied) между Nginx и PHP-FPM в Debian и Ubuntu обычно связана с правами на сокет, каталог или параметрами пула. Разберём, как проверить логи, пользователя Nginx, путь fastcgi_pass и настройки listen.owner, listen.group и listen.mode.
Debian/Ubuntu: как исправить Permission denied между Nginx и PHP-FPM через Unix socket

Связка Nginx и PHP-FPM в Debian и Ubuntu обычно работает стабильно годами, но одна из самых частых поломок выглядит неприятно и не слишком информативно: в логах Nginx появляется connect() to unix failed (13: Permission denied), а сайт начинает отдавать 502 Bad Gateway. На практике это почти всегда не «сломанный PHP», а проблема доступа к Unix socket.

Сценарий типичный: обновили пакет, поменяли пул PHP-FPM, отредактировали www.conf, перенесли конфиг с другого сервера, переключили версию PHP или просто не совпали пользователь и группа. В итоге Nginx пытается подключиться к сокету, но ядро запрещает доступ.

Хорошая новость в том, что диагностируется такая ситуация довольно быстро. Главное — не начинать с хаотичных изменений прав на всё подряд вроде chmod 777. Это не исправление, а способ замаскировать реальную проблему и создать новую.

Ниже разберём, как устроено взаимодействие Nginx и PHP-FPM через Unix socket, какие параметры отвечают за доступ, как проверить пользователя веб-сервера, что смотреть в php-fpm www.conf и почему проблема иногда кроется не в самом сокете, а в каталоге, где он лежит.

Материал ориентирован на Debian и Ubuntu, но сама логика пригодится и на других дистрибутивах. Примеры ниже даны для типовой схемы с php8.2-fpm или php8.3-fpm, однако подход одинаков и для других версий.

Как выглядит ошибка и что она означает

Обычно в логе Nginx можно увидеть одну из таких строк:

connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream
connect() to unix:/var/run/php/php-fpm.sock failed (13: Permission denied) while connecting to upstream

Ключевой фрагмент здесь — Permission denied. Он означает, что сокет существует или путь к нему указан корректно, но процесс Nginx не может открыть его из-за ограничений на уровне файловых прав.

Если бы сокета не было вообще, ошибка чаще выглядела бы как No such file or directory. А если PHP-FPM не слушал бы нужный адрес, вы бы увидели другой набор симптомов. Поэтому сообщение connect() to unix failed с кодом 13 почти всегда указывает именно на проблему прав доступа.

Самая частая причина: Nginx работает от пользователя www-data, а сокет PHP-FPM создан с владельцем или группой, которые этому пользователю недоступны.

Почему Unix socket ломается чаще, чем кажется

Unix socket — это специальный файл в файловой системе, через который Nginx общается с PHP-FPM локально на сервере. В Debian и Ubuntu он обычно создаётся в /run/php/ и выглядит как php8.2-fpm.sock.

Для подключения к сокету должны сойтись сразу несколько условий:

  • Nginx должен указывать на правильный путь в fastcgi_pass.
  • Сам сокет должен существовать.
  • Права на сокет должны позволять подключение.
  • Права на каталог, где лежит сокет, тоже должны позволять доступ.
  • PHP-FPM должен запускать пул с корректными настройками listen.owner, listen.group и listen.mode.

Достаточно одной ошибки в этой цепочке — и вы получите классический nginx permission denied.

Если проект размещён на виртуальном хостинге, доступ к системным пулам и сокетам обычно ограничен, и такие ошибки чаще актуальны для выделенных окружений. На своих серверах и в VDS эту схему нужно контролировать самостоятельно.

С чего начинать диагностику

Первое правило: сначала смотрим логи и фактическое состояние системы, потом меняем конфиг. Иначе очень легко лечить не ту проблему.

1. Проверяем лог Nginx

sudo tail -n 50 /var/log/nginx/error.log

Если у вас отдельный лог для виртуального хоста, смотрите и его. Нужно подтвердить, что ошибка действительно связана с connect() to unix failed и именно с Permission denied.

2. Проверяем, запущен ли PHP-FPM

sudo systemctl status php8.2-fpm
sudo systemctl status php8.3-fpm

Подставьте свою версию PHP. Если служба неактивна, сокет может не создаваться вовсе. Но даже при активной службе права на сокет могут быть неверными.

3. Смотрим, существует ли socket и какие у него права

ls -l /run/php/
stat /run/php/php8.2-fpm.sock

Вас интересуют владелец, группа и режим доступа. Для типовой установки в Debian и Ubuntu часто ожидается что-то вроде владельца www-data и режима 660.

4. Проверяем права на каталог

namei -l /run/php/php8.2-fpm.sock

Это очень полезная команда, о которой часто забывают. Даже если права на сам php-fpm socket выглядят нормальными, один из каталогов по пути может запрещать доступ. Например, сокет лежит в кастомном каталоге, у которого нет права на выполнение для нужной группы.

5. Проверяем, от какого пользователя работает Nginx

ps -o user,group,cmd -C nginx
grep -R "^user" /etc/nginx/nginx.conf

На Debian и Ubuntu это почти всегда www-data, но на нестандартных сборках или после ручных правок может быть иначе.

Если вы ведёте несколько сайтов на одном сервере, полезно заранее зафиксировать схему пользователей, групп и пулов PHP-FPM, чтобы не разбирать такие инциденты в аварийном режиме.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Какие параметры PHP-FPM отвечают за доступ к сокету

Главные настройки находятся в конфиге пула, обычно это файл вида /etc/php/8.2/fpm/pool.d/www.conf. Если у вас несколько пулов, проблема может быть не в www.conf, а в конкретном файле сайта.

Ищем такие параметры:

listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

Разберём их по смыслу:

  • listen — путь к Unix socket.
  • listen.owner — владелец сокета.
  • listen.group — группа сокета.
  • listen.mode — права доступа к сокету.

Если Nginx работает от www-data, то безопасный и практичный вариант для большинства случаев — дать сокету владельца и группу www-data с режимом 0660.

После изменения конфигурации нужен перезапуск или reload PHP-FPM, чтобы сокет был создан заново с новыми параметрами.

sudo systemctl restart php8.2-fpm
sudo systemctl reload nginx

Если вы параллельно меняете и инфраструктуру сайта, полезно держать под рукой отдельный план миграции без простоя: перенос сайта с минимальным downtime. Это помогает не смешивать ошибки сокета с последствиями переезда.

Проверка прав на Unix socket PHP-FPM и каталог /run/php в терминале Linux

Типовой рабочий вариант для Debian/Ubuntu

Если у вас обычный один сервер без экзотики, начните с такой схемы: Nginx работает от www-data, PHP-FPM пул тоже настроен на сокет в /run/php/, а права выставлены через listen.owner и listen.group.

Пример блока из www.conf:

[www]
user = www-data
group = www-data
listen = /run/php/php8.2-fpm.sock
listen.owner = www-data
listen.group = www-data
listen.mode = 0660

И соответствующий фрагмент в конфиге сайта Nginx:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}

Важно, чтобы путь в fastcgi_pass совпадал с тем, что указан в listen. Банально, но именно из-за старого пути после апгрейда с php8.1-fpm на php8.2-fpm часто начинаются поиски «битых прав», хотя проблема в несовпадении имени сокета.

Что ломается чаще всего на практике

Неверная группа сокета

Очень частый случай: пул PHP-FPM настроен так, что сокет создаётся с группой, в которой нет пользователя Nginx. Например, владелец сайта — отдельный системный пользователь, а Nginx продолжает работать как www-data.

В таком случае есть два рабочих подхода: либо привести сокет к группе www-data, либо осознанно добавить Nginx в нужную группу. Второй вариант требует аккуратности и понимания модели доступа, особенно на сервере с несколькими сайтами.

Права на сокет слишком строгие

Если установлен режим 0600, подключиться к сокету сможет только владелец. Для Nginx это обычно недостаточно, если он не является тем же пользователем.

Нормальный компромисс для большинства установок — 0660. Делать 0666 обычно не нужно.

Сокет лежит в нестандартном каталоге

Иногда администратор переносит сокет в каталог проекта, например в /home/site/run/ или /srv/app/tmp/. Сам файл сокета может иметь правильные права, но один из родительских каталогов не даёт Nginx пройти по пути.

Именно поэтому команда namei -l так полезна: она показывает права на каждом уровне.

Смешение пользователей пула и файлов сайта

Многие пытаются решить всё одной моделью: и PHP-FPM, и файлы сайта, и сокет, и Nginx должны работать от одного пользователя. Иногда это удобно, но нередко приводит к путанице. Важно понимать: права на сокет — это отдельная история, не всегда напрямую связанная с владельцем файлов проекта.

Пошаговый план исправления

Если нужно восстановить работу быстро и без лишних экспериментов, идите по такому порядку.

  1. Убедитесь, что в логе Nginx действительно ошибка Permission denied при доступе к Unix socket.
  2. Проверьте, что PHP-FPM запущен и создаёт нужный сокет.
  3. Сверьте путь fastcgi_pass в Nginx с параметром listen в пуле PHP-FPM.
  4. Посмотрите владельца, группу и режим сокета.
  5. Проверьте доступ к каталогам по пути до сокета.
  6. Приведите listen.owner, listen.group и listen.mode к ожидаемой схеме.
  7. Перезапустите PHP-FPM, затем перечитайте конфиг Nginx.
  8. Проверьте логи повторно.

В большинстве случаев проблема решается уже на шагах 3–6.

Сравнение настроек Nginx fastcgi_pass и параметров PHP-FPM listen в конфигурационных файлах

Пример полной проверки на сервере

Допустим, у вас в логе такая ошибка:

connect() to unix:/run/php/php8.2-fpm.sock failed (13: Permission denied) while connecting to upstream

Тогда последовательность может быть такой:

sudo grep -R "fastcgi_pass" /etc/nginx/sites-enabled
sudo grep -R "^listen" /etc/php/8.2/fpm/pool.d/
ls -l /run/php/
namei -l /run/php/php8.2-fpm.sock
ps -o user,group,cmd -C nginx
sudo systemctl restart php8.2-fpm
sudo nginx -t
sudo systemctl reload nginx

После этого откройте сайт снова и параллельно смотрите лог:

sudo tail -f /var/log/nginx/error.log

Если ошибка не исчезла, почти всегда проблема в том, что вы исправили не тот пул, не ту версию PHP или не тот виртуальный хост.

Когда проблема не в сокете, а выглядит похоже

Есть несколько ситуаций, которые внешне напоминают ошибку прав на Unix socket, но корень проблемы другой.

Неправильный путь к сокету после обновления PHP

Например, PHP-FPM уже работает как php8.3-fpm, а Nginx всё ещё смотрит в /run/php/php8.2-fpm.sock. В этом случае ошибка чаще будет про отсутствие файла, но в сложных конфигурациях легко запутаться и начать править не там.

Несколько пулов PHP-FPM

Один сайт использует www.conf, другой — отдельный пул site.conf. Вы меняете глобальный конфиг, а реальный трафик идёт в другой сокет. В результате кажется, что listen.owner не работает, хотя вы просто редактировали не тот файл.

Systemd override или tmpfiles

Если каталог для сокета создаётся нестандартно, его права могут переопределяться при старте системы. Тогда после ручного исправления всё «вдруг снова ломается» после reboot.

Если сервером управляют через панель, полезно заранее проверить, не переписывает ли она параметры пулов и виртуальных хостов. В таких сценариях помогает отдельный обзор: сравнение панелей управления для VDS.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Почему не стоит лечить это через chmod 777

Такой совет до сих пор встречается в случайных обсуждениях, но использовать его в продакшене нельзя. Да, иногда это временно снимает симптом, потому что все получают доступ ко всему. Но вместе с этим вы теряете контроль над моделью безопасности и усложняете дальнейшую диагностику.

Если для починки php-fpm socket понадобился 777, значит, причина не найдена, а просто скрыта.

Правильное решение — определить, какой пользователь должен подключаться к сокету, и явно выдать доступ через listen.owner, listen.group и listen.mode.

Что выбрать: Unix socket или TCP localhost

Иногда после нескольких неудачных попыток хочется отказаться от Unix socket и перевести связку на TCP, например 127.0.0.1:9000. Это рабочий вариант, но не универсальная «таблетка».

У TCP свои плюсы: проще визуально понимать схему, легче диагностировать сетевыми инструментами, нет файловых прав на сокет. Но появляются сетевые параметры, а также требуется следить, чтобы PHP-FPM слушал только локальный интерфейс.

Unix socket в локальной связке Nginx и PHP-FPM остаётся нормальным и эффективным выбором. Если всё настроено правильно, проблем он не создаёт. Поэтому сначала лучше исправить права, а не менять архитектуру без необходимости.

Мини-чеклист после исправления

  • Путь в fastcgi_pass совпадает с listen.
  • Nginx работает от того пользователя, которому доступен сокет.
  • listen.owner и listen.group соответствуют вашей схеме.
  • listen.mode обычно установлен в 0660.
  • Каталог с сокетом доступен по всей цепочке пути.
  • После изменения конфига PHP-FPM был перезапущен.
  • nginx -t выполняется без ошибок.

Итог

Ошибка nginx permission denied при подключении к php-fpm socket в Debian и Ubuntu почти всегда сводится к трём вещам: неверный путь, неверный владелец или группа сокета, либо недостаточные права на сам сокет или каталог с ним. Это неприятная, но обычно быстрая в исправлении проблема.

Если действовать последовательно — проверить лог, состояние службы, путь сокета, пользователя Nginx, параметры listen.owner, listen.group и права на каталог — причина находится без долгих догадок. А главное, без опасных костылей вроде глобальных разрешений на запись и чтение.

На рабочих серверах лучше придерживаться простой и предсказуемой схемы: Nginx и PHP-FPM согласованы по пользователю и группе, сокеты лежат в стандартном каталоге, а каждый пул имеет явно заданные параметры доступа. Тогда даже после обновлений и миграций такие сбои диагностируются за несколько минут.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: как исправить systemd service holdoff time over и restart counter is at OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить systemd service holdoff time over и restart counter is at

Если сервис в Debian или Ubuntu уходит в цикл перезапусков, systemd показывает holdoff time over и restart counter is at. Разберём ...
Debian/Ubuntu: RTNETLINK answers: File exists — как исправить ошибки IP, route и netplan OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: RTNETLINK answers: File exists — как исправить ошибки IP, route и netplan

Ошибка RTNETLINK answers: File exists в Debian и Ubuntu обычно означает, что IP-адрес, маршрут или правило уже существуют. Показыв ...
Debian/Ubuntu: rp_filter, reverse path filtering и policy routing без сюрпризов OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: rp_filter, reverse path filtering и policy routing без сюрпризов

Разбираем, как в Debian/Ubuntu работает reverse path filtering, почему в dmesg появляются martian source и как правильно сочетать ...