Where to start First steps track · 15 stages
Linux Labs

Unix sockets — processes talking through a file

9 min Ubuntu 24.04 · iproute2 6.1 · nginx 1.24

A unix socket is a file through which processes on one machine exchange data; connecting needs write permission on it.

Cheat sheet

9 commands Printable version
  • ls -l /run/app/app.sock s as the first letter — a socket
  • stat -c '%F %a %U:%G' /run/app/app.sock type, mode, owner
  • ss -xl listening unix sockets
  • sudo ss -xlp | grep app.sock which process listens
  • sudo find /run -type s sockets under /run
  • curl --unix-socket /run/app/app.sock http://localhost/ HTTP over it
  • nc -U /run/app/app.sock a raw connection
  • sudo chgrp www-data /run/app/app.sock access for nginx's group
  • sudo chmod 660 /run/app/app.sock

Overview

A unix socket is a meeting point for two processes on one machine. As with a network socket, the server listens and the client connects, but the address is a file path such as /run/app/app.sock instead of an IP and port. Data goes through the kernel and never reaches the network.

Where you meet them: PostgreSQL listens on /var/run/postgresql/.s.PGSQL.5432 — psql without -h connects through it; Docker on /run/docker.sock; systemd and D-Bus keep dozens of sockets in /run. An application behind nginx often listens on a socket instead of a port: no port is taken, the application cannot be reached from outside, and file permissions decide access.

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

s as the first letter is the "socket" type. The size is always 0: no data is stored in the file.

Permissions: who can connect

To connect, a client needs write permission on the socket file and search permission (x) on every directory in the path. Read permission is not needed.

The server creates the file, and the mode comes from its umask. A root process with umask 022 creates srwxr-xr-x root root — only root can connect. nginx connects as the www-data user:

Socket permissions Can www-data connect?
srwxr-xr-x root root no: others have no w
srw-rw---- root www-data yes: the group has w
srwxrwxrwx root root yes, and so can any user

Mode 777 opens the socket to every process on the machine. Grant access through a group the client belongs to, with mode 660 or 770.

Lifetime of a socket file

The server creates the file when it starts listening and should delete it on exit. A crashed or killed process leaves the file behind: the path exists but nobody listens. A client then gets Connection refused, and a new server start gets Address already in use until the old file is removed.

/run lives in memory and is empty after a reboot. systemd creates the directory for a service's socket: the line RuntimeDirectory=app in the unit makes /run/app appear when the service starts and vanish when it stops.

Recipes

4

Who listens on a socket

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 is a stream socket (like TCP), u_dgr a datagram one (like UDP). -p adds the process: users:(("python3",pid=1750,fd=3)); other users' processes show only with sudo. If the file exists but ss -xl does not list it, nobody listens on the socket.

Test a socket by hand

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 sends an HTTP request into the socket; the name in the URL only goes into the Host header. curl's error is misleading: with no permission and with no file alike it prints Failed to connect to localhost port 80 … Couldn't connect to server, although neither localhost nor port 80 is involved. nc -U states the reason: nc: /run/app/app.sock: Permission denied.

Give nginx access

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

This lasts until the application restarts: the socket — and with RuntimeDirectory the whole directory — is created anew with the old permissions. For good — in the application's settings (many can set the socket's mode and group) or in the unit of the service that creates the socket:

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

The socket gets the group www-data and mode srwxrwx---.

Another way is to add www-data to the socket's group: sudo usermod -aG app www-data. nginx worker processes get their groups when they start, so after usermod run sudo systemctl reload nginx — it starts new workers that already have the group.

The PostgreSQL socket

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

A directory in -h means a socket connection, the same as no -h at all. PostgreSQL checks such a connection against the local lines of pg_hba.conf; -h 127.0.0.1 is TCP and the host lines.

Troubleshooting

4

Permission denied on connect

nginx logs connect() to unix:/run/app/app.sock failed (13: Permission denied) while connecting to upstream and answers 502; nc -U says Permission denied. The client has no write permission on the file or no search permission on a directory in the path. Check ls -l of the file and namei -l of the path: the client (www-data for nginx) must be in a group with w and get through every directory.

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. There is no file: a typo in the client's path, the server is not running, or it creates the socket elsewhere. ss -xl shows where it really listens.

Connection refused although the file is there

The file is left over from a stopped process — ss -xl does not list it. Start the service; if it fails with Address already in use, remove the old file.

Address already in use

The server cannot create the socket: a file with that name already exists. Python says OSError: [Errno 98] Address already in use. Make sure the old process is gone (sudo ss -xlp) and remove the file — or have the service remove it before it starts.

Danger zone

1

chmod 777 on a socket

A socket writable by everyone takes commands from any user on the machine. For /run/docker.sock that is root-level access: whoever writes to it starts containers with any privileges. Grant access through a group.

Terms

1
unix socket
A file that is a meeting point for processes on one machine (s as the first letter in ls -l): the server listens on it, the client connects by path. Connecting needs write permission on the file. Also appears in: curl, nginx, PostgreSQL, Docker and 1 more

See also

  • nginx — proxy_pass to a socket, 502 errors.
  • ss — ss -xl, listening sockets.
  • permissions — rwx, owner and group.
  • umask — the mode a socket file is created with.
  • namei — permissions along the whole path.
  • postgresql — the local socket and peer login.
  • docker — docker.sock and the docker group.
  • systemd — RuntimeDirectory, Group, UMask in a unit.
Loading…