DIVED(1)
π
DIVED(1) β like, the dived manual page, bestie
okay so this is dived from the General Commands Manual section, and honestly? she's a whole vibe. sit down, grab a strawberry drink π, and let me tell you everything.
β¨ NAME β¨
dived β listens on an AF_UNIX socket for requests to start programs (the requests come from dive(1)) and more. yes, "and more." she's mysterious like that π
π SYNOPSIS π
dived socket_path [options] [ -- command line ]
dived @abstract_address [options] [ -- command line ]
dived -i [options] [ -- command line ]
dived -J [options] -- command line
dived -j [options] -- command line
π¦ DESCRIPTION π¦
So this program is a helper that starts other processes for you β either because some remote fam asked nicely, or because you told it to directly β and it lets you use all kinds of Linux features while doing it: capabilities, namespaces, chroot, the whole menu. π She's simple, she's lightweight, and she does not need any config files. Like, none. Zero. The goal is literally to be the Linux tool for starting processes in all sorts of ways β the same way socat(1) is the tool for using all sorts of sockets in all sorts of ways. iconic parallel, no cap.
In her primary mode of operation, dived listens on an AF_UNIX socket and just... waits for dive(1) to connect. π«Ά And when a client does connect, she:
- Obtains the connected client's
uid/gid; - Retrieves all the file descriptors from the client;
- Changes into the appropriate
uid/gid, sets up groups; - Retrieves
umask, environment variables, command line arguments, and the current directory; - Starts the requested program;
- Waits for the program to terminate and reports back the exit code.
The way this works means the remote user genuinely feels like they just started the program themselves β but plot twist π β the program was actually started remotely. That alone is highkey useful when you wanna start programs inside other Linux namespaces.
And with various options you can add or remove some of those steps, which unlocks extra uses like:
- Acting like a simple
sudo(8)(password authentication included, bestie π₯) - Acting like
chroot(8)(and securely letting users usechroot, too) - Acting like
unshare(1)(including for the"pid"namespace) - Acting like
capsh(8)(managing capabilities and lockbits)
π OPTIONS π
First thing first: the first command line argument must be the socket path (filesystem path or @abstract) or "-i" (--inetd) or "-J" (--just-execute) or "-j". periodt.
All the rest of the options each take their own separate element of argv β no short-option combining here, sorry babe π. An option's argument is the next argv element (so no "--long-option=argument", you gotta do "--long-option argument").
"--" stops option parsing and starts the "forced command-line arguments", which limits what can be executed with dived. That's the trick: you specify the beginning of the command line, and the remote user specifies the ending. chef's kiss π
In "-j"/"-J" mode the "--" is required. don't forget it, i'm begging π
-A,--no-argvβ don't let the client set [part of] the command line. Should be used together with"-- forced command line arguments".
example:
dived qqq -A -- /sbin/shutdown -s now
dive qqq this is ignored
-a,--authenticateβ start this program for authentication. The program is started using"system"after file descriptors are received from the client, but before everything else (root, current dir, environment) is received. Nonzero exit code => the client gets rejected. π
DIVE_* environment variables are also available to the program. The program is expected to ask for a password, check the user id, or log the event.
The program is started as the dived user, before any setuids.
example:
dived /var/run/givemeroot.dive -C 777 -P -a 'user=root /root/askpassword'
gives the connected user root access if they enter the correct password. slay π₯
The program can also be used to do some setup as root before dropping privileges:
dived /var/run/emptynetwithlo -C 777 -P -s net -a 'ifconfig lo up'
-B,--retain-capabilitiesβ remove all capabilities from the bounding set except the ones you specify.
example:
dived -J -B cap_net_raw -- /bin/ping 127.0.0.1
-b,--remove-capabilitiesβ remove the selected capabilities from the bounding set.
dived -J -b cap_net_raw -- /bin/ping 127.0.0.1
which gives you:
ping: icmp open socket: Operation not permitted
yeah. that's the vibe check failing π
-C,--chmodβchmodthe socket to this mode (like'0777').-c,--set-capabilitiesβ uselibcapto interpret the specified string as a capabilities set and apply it.
example:
cp /bin/ping /root/ping
setcap cap_net_raw+ei /root/ping
dived -J -c 'cap_net_raw+i' -u nobody -- /root/ping 127.0.0.1
-d,--detachβ detach from the console after opening the socket. bye bestie π-D,--children-daemonβ call"daemon"in forked children. This is useful primarily for the case wheredivedwas started from a console and didn't detach itself, so the started processes accidentally receive the server's controlling terminal instead of the client's one β which causes weird behaviour. π-e,--effective-userβ set the effective user ID to this user instead of theSO_PEERCRED-obtaineduid.
Note that other groups can be preserved in this mode. π«Ά
-E,--no-environmentβ don't let the client set any environment variables. The environment of the started programs will be the same as the current environment.
By default dived only rejects DIVE_* environment variables.
-F,--no-forkβ accept once, serve only one client. Useful for debugging, or for starting the requested process withpid=1in a PID namespace. π-g,--groupsβsetgidto this group instead of the client'sSO_PEERCRED-obtainedgid. Also doessetgroups(2)to the specified comma-separated list of groups. With both-uspecified to a numericuidand-gspecified to a list of numericgids,divedshould operate independently of/etc/passwdand/etc/groupfiles. fr fr, no cap.
example:
# dived -J -S -T -u 123213 -g man,9999,43 -- /usr/bin/id
uid=123213 gid=12(man) groups=12(man),43(utmp),9999
-h,--chdirβ set this directory as the current one. If both--chdirand--chrootare specified, we remember the specified directory before thechroot, butchdirto it after thechroot. the way that works is honestly so clever πΈ
example:
dived -J -S -T -R . -h / -- /bin/bash
this swaps the current and root directories and executes /bin/bash. iconic.
complicated example:
/usr/bin/dived -J -S -T -R /lib -h / -- /ld-linux.so.2 --library-path /i386-linux-gnu/ ./usr/bin/dived -J -S -T -R . -h ../.. -- /bin/bash
this escapes the chroot jail and re-enters it, leaving the "outer" root as the current directory, without executing any programs from the "outer" system. "i386-linux-gnu", "ld-linux.so.2" and "/usr/bin/dived" may require adjustments. π₯ (main character energy, honestly.)
-H,--no-chdirβ don't let the client set the current directory.-i,--inetdβ don't bind the socket at all, just usestdin(fd = 0) as the accepted client's socket.
example /etc/inetd.conf configuration line:
/var/run/qqq.dive stream unix nowait qqq /usr/bin/dived dived -i
this allows anybody who can access /var/run/qqq.dive to run commands as user qqq. π
-j,--just-execute2β alias of-J -S -T -P. that's it, that's the whole flag. queen of delegation π-J,--just-executeβ don't use the socket at all (so: don't receive file descriptors,argv, environment), just start (execve) the program right away. β‘-l,--rlimitβ set resource limits usingsetrlimit(2).
The argument should be a comma-separated list of resource=hard_limit:soft_limit. The soft limit may be omitted.
"dived --help" should show the list of recognized resources. You can also specify numeric resources.
Limit values are typically in bytes or in seconds. π
example:
dived -J --rlimit cpu=3 -- /bin/cat /dev/urandom > /dev/null
-L,--lock-securebitsβ set and lockSECBIT_NO_SETUID_FIXUPandSECBIT_NOROOT.
This makes the root user (uid=0) non-special for the kernel. To be used in conjunction with capabilities (the -B and -c options). π
-m,--ambient-capabilitiesβ make the specified permitted and inheritable capabilities ambient, allowing them to be preserved acrossexecve.
Minimum Linux kernel version is 4.3. β
example:
USER=vi HOME=/home/vi dived -J -S -T -c CAP_NET_BIND_SERVICE+ip -m CAP_NET_BIND_SERVICE -u vi -- bash
-M,--no-umaskβ don't let the client setumask.-n,--signalsβ transfer all signals fromdive.
By default dived tells the PID of the launched process to dive, and tries to deliver signals to the started process by itself (which should be OK unless we're overriding the user with -u, -e or -P).
With the -n option, dived accepts signals from the client and helps deliver them to the started program. This way an unprivileged user can be allowed to send signals to dived-started programs. π«Ά
--signals-pgidβ transfer all signals fromdiveto the process group.
Like the -n option, but it sends the signal to the entire process group instead of just one PID. Useful for allowing Ctrl+C interrupting behaviour to travel through dive/dived. π (the way that's a real quality-of-life fix)
-N,--setnsβ open this file andsetns(2)it.
Such files can be found in /proc/<pid>/ns/<something> or /var/run/netns/.
You can specify this option up to 8 times to "dive" into multiple namespaces. π
dived opens the namespace file each time it needs to do setns. So a namespace will not be active only because dived is referencing it. important!! β¨
-O,--no-fdsβ don't let the client set file descriptors.-p,--pidfileβ save the PID to this file. Can be specified multiple times. Can also be used to adddived-spawned processes to a control group (cgroup)tasksfile. π-P,--no-setuidβ don't mess with user/group/capabilities things at all, just start the program.
The -a option will still work like expected, though.
-R,--chrootβchrootto this directory. Note that the current directory stays on the unchrooted filesystem; use the-Woption to prevent that.--chrootand--chdircan be specified at the same time and should not interfere with each other. If a relative directory is specified as the argument, it is taken before--chdiris applied.
pidfile is saved unchrooted. π
-r,--client-chrootβ allow arbitrarychrootfrom the client.
By default dive always sends the intended root directory descriptor, but dived ignores it. With this option we actually chroot to wherever the client wants. π
Use -X or -B '' options to disable starting any setuid-bit things after such a chroot. like, seriously. that's the safety rail, bestie.
-s,--unshareβ unshare the specified namespaces. Known namespaces:ipc,net,fs,pid,uts,user,cgroup. π¦-S,--no-setsidβ nosetsid.
Don't do:
setpgid(0, getppid());
setsid();
β¦and that's the whole setsid situation, bestie β chef's kiss π Moving on to the rest of the flags, because we are not done slaying β¨
-t,--write-contentβ after the namespaces are set up, but before dropping privileges, write the content you specified into a file. You can pass this one more than once (yes, really β stack 'em, queen π).
Example:
dived -J -S -T -P -s user -t /proc/self/uid_map "0 1000 1" -t
/proc/self/setgroups deny -t /proc/self/gid_map '0 1000 1' --
/bin/bash
-tt,--setup-uidgidmapβ literally just an alias of this whole vibe:
-t /proc/self/uid_map "0 `id -u` 1" -t /proc/self/setgroups deny -t /proc/self/gid_map "0 `id -g` 1"
Takes no arguments at all, zero, nada, she's self-sufficient π
Example:
dived -j -s user -tt -- /bin/bash
-T,--no-cscttyβ don't do this thing:
ioctl (terminal_fd_received_from_client, TIOCSCTTY, 1);
That's it. That's the flag π¦
-U,--chownβchownthe socket to this user:group. Both the user and the group must be specified, no half-sending it β and ngl they can totally be numeric πΈ-u,--userβsetuidto this user instead of the uid we got from the client'sSO_PEERCRED. Unless--groupis also specified, groups get initialized withinitgroups(3)π«Ά-V,--pivot-rootβpivot_rootto the specified directory, and the old root gets stashed in the directory you give as the second argument.
Example:
TODO
(yes, bestie, the docs actually just say TODO π iconic of them honestly)
-W,--root-to-currentβ set the server's root directory as the current directory (this implies-H; it's lowkey a lifesaver with-r). It helps you inspect the container's filesystem using the host's own utilities, if that filesystem isn't directly visible.
Example:
dived /var/run/some_socket_on_shared_fs -U 0:0 -C 700 -W -r
dive /mnt/container/var/run/some_socket_on_shared_fs bash
β¦so you get /mnt/container/ as your current directory, but the host's / as root β and the other filesystems mounted in the container are visible π₯
-w,--no-waitβ don't fork and wait for the exit code. It just sets everything up andexecves the program, no forking and no waiting around to report back to the client when the program finishes. She's out the door, periodt π¨-X,--no-new-privsβ setPR_SET_NO_NEW_PRIVS, which denies elevating privileges using the setuid-bit or filesystem capabilities. Requires a new enough Linux kernel β
πΏ ENVIRONMENT πΏ
So here's the tea: dived itself does not use any environment variables for configuration. But for the programs it's starting, it sets the following ones π
DIVE_UIDβ set to the user id of the client.DIVE_GIDβ set to the group id of the client.DIVE_PIDβ set to the PID of the program that connected to us.DIVE_USERβ set to the username of the connected client (if it can be resolved from the uid).
Heads up bestie: any DIVE_* environment variables the client already had are discarded. Gone. Not invited to the party π
π¬ EXAMPLES π¬
dived /var/run/socket.dive -C 777 -d -p /var/run/socket.pid
Run dived in a way that just lets users start programs as similarly as possible to how they'd start them directly (without dive/dived). Detach it, save the pidfile, and chmod the /var/run/socket.dive to 777 β¨
dived /var/run/socket.dive -U 0:chrooters -r -X
dived /var/run/socket.dive -U 0:chrooters -r -B ''
Let users in the group "chrooters" chroot into an arbitrary directory securely β turning off any privilege elevation using the suid-bit or filesystem capabilities. Secure queen behaviour π
dived @without_network -C 777 --unshare net
Let anybody run their programs without network access, i.e. inside a separate, unconfigured network namespace π¦
dived -J -T -S -P -L -- /bin/bash -i
Open a shell where uid=0 has no special privileges at all (according to the Linux kernel). Main character energy, zero privilege energy π
dived /var/run/container_admin.dive -T --unshare pid,fs,net,uts,ipc -d
dive /var/run/container_admin.dive /bin/mount -t proc proc
/mnt/container/proc
dive /var/run/container_admin.dive /sbin/ifconfig lo up
dive /var/run/container_admin.dive dived /var/run/container_user.dive -d
-T -W
-B
CAP_CHOWN,CAP_DAC_OVERRIDE,CAP_DAC_READ_SEARCH,CAP_FOWNER,CAP_FSETID,CAP_IPC_OWNER,
CAP_KILL,CAP_NET_BIND_SERVICE,CAP_NET_RAW,CAP_SETGID,CAP_SETUID -R
/mnt/container
Start up and set up a sort of a container, then create a special restricted root login for it π
dived /var/run/alice4bob -u alice -U bob:0 -a 'exit $RANDOM'
Let user bob run commands as alice β but only when he's lucky enough. Fr fr, the dice decide π
See additional examples at http://vi.github.com/dive/ β go look, bestie, there's more π
β οΈ CAVEATS β οΈ
Some dived features (like -X, for example) require a recent enough Linux kernel. Other behaviour can vary a bit between different versions of the Linux kernel. So like, vibe check your kernel first π
When you use --unshare pid, dived can tell dive that its pid is 1. And dive (if run as root) can then accidentally kill -INT 1, which causes a system reboot. Yeah. That's a whole thing. Be careful π
Even though dived sets up groups using initgroups(3), it does not set all the user's PAM settings β you know, things like resource usage limits. So don't assume that part's handled π«Ά
You genuinely need to understand what is exactly happening to use dived securely (especially as root). For example:
dived @socket -P -- chroot /some/root su -l someuser
is not secure β because the user can set PATH and LD_whatever before we execute binaries. Not the cute kind of surprise π
π AUTHOR π
Vitaly "_Vi" Shukela β an absolute icon, we stan π
π§ AVAILABILITY π§
The program is intended to be used with Linux primarily π§
Source code is available at https://github.com/vi/dive β go star it, it's giving open source excellence π
And that's the whole page, bestie! This was DIVED(1), v1.2, dated 2013-03-12 β so she's vintage, she's retro, and she still slays πβ¨π
π¦ where this page comes from
- alpine 3.24: dived-doc 1.9.0-r1 Β· MIT
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms