Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Container requires root under the rootless podman/docker container #47

Closed
kernbug opened this issue Feb 7, 2024 · 5 comments
Closed
Assignees
Labels
bug Something isn't working

Comments

@kernbug
Copy link

kernbug commented Feb 7, 2024

Describe the bug
Container is not able to start with podman/docker --user option defined.

To Reproduce
Steps to reproduce the behaviour:

  1. Assume starting simple example under the simple user (let's name it userx) using podman, just freshly provisioned Rocky Linux and (dnf install podman):
podman pod create --publish 59822:59822/udp --name wg-unbound-pod

podman run \
  --name madnuttah-unbound \
  -- user $(id -u userx)
  -d \
  --pod unbound-pod \
  --restart=unless-stopped \
  --volume /opt/userx/unbound/iana.d/:/usr/local/unbound/iana.d/:rw,Z \
  --volume /opt/userx/unbound/log.d/unbound.log:/usr/local/unbound/log.d/unbound.log:rw,Z \
madnuttah/unbound:latest
  1. Container fails:

chroot procedure doesn't have permissions (and this is logically correct) and tries to use some custom id 1000
port 5335 is defined by default, but internally it tries to listen on 127.0.0.1:53 and fails to bind something under the privileged port numbers
since user 1000 is hardcoded - podman mapping of the file permissions doesn't work and you need to give permissions for this files separately, this can intersect/cross with already existing users in the system allocated for other needs and they will have permissions
you can install anything inside a container (good only for troubleshooting/testing)

Expected behavior

  1. Default configuration should not try to bind on :53 even for localhost, this will require additional CAP flag and will not be used by default;
  2. Unbound should start with minimal permissions under user defined during run, not some hardcoded one, chroot gives a tradeoff do have root inside container;

Please complete the following information:

  • Device: VPS/1 core/2GB RAM
  • OS: Rocky Linux
  • Architecture: x86_64
  • Version 9.3

Additional context
Thank you for images, but it will be much appreciated if you can make them secure without root inside container to create "secure chroot", since such kind of an application doesn't requires escalated privileges (like wireguard for some scenario) to handle it's job.

@kernbug kernbug added the bug Something isn't working label Feb 7, 2024
@madnuttah
Copy link
Owner

Hi and thanks for contacting me.

Default configuration should not try to bind on :53 even for localhost, this will require additional CAP flag and will not be used by default

Port 53 is used for the healthcheck internally, you can disable it in the unbound.conf and the yaml file respectively. I never needed to enable a CAP for my image and no one should.

Unbound should start with minimal permissions under user defined during run, not some hardcoded one, chroot gives a tradeoff do have root inside container

I'm sorry if I don't get your point but unbound runs with user _unbound (uid/gid 1000) with minimal permissions:

  PID  PPID USER     STAT   VSZ %VSZ CPU %CPU COMMAND
    1     0 _unbound S     183m   2%   0   0% {unbound} /usr/local/unbound/unbou
16506     0 0        S     1696   0%   3   0% ash
16751 16506 0        R     1624   0%   1   0% top

The unbound.sh startup script will be executed by root and the root user is still needed by the container OS.

You are right, the id's could interfere but how to set permissions if the ids are unknown?

What happens when you run the container with uid 1000?

Since this container was never tested nor it was designed for use with podman, what would it need to make it work?

Thanks

@kernbug
Copy link
Author

kernbug commented Feb 7, 2024

Thank you for a reply.

#Port 53 is used for the healthcheck internally

Why not to use 5335? You can try to start Docker image with --user definition and it will fail to bind this port.

#I'm sorry if I don't get your point but unbound runs with user _unbound (uid/gid 1000) with minimal permissions:

Sorry, was not clear. Dockerfile you have doesn't define USER directive: https://docs.docker.com/engine/reference/builder/, so inside a container you have root privileges.

#The unbound.sh startup script will be executed by root and the root user is still needed by the container OS.
Container running with a user privileges will have more security, than container running with root and using chroot for application.

#Since this container was never tested nor it was designed for use with podman, what would it need to make it work?
Docker/Podman will behave the same, if you run under --user 1000 option, but I will create change list since have more time, so you can review them.

@madnuttah
Copy link
Owner

Will be fixed in the next update. Some permissions were missing. I'll may release a distroless version based on my Alpine image.

@madnuttah
Copy link
Owner

Would you mind testing this?

docker pull madnuttah/unbound-dev:latest

@madnuttah madnuttah reopened this Feb 12, 2024
madnuttah added a commit that referenced this issue Feb 13, 2024
Chroot never functioned properly. Many thanks to @kernbug for reporting this issue. Sorry for this lack of knowledge, I thought it's sufficient to set an entry in the unbound.conf. Everyday we learn, don't we?
Libevent will not be compiled by myself anymore
The image is distroless now, so no need for chroot anymore, see issue #47
I've moved some examples around, some links may be broken and will be fixed asap
@madnuttah
Copy link
Owner

The container runs distroless in the next update, thanks again for reporting this issue!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants