Socketbox

Socketbox is a modern replacement for the classic "inetd" or "xinetd" daemon. Similar to inetd, Socketbox is responsible for managing listening sockets and whenever an incoming connection appears on any of the listening sockets, it spawns a new connection handling process of choice. However, unlike inetd, which spawns a totally new process for each connection, Socketbox uses SCM_RIGHTS to pass the accepting (connection) socket over to the existing process on the system.

For many server daemons, no changes to the code is required, thanks to the LD_PRELOAD library included with socketbox. Otherwise, if the server daemon has an "inetd" mode, then it can work with the socketbox-inetd compatibility layer. If all else fails, there is a socket relay included too.

Socketbox is most useful for use in conjunction with server daemons running in Linux containers and Docker (including ctrtool), where the network namespace of the server daemon is different from that where the listening socket is located. However, unlike e.g. docker-proxy, the network namespace of the server daemon does not need to be related (e.g. connected through a veth device) to the namespace of the listening socket in any way. This means that it will work even if the network namespace of the server is completely isolated (e.g. a freshly created network namespace created with ip netns add, unshare -n, or ctrtool launcher -n), or if the default routing policy of the network namespace is completely unrelated to that of the listening socket's namespace (e.g. in scenarios like this one)

Theory of operation

Socketbox relies on a few main premises for it to work properly. They are:

  • Most container runtimes allow the user to share a volume between the host and the container, or between two containers (e.g. -v /host_dir:/container_dir in Docker). If there is a Unix domain socket from one container or the host shared in that volume, then another container or the host in a different network namespace can access that Unix domain socket, as if it were still "active".
  • The SCM_RIGHTS ancillary message of Unix domain sockets can be used to pass file descriptors (e.g. sockets) from one process to another. Since containers share a single Linux kernel, the SCM_RIGHTS mechanism also works across different containers.
  • All TCP server daemons use a standard "bind-listen-accept" sequence to set up the listening socket. We can use an LD_PRELOAD library to intercept those socket calls to be able to receive incoming "connections" (as if by accept()), using SCM_RIGHTS to pass the connection sockets to the server daemon whenever there is an incoming connection in the listener's network namespace.