v1.28.0 requires the NET_BIND_SERVICE capability #5188

Closed
opened 2026-03-07 20:16:10 -06:00 by GiteaMirror · 5 comments
Owner

Originally created by @spantaleev on GitHub (Mar 29, 2023).

I'm launching a Vaultwarden container like this:

docker run \
-it \
--rm \
--name=my-vaultwarden \
--log-driver=none \
--user=12345:12345 \
--cap-drop=ALL \
--read-only \
-e ROCKET_PORT=8080 \
--tmpfs=/tmp:rw,noexec,nosuid,size=128m \
--tmpfs=/data:rw,noexec,nosuid,size=128m \
--tmpfs=/cache:rw,noexec,nosuid,size=128m \
--tmpfs=/ephemeral:rw,noexec,nosuid,size=128m \
docker.io/vaultwarden/server:1.28.0-alpine

And it leads to an error like this:

/start.sh: exec: line 25: /vaultwarden: Operation not permitted

Adding --cap-add=NET_BIND_SERVICE \ after --cap-drop=ALL \ fixes the problem and lets the process proceed further.

When using 1.27.0 instead of 1.28.0, the NET_BIND_SERVICE capability was not required. This can be tried by changing the version in the original command above and not adding NET_BIND_SERVICE.

I've explicitly configured ROCKET_PORT to use 8080 in an effort to escape needing NET_BIND_SERVICE in this container.


This seems to be caused by https://github.com/dani-garcia/vaultwarden/pull/3170

By adding the NET_BIND_SERVICE to the executable, it can no longer be used without having this privilege, not matter which ports you will need later.

Building my own container image that removes the capabilities added to /vaultwarden fixes the problem:

FROM docker.io/vaultwarden/server:1.28.0-alpine

RUN apk add --no-cache libcap && setcap cap_net_bind_service=-ep /vaultwarden

Seems like #3170 is only usable for niche situations with old Docker versions and is causing trouble otherwise. I suppose it's better to revert it.

Originally created by @spantaleev on GitHub (Mar 29, 2023). I'm launching a Vaultwarden container like this: ```sh docker run \ -it \ --rm \ --name=my-vaultwarden \ --log-driver=none \ --user=12345:12345 \ --cap-drop=ALL \ --read-only \ -e ROCKET_PORT=8080 \ --tmpfs=/tmp:rw,noexec,nosuid,size=128m \ --tmpfs=/data:rw,noexec,nosuid,size=128m \ --tmpfs=/cache:rw,noexec,nosuid,size=128m \ --tmpfs=/ephemeral:rw,noexec,nosuid,size=128m \ docker.io/vaultwarden/server:1.28.0-alpine ``` And it leads to an error like this: > /start.sh: exec: line 25: /vaultwarden: Operation not permitted Adding `--cap-add=NET_BIND_SERVICE \` **after** `--cap-drop=ALL \` fixes the problem and lets the process proceed further. When using 1.27.0 instead of 1.28.0, the `NET_BIND_SERVICE` capability was not required. This can be tried by changing the version in the original command above and not adding `NET_BIND_SERVICE`. I've explicitly configured `ROCKET_PORT` to use `8080` in an effort to escape needing `NET_BIND_SERVICE` in this container. ------ This seems to be caused by https://github.com/dani-garcia/vaultwarden/pull/3170 By adding the `NET_BIND_SERVICE` to the executable, it can no longer be used without having this privilege, not matter which ports you will need later. Building my own container image that removes the capabilities added to `/vaultwarden` fixes the problem: ```Dockerfile FROM docker.io/vaultwarden/server:1.28.0-alpine RUN apk add --no-cache libcap && setcap cap_net_bind_service=-ep /vaultwarden ``` Seems like #3170 is only usable for niche situations with old Docker versions and is causing trouble otherwise. I suppose it's better to revert it.
Author
Owner

@jjlin commented on GitHub (Mar 29, 2023):

#3170 is intended to simplify running as a non-root user inside the container, particularly for less advanced users. While Docker 20.10.0 and above will automatically allow even non-root processes to bind to ports <1024, there are still users on older Docker versions, as well as users of other tools like Podman, which doesn't have this allowance AFAIK.

Is there a specific security concern with allowing NET_BIND_SERVICE in your use case? Arguably, the way you do things is also pretty niche.

@jjlin commented on GitHub (Mar 29, 2023): #3170 is intended to simplify running as a non-root user inside the container, particularly for less advanced users. While Docker 20.10.0 and above will automatically allow even non-root processes to bind to ports <1024, there are still users on older Docker versions, as well as users of other tools like Podman, which doesn't have this allowance AFAIK. Is there a specific security concern with allowing `NET_BIND_SERVICE` in your use case? Arguably, the way you do things is also pretty niche.
Author
Owner

@spantaleev commented on GitHub (Mar 29, 2023):

I don't mind running it with NET_BIND_SERVICE, but given that it doesn't bind to such ports, it seems unnecessary and surprising. It took me quite a while to figure out why I was getting Operation not permitted when launching the process.

It seems like this convenience for less advanced users comes with at a slight security cost for others and a surprising complexity for people trying to drop all privileges for the container.

I believe the defaults should be adjusted so that the container does not use privileged ports by default and no such capability shenanings are necessary. Exposing a port 80 is done by Docker itself when publishing the ports, so there's really no need to bind to port 80 inside the container and force the need for the NET_BIND_SERVICE capability.

@spantaleev commented on GitHub (Mar 29, 2023): I don't mind running it with `NET_BIND_SERVICE`, but given that it doesn't bind to such ports, it seems unnecessary and surprising. It took me quite a while to figure out why I was getting `Operation not permitted` when launching the process. It seems like this convenience for less advanced users comes with at a slight security cost for others and a surprising complexity for people trying to drop all privileges for the container. I believe the defaults should be adjusted so that the container does not use privileged ports by default and no such capability shenanings are necessary. Exposing a port `80` is done by Docker itself when publishing the ports, so there's really no need to bind to port `80` inside the container and force the need for the `NET_BIND_SERVICE` capability.
Author
Owner

@jjlin commented on GitHub (Mar 29, 2023):

Hindsight is 20/20 of course, but changing the default listen port in the Docker image at this point would likely break things for the vast majority of existing users.

@jjlin commented on GitHub (Mar 29, 2023): Hindsight is 20/20 of course, but changing the default listen port in the Docker image at this point would likely break things for the vast majority of existing users.
Author
Owner

@Omar007 commented on GitHub (Mar 29, 2023):

Tried updating and ran into this problem as well. Very unsure why this change to require a hard-coded capability at all times was made. Any user that has this running and configured their system properly has to already be in one of three categories; container configured with the capability added because it is running as non-root on a privileged port, configured to run as root on w/e port, or configured to run non-root on a non-privileged port. It wouldn't currently be running in the first place otherwise.
So who is this helping or supposed to help? It can really only affect new users who are now forced to configure their systems/containers in a way not within the realm of one of the three proper deployment configurations 😕 🤔

I can understand not wanting to change the default port and this shouldn't be needed but the current change does not seem like the proper action either.
This seems to be something that should probably just have been a documentation update instead of encouraging bad practices (enabling/requiring capabilities/privileges not actually needed).

@Omar007 commented on GitHub (Mar 29, 2023): Tried updating and ran into this problem as well. Very unsure why this change to require a hard-coded capability at all times was made. Any user that has this running and configured their system properly has to already be in one of three categories; container configured with the capability added because it is running as non-root on a privileged port, configured to run as root on w/e port, or configured to run non-root on a non-privileged port. It wouldn't currently be running in the first place otherwise. So who is this helping or supposed to help? It can really only affect new users who are now forced to configure their systems/containers in a way not within the realm of one of the three proper deployment configurations :confused: :thinking: I can understand not wanting to change the default port and this shouldn't be needed but the current change does not seem like the proper action either. This seems to be something that should probably just have been a documentation update instead of encouraging bad practices (enabling/requiring capabilities/privileges not actually needed).
Author
Owner

@jjlin commented on GitHub (Mar 29, 2023):

It's intended to help anyone who is using the default configuration (running as root on port 80) to transition more easily to running as non-root (still on the default port 80) simply by adding an additional --user option.

@jjlin commented on GitHub (Mar 29, 2023): It's intended to help anyone who is using the default configuration (running as root on port 80) to transition more easily to running as non-root (still on the default port 80) simply by adding an additional `--user` option.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/vaultwarden#5188