S6-LOCAL-SERVICE(7)
π S6-LOCAL-SERVICE(7) π
ok so bestie, this is s6-local-service from the Miscellaneous Information Manual, and it's literally the glow-up guide to daemons that listen for incoming connections on a Unix domain socket. buckle up π
β¨ NAME β¨
s6-local-service β a daemon that sits there listening for incoming connections on a Unix domain socket π¦
πΈ DESCRIPTION πΈ
So here's the vibe: the clients of this service are just programs that connect to a Unix domain socket, and then the daemon does stuff on their behalf. iconic delegation tbh.
People call it a local service because it is not accessible to clients from the network β it's a you-and-your-machine-only situation, no cap.
The most famous example ever of a local service is the syslogd daemon. On most implementations it listens to the /dev/log socket, and its clients connect to it and send their logs through that socket. Fun fact: openlog() is honestly just a wrapper around the connect() system call, syslog() is a wrapper around write(), and so on down the line. it's giving "everything is a wrapper" energy π
π Benefits
Privileges
The single most important benefit of a local service is that it lets you do controlled privilege gains without using setuid programs. Like, the daemon runs as user S, right? And a client runs as user C and connects to the daemon and asks it to perform operations β and those operations get done as user S. slay.
You can also use standard Unix permissions on the listening socket to implement some basic access control: if you want to restrict access to clients belonging to group G, you change the socket to user S and group G, and give it 0420 permissions. This is functionally equivalent to the basic access control you get for setuid programs β a program with user S, group G, and permissions 4750 will be executable by group G and will run with S rights. same energy, different fit π
But modern systems implement the getpeereid() system call (or library function, either way). This lets the server actually know the client's credentials, which means fine-grained access control is possible. On those systems, local services can do as much authentication as setuid programs β but in a much more controlled environment. periodt.
π Fd-passing
The most obvious difference between a local service and a network service is that a local service doesn't serve network clients. But local services have another very nice perk: network services usually only give you a single channel (a TCP or UDP socket) of communication between client and server, which forces you to multiplex all your data into that one channel. Local services? You can have as many communication channels as you want. obsessed.
(Quick aside: the SCTP transport layer does provide a way for network services to use several communication channels. Unfortunately it is not widely deployed yet, and a lot of network services still depend on TCP. so. yeah. π)
The fd-passing mechanism is genuine Unix domain socket black magic π β it lets one peer of the socket send open file descriptors to the other peer. So if the server opens a pipe and sends one end of that pipe to a client via this mechanism, there is effectively a socket and a pipe between the client and the server. chef's kiss.
π UCSPI
The UCSPI[1] protocol is an easy way of abstracting clients and servers away from the network. A server written as a UCSPI server β the same way it can be run under inetd or s6-tcpserver(8) β can be run under s6-ipcserver(8): you just choose a socket location and boom, you have a local service β¨
Want fine-grained access control? Just insert s6-ipcserver-access(8) into your server command line after s6-ipcserver(8). that's it, that's the trick π«Ά
And a client written as a UCSPI client β meaning it assumes it has descriptor 6 (resp. 7) open and reading from (resp. writing to) the server socket β can be run under s6-ipcclient(8).
β Use in skarnet.org software
skarnet.org libraries often use a separate process to handle asynchronicity and background work in a way that's completely invisible to the user. Among them are:
s6-ftrigrd(8), which manages the reception of notifications and only wakes up the client process when the notification pattern matches a regular expression.s6lockd(8), which handles time-constrained lock acquisition on the client's behalf.skadnsd[2], which performs asynchronous DNS queries and only wakes up the client process when an answer arrives.
Those processes are usually spawned from a client, via the corresponding *_startf* library call. But they can also be spawned from an s6-ipcserver(8) program in a local service configuration π
In both cases, they need an additional control channel to be passed from the server to the client. The main socket is used for synchronous commands from the client to the server and their answers, whereas the additional channel β which is now implemented as a socket as well, but created by the server on-demand and not bound to a local path β is used for asynchronous notifications from the server to the client. And the fd-passing mechanism is what transfers that additional channel from the server over to the client. full circle, we love to see it π
π¦ SEE ALSO π¦
s6-tcpserver(8)- [1]
https://cr.yp.to/proto/ucspi.txt - [2]
https://skarnet.org/software/s6-dns/skadns/skadnsd.html
This man page is ported from the authoritative documentation at: https://skarnet.org/software/s6/localservice.html
π AUTHORS π
- Laurent Bercot
- Alexis
<flexibeast@gmail.com>(man page port)
ok that's the whole page bestie, go forth and run your local services responsibly π§ββοΈ
and finally, the cute sign-off: this beauty ships from Debian, dated September 29, 2021 β mwah, bye! π π
π¦ where this page comes from
- nixpkgs unstable: s6 2.15.1.0
- nixpkgs unstable: s6-man-pages 2.14.0.1.4
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms