С чего начать Первые шаги трек · 15 ступеней
Linux Labs

Unix-сокеты — связь процессов через файл

7 мин Ubuntu 24.04 · iproute2 6.1 · nginx 1.24

Unix-сокет — файл, через который процессы одной машины обмениваются данными; подключается тот, у кого есть право записи.

Шпаргалка

9 команд Версия для печати
  • ls -l /run/app/app.sock s первой буквой — сокет
  • stat -c '%F %a %U:%G' /run/app/app.sock тип, режим, владелец
  • ss -xl слушающие unix-сокеты
  • sudo ss -xlp | grep app.sock какой процесс слушает
  • sudo find /run -type s сокеты в /run
  • curl --unix-socket /run/app/app.sock http://localhost/ HTTP в сокет
  • nc -U /run/app/app.sock сырое соединение
  • sudo chgrp www-data /run/app/app.sock доступ группе nginx
  • sudo chmod 660 /run/app/app.sock

Обзор

Unix-сокет — точка связи двух процессов на одной машине. Как и с сетевым сокетом, сервер его слушает, а клиент подключается, только адрес — не IP и порт, а путь к файлу: /run/app/app.sock. Данные идут через ядро и в сеть не попадают.

Где встречается: PostgreSQL слушает /var/run/postgresql/.s.PGSQL.5432 — через него подключается psql без -h; Docker — /run/docker.sock; systemd и D-Bus держат десятки сокетов в /run. Приложение за nginx часто слушает сокет вместо порта: порт не занят, снаружи до приложения не достать, доступ решают права файла.

text
$ ls -l /run/app/app.sock
srwxr-xr-x 1 root root 0 Oct 20 10:04 /run/app/app.sock

s первой буквой — тип «сокет». Размер всегда 0: данные в файле не лежат.

Права: кто может подключиться

Чтобы подключиться, клиенту нужно право записи на файл сокета и право входа (x) во все каталоги пути. Право чтения не нужно.

Файл создаёт сервер, права берутся из его umask. Процесс от root с маской 022 создаёт srwxr-xr-x root root — подключится только root. Клиент nginx — пользователь www-data:

Права сокета www-data подключится?
srwxr-xr-x root root нет: у остальных нет w
srw-rw---- root www-data да: w у группы
srwxrwxrwx root root да, как и любой пользователь

Режим 777 открывает сокет всем процессам машины. Доступ дают группой, в которой состоит клиент, и режимом 660 или 770.

Жизнь файла сокета

Сервер создаёт файл, когда начинает слушать, и сам должен удалить его при выходе. Упавший или убитый процесс оставляет файл: путь есть, а слушать некому. Клиент тогда получает Connection refused, а новый запуск сервера — Address already in use, пока старый файл не удалят.

/run живёт в памяти и после перезагрузки пуст. Каталог для сокета службы создаёт systemd: строка RuntimeDirectory=app в юните — и /run/app появляется при старте службы и исчезает при остановке.

Рецепты

4

Кто слушает сокет

bash
ss -xl | grep app.sock
sudo ss -xlp | grep app.sock
text
u_str LISTEN 0 5 /run/app/app.sock 12366 * 0

u_str — потоковый сокет (как TCP), u_dgr — датаграммы (как UDP). Ключ -p добавляет процесс: users:(("python3",pid=1750,fd=3)); чужие процессы видно только с sudo. Файл есть, а в ss -xl его нет — сокет никто не слушает.

Проверить сокет руками

bash
curl --unix-socket /run/app/app.sock http://localhost/
printf 'GET / HTTP/1.0\r\n\r\n' | nc -U /run/app/app.sock

curl шлёт HTTP-запрос в сокет, имя в адресе идёт только в заголовок Host. Ошибку curl пишет обманчиво: и без прав, и без файла — Failed to connect to localhost port 80 … Couldn't connect to server, хотя ни localhost, ни порт 80 тут ни при чём. nc -U называет причину прямо: nc: /run/app/app.sock: Permission denied.

Дать доступ nginx

bash
sudo chgrp www-data /run/app/app.sock
sudo chmod 660 /run/app/app.sock

Такая правка живёт до перезапуска приложения: сокет — а с RuntimeDirectory и весь каталог — создаётся заново, с прежними правами. Насовсем — в настройках приложения (многие умеют задать режим и группу сокета) или в юните службы, которая создаёт сокет:

ini
[Service]
RuntimeDirectory=app
Group=www-data
UMask=0007

Сокет получит группу www-data и режим srwxrwx---.

Другой путь — добавить www-data в группу сокета: sudo usermod -aG app www-data. Группы рабочих процессов nginx берёт при их запуске, поэтому после usermod нужен sudo systemctl reload nginx — он запускает новые рабочие процессы уже с этой группой.

Сокет PostgreSQL

bash
ls -la /var/run/postgresql/
sudo -u postgres psql -h /var/run/postgresql -c 'SELECT 1'

Каталог в -h — подключение через сокет, как без -h вовсе. Такое подключение PostgreSQL проверяет по строкам local в pg_hba.conf; -h 127.0.0.1 — уже TCP и строки host.

Неполадки

4

Permission denied при подключении

nginx пишет connect() to unix:/run/app/app.sock failed (13: Permission denied) while connecting to upstream и отвечает 502, nc -U — Permission denied. У клиента нет права записи на файл или входа в каталог пути. Посмотри ls -l файла и namei -l пути: клиент (для nginx — www-data) должен попадать в группу с w и проходить все каталоги.

No such file or directory

nginx — (2: No such file or directory), psql — connection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failed: No such file or directory. Файла нет: опечатка в пути у клиента, сервер не запущен или создаёт сокет в другом месте. Где он слушает на самом деле, покажет ss -xl.

Connection refused, хотя файл на месте

Файл остался от остановленного процесса — в ss -xl его нет. Запусти службу; не стартует из-за Address already in use — удали старый файл.

Address already in use

Сервер не может создать сокет: файл с этим именем уже есть. У Python — OSError: [Errno 98] Address already in use. Проверь, что старый процесс не работает (sudo ss -xlp), и удали файл — или пусть служба удаляет его перед стартом.

Опасно

1

chmod 777 на сокет

Сокет с w для всех принимает команды от любого пользователя машины. Для /run/docker.sock это доступ уровня root: кто пишет в него, запускает контейнеры с любыми правами. Доступ дают группой.

Термины

1
unix-сокет unix socket
Файл-точка связи процессов на одной машине (s первой буквой в ls -l): сервер его слушает, клиент подключается по пути. Подключиться может тот, у кого есть право записи на файл. Ещё встречается в: curl, nginx, PostgreSQL, Docker и ещё 1

См. также

  • nginx — proxy_pass на сокет, ошибки 502.
  • ss — ss -xl, слушающие сокеты.
  • permissions — права rwx, владелец и группа.
  • umask — с какими правами создаётся файл сокета.
  • namei — права по всему пути к файлу.
  • postgresql — локальный сокет и вход peer.
  • docker — docker.sock и группа docker.
  • systemd — RuntimeDirectory, Group, UMask в юните.
Загрузка…