Give non root users permission to use one port

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

The domain name is example.org and I give each member a subdomain, for example bob.example.org for Bob and anna.example.org 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 anna.example.org 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:

#!/bin/bash
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.


Just wanted to add another perspective...certainly more work! But interesting...

Consider running a container orchestrator, such as Kubernetes. Check out KIND (Kubernetes-in-Docker) for an interesting way to run a Kubernetes cluster on a single node with only Docker.

You could then, for example, do something like

  • create a namespace for each user, such as bob-ns and anna-ns.
  • create a service in each namespace, exposing the specified ports
  • provide each user a role that allows them to create pods(groupings of containers) in their namespace, thus allowing them to accept traffic from the given service in their namespace.

If you structure the roles right, the users could concievably be allowed to launch whatever containers they want in their namespace, but would not be permitted to modify the service which defines the ports exposed.

This is simplified for the sake of space, but the primitives that something like k8s provide are excellent for multi-tenant systems like this.