How does this work internally? 
oniux works by immediately spawning a child process using the clone(2)
system call, which is isolated in its own network, mount, PID, and user namespace. This process then mounts its own copy of /proc
followed by UID and GID mappings to the respective UID and GID of the parent process.
Afterwards, it creates a temporary file with nameserver entries which will then be bind mounted onto /etc/resolv.conf
, so that applications running within will use a custom name resolver that supports resolving through Tor.
Next, the child process utilizes onionmasq to create a TUN interface named onion0
followed by some rtnetlink(7)
operations required to set up the interface, such as assigning IP addresses.
Then, the child process sends the file descriptor of the TUN interface over a Unix Domain socket to the parent process, who has been waiting for this message ever since executing the initial clone(2)
.
Once that is done, the child process drops all of its capabilities which were acquired as part of being the root process in the user namespace.
Finally, the command supplied by the user is executed using facilities provided by the Rust standard library.