Search code examples
dockersetuid

Run docker container via a setuid binary


I am trying to set up a container on my (debian stretch) server, and to lock it down as much as possible.

The container my-container only needs to be started, it then does some processing and returns (the whole thing takes about one second).

I can easily do it as root with docker start -a my-container.

My problem is that this processing needs to be triggered with a php script. Instead of giving www-data the right to start docker containers, I created a dedicated user, with a small setuid binary that executes the docker command.

Now, executing the setuid binary from another user doesn't work and returns:

FATA[0000] Get http:///var/run/docker.sock/v1.18/containers/my-container/json: dial unix /var/run/docker.sock: permission denied. Are you trying to connect to a TLS-enabled daemon without TLS?

While executing the binary from the special user account works.

I use 4510 permissions:

-r-s--x--- 1 docker-proxy-launcher another-user 8448 sept. 23 23:43 /home/docker-proxy-launcher/docker-prestage

The binary is a very simple program, derived from the execve man page:

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
char *newenviron[] = { NULL };
char * newargv[] = {NULL, "start", "-a", "my-container", NULL};
char * exec="/usr/bin/docker";

newargv[0] = exec;

execve(exec, newargv, newenviron);
perror("execve"); /* execve() only returns on error */
exit(EXIT_FAILURE);
}

I really don't get what is preventing me from launching the docker process with this setuid binary.


Solution

  • I actually figured this out myself. The setuid bit just changes the user id, not the group id of the process. As a result, the executable has the rights of the new user, but not the ones from the groups it belongs to.

    As a workaround, I changed the binary to be owned by root:docker (as belonging to the docker group gives the permission to write on the docker socket):

    srw-rw---- 1 root docker 0 sept. 23 23:09 /var/run/docker.sock
    

    I also changed the permissions to be 2111 (setgid, executable by anyone as it is not a security issue on my system; if it was, I think I could have used ACLs):

    ---x--s--x 1 root docker 8448 sept. 24 10:58 /home/docker-proxy-launcher/docker-prestage
    

    It now all works properly.