S6-SUDOD(8)
π S6-SUDOD(8) β bestie, this is the server side of the sudo glow-up
okay so you found the s6-sudod page, which means you're doing big-kid privilege-dropping stuff and I'm SO proud of you. this is the System Manager's Manual entry, and we're gonna get through it together, no cap. π«Ά
β¨ NAME β¨
s6-sudod β receives command-line arguments, environment variables and standard descriptors from a peer s6-sudoc(8) program over a Unix socket, then forks another program
like, it's the receiving end. the server twin. the one that catches everything the client throws at it. π
πΈ SYNOPSIS πΈ
s6-sudod [-0] [-1] [-2] [-d] [-t timeout] [sargv...]
π¦ DESCRIPTION π¦
okay so picture this. s6-sudod gets 3 file descriptors via fd-passing over a Unix socket that must be open on its descriptors 0 and 1. (the descriptors it receives are gonna become the stdin, stdout and stderr of the server program, iykyk.) it expects an s6-sudoc(8) process to be the one sending them on the client side. π
it also receives a list of command-line arguments cargv..., and an environment clientenv. then s6-sudod forks and executes sargv... cargv.... β yes, the client command line gets appended to the server command line. π it waits for its child to exit, transmits its exit code to the peer s6-sudoc(8) process, and then it exits 0. slay.
now, the spicy part. if the -d option to s6-sudod has not been given, and s6-sudoc(8) is killed (or exits after timeoutrun milliseconds) while the server program is still running, s6-sudod will send a SIGTERM and a SIGCONT to its child, then exit 1. but β and this is important, bestie β sending a SIGTERM to the child does not guarantee that it will die. and if it keeps running, it might still read from the file that was s6-sudoc(8)'s stdin, or write to the files that were s6-sudoc(8)'s stdout or stderr. π« this is a potential security risk. administrators should audit their server programs to make sure this does not happen. like, actually. go audit them. π
more generally: anything using signals or terminals will not be handled transparently by the s6-sudoc(8) + s6-sudod mechanism. the whole thing was designed to let programs gain privileges in specific situations β short-lived, simple, noninteractive processes. it was not designed to emulate the full suid functionality and will not go out of its way to do so. periodt. π
administrators should also make sure that it's not a problem ifs6-sudod's child keeps running after thes6-sudoc(8) client exits, if they have given the-doption tos6-sudod. in particular, they should study what happens if another connection to the same service occurs while an instance is still running. π¨
sargv may be empty. in that case, the client is in complete control of the command line executed as serveruser. this setup is permitted by s6-sudod, but it is very dangerous, and extreme attention should be paid to the construction of the s6-ipcserver-access(8) rules. like, extreme extreme. π
π OPTIONS π
-0β do not inherit stdin froms6-sudoc(8). the child will be run with its stdin pointing to/dev/nullinstead. π³οΈ-1β do not inherit stdout froms6-sudoc(8). the child will be run with its stdout pointing to/dev/nullinstead. π³οΈ-2β do not inherit stderr froms6-sudoc(8). the child will be run with its stderr being a copy ofs6-sudod's stderr instead. (this is useful to still log the child's error messages without sending them to the client. iconic, honestly. π)-dβ Detach. the child will keep running until it naturally exits, even if the client disconnects. setting this option also enforces-0,-1and-2. bear in mind that this option relinquishes a lot of control over the child, and administrators should make sure it is appropriately short-lived. π«£-t timeoutβ ifs6-sudodhas not received all the needed data from the client aftertimeoutmilliseconds, it will exit without spawning a child. by default,timeoutis 0, meaning infinite. this mechanism exists to protect the server from malicious or buggy clients that would uselessly consume resources. thank u for your service,-t. π‘οΈ
π ENVIRONMENT π
s6-sudod transmits its own environment to its child, plus the environment sent by s6-sudoc(8), filtered in the following manner: for every variable sent by s6-sudoc(8), if the variable is present but empty in s6-sudod's environment, then its value is overridden by the value given by s6-sudoc(8). a variable that is already nonempty, or that doesn't exist, in s6-sudod's environment, will not be transmitted to the child. in other words:
- if there's no variable
Xins6-sudod's environment, the child will have no variableXdefined. π« - if there's a non-empty variable
Xins6-sudod's environment, the child will inherit that variable, with its value, froms6-sudod. π - if there's an empty variable
Xins6-sudod's environment, ands6-sudoc(8) transmits variableX, then the child will inherit that variable with the value froms6-sudoc(8). (ifs6-sudoc(8) does not transmitX, the variable will be present, but empty, in the child's environment.) β¨
π§ EXAMPLES π§
the typical use of s6-sudod is in a local service with an s6-ipcserver(8) process listening on a Unix socket, an s6-ipcserver-access(8) process performing client authentication and access control, and possibly an s6-envdir(8) process setting up the environment variables that will be accepted by s6-sudod. the following script, meant to be a run script in a service directory, will set up a privileged program:
#!/command/execlineb -P
fdmove -c 2 1
fdmove 1 3
s6-envuidgid serveruser
s6-ipcserver -U -1 -- serversocket
s6-ipcserver-access -v2 -l0 -i rules --
exec -c
s6-envdir env
s6-sudod
sargv
okay let's walk through it, because it's giving chef's kiss layered:
execlineb(1) executes the script. πfdmove(1) makes sure the script's error messages are sent to the service's logger. πfdmove(1) redirects the script's stdout to file descriptor3. this is useful if the service directory contains anotification-fdfile containing3, so the daemon can perform readiness notification (cf.s6-notifywhenup(7)) by writing a newline to its stdout. (the-1option tos6-ipcserver(8) tells it to do this.) πs6-envuidgid(8) sets theUID,GIDandGIDLISTenvironment variables fors6-ipcserver(8) to interpret. π€s6-ipcserver(8) binds toserversocket, drops its privileges to those ofserveruser, and announces its readiness. then, for every client connecting toserversocket:s6-ipcserver-access(8) checks the client's credentials according to the rules in directoryrules. πexec -c(cf.exec(1)) clears the environment. π§Ήs6-envdir(8) sets environment variables according to the directoryenv. you can make sure that a variableVARwill be present but empty by performingecho > env/VAR. (a single newline is interpreted bys6-envdir(8) as an empty variable; whereas ifenv/VARis totally empty, then theVARvariable will be removed from the environment.) π±s6-sudodreads a command linecargv, a client environment and file descriptors over the socket. π₯s6-sudodspawnssargv cargv. π
(actually, s6-ipcserver(8) does not do this itself: it executes into other programs that each do one of the tasks. but for our example, it does not matter.) π
this means that user clientuser running s6-sudo serversocket cargv will be able, if authorized by the configuration in rules, to run sargv cargv as user serveruser, with stdin, stdout, stderr and the environment variables properly listed in env transmitted to sargv. it's giving β¨ privilege escalation but make it safe β¨. π
π SEE ALSO π
exec(1), execlineb(1), fdmove(1), s6-sudo(8), s6-sudoc(8)
this man page is ported from the authoritative documentation at: https://skarnet.org/software/s6/s6-sudod.html π¦
π AUTHORS π
Laurent Bercot Alexis <flexibeast@gmail.com> (man page port)
okay bestie, that's the whole page!! π big credit to the Debian crew β this one's from September 29, 2021 and it's literally the S6-SUDOD(8) page, now with 100% more sparkle. go forth and -t timeout responsibly, mwah ππ
π«Ά
π¦ 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