Give non root users permission to use one port

Posted on

A server stack is the collection of software that forms the operational infrastructure on a given machine. In a computing context, a stack is an ordered pile. A server stack is one type of solution stack — an ordered selection of software that makes it possible to complete a particular task. Like in this post about Give non root users permission to use one port was one problem in server stack that need for a solution. Below are some tips in manage your linux server when you find problem about linux, docker, , , .

I host a lab server where I am root (and a regular user).

The domain name is and I give each member a subdomain, for example for Bob and for user Anna. I think you get the deal. 🙂 The subdomains are reversed proxied using nginx to a specific port.

My question is, is there any way that I can give permission to non root users to start docker containers on their specific range of ports. For example Anna is given range 1300-1350 where port 1300 is bound to and the other ones are in reserve.

The system runs Debian 11 Bullseye and the latest Docker version.

First of all, only trusted users should be allowed to control your Docker daemon

The docker daemon runs as root by default on a Debian Bullseye installation. Adding a user to the docker group gives that user psuedo root access due to having control of the docker daemon having that amount of access. Every user in the docker group will have complete control of the host and others containers and can run a container that --publishes any port.

There are a few options to providing security to users docker access.

  1. Rootless docker
  2. sudo
  3. API

1. Rootless docker

A rootless docker setup would enable each user to run a docker deamon. For ports lower than 1024 it would need to abide by the unprivileged ports information bob provided as each user will “own” their own deamon. Docker also provides related guidance. This wouldn’t stop Anna from taking Bobs port.

2. sudo

The simplest method to allow users to run docker commands is to provide a root controlled script via sudo that is either static, or controls the user input for optional arguments:

docker run --detach --publish 1300:1300 anna/app-image
anna    ALL=(root) NOPASSWD: /usr/local/bin/start-anna-image

If you want users to be able to add their own options you need to be very careful about controlling their input as it’s vert easy to

3. Authorization plugin or API for Docker

As Docker doesn’t provide any authorization layer on the daemon you need to add something to control user access.

Docker provides an in built authorization plugin framework to enable this. Some examples are opa-docker-authz and casbin-authz-plugin

You could give the users access to a form of proxy API that provides the authentication and authorization over what is passed on to the Docker REST API. There are docker libraries for most programming languages. Kubernetes+RBAC is an example of an API that sits in front of the Docker daemon and controls access (just a very big/complex one that does a lot more).

AFAIK Linux only has the concept privileged ports versus unprivileged ports.

The Linux kernel tuning parameter net.ipv4.ip_unprivileged_port_start defines which ports are privileged. All ports between 0 and net.ipv4.ip_unprivileged_port_start are privileged.

Privileged ports can only used by processes either started by the root user or with root privileges or by processes that are assigned the capability CAP_NET_BIND_SERVICE with for example sudo setcap cap_net_bind_service=ep /path/bin/application

All other ports are unprivileged and can be used by any user, as longs the ports are not already in use.

I don’t know of any alternative method to allow specific users to use particular ports.

As long as the ports are unprivileged, non-root users can bind to any port (over 1024). They can start the containers with:

docker run --expose 1300-1350  <image-name>

It is first come first served. If two programs are trying to bind to the same port, only the first one to bind will succeed.

For privileged ports (less than 1024), you need either root or CAP_NET_BIND_SERVICE capability. See man capabilities for details.

The subdomains are reversed proxied using nginx to a specific port.

You can proxy the subdomains to Unix sockets.

    proxy_pass http://unix:/var/run/anna.sock:/;

Repeat as needed for each subdomain, and set the permissions on the Unix sockets so that only the users you want can listen there.

Also note that a user who can run Docker containers can mount /etc/passwd into them and gain root, so that has to be protected against separately.

Leave a Reply

Your email address will not be published. Required fields are marked *