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

Run Dockerized server process as unprivileged user by default #79

Open
Ajedi32 opened this issue May 5, 2018 · 6 comments
Open

Run Dockerized server process as unprivileged user by default #79

Ajedi32 opened this issue May 5, 2018 · 6 comments

Comments

@Ajedi32
Copy link
Contributor

Ajedi32 commented May 5, 2018

Would be nice from a security perspective if the Dockerized version of acme-dns automatically started as an unprivileged user (instead of as root).

The container does provide some level of isolation from the host system already (though as I understand it that isolation isn't perfect, especially against root), but no sense in giving the public-facing server any more permissions than necessary.

@Ajedi32 Ajedi32 changed the title Run Docker process as unprivileged user Run Dockerized server process as unprivileged user May 5, 2018
@Ajedi32
Copy link
Contributor Author

Ajedi32 commented May 6, 2018

Actually, after reading up a bit more on how Docker works, I'm not sure this feature needs to be added to acme-dns itself. I'm able to get the process to run as an unprivileged user using a docker-compose.yml file similar to the following:

version: '2'
services:
  acmedns:
    image: joohoi/acme-dns:latest
    ports:
      - "443:1443"
      - "53:1053/udp"
      - "80:1080"
    user: 1000:1000
    volumes:
      - /containers/acme-dns/config:/etc/acme-dns:ro
      - /containers/acme-dns/data:/var/lib/acme-dns

Where '1000' is the user id of the user on the host that I want to run acme-dns as. Note also that I had to change the config file to ensure acme-dns doesn't try to bind to any privileged ports (though those ports are then remapped by Docker, as you can see in the config file above).

@Ajedi32 Ajedi32 closed this as completed May 6, 2018
@Ajedi32
Copy link
Contributor Author

Ajedi32 commented May 6, 2018

Oops, looks like there's a problem; the directory cache for ACME certs, api-certs, isn't configurable, and by default it's placed under /root, which doesn't have the exec permission bit set for "other". So even if I add /containers/acme-dns/api-certs:/root/api-certs as a volume, the server still can't find that directory.

@Ajedi32
Copy link
Contributor Author

Ajedi32 commented May 14, 2018

Now that #81 is merged, it's possible to run acme-dns as an unprivileged user with the above docker-compose.yml by setting acme_cache_dir = "/var/lib/acme-dns/api-certs" in the config file, and configuring acme-dns to bind to high-numbered (>1024) ports within the container.

That's enough to satisfy my use-case, but I'm going to leave this issue open as a request to run the container as an unprivileged user by default. I realize that's a bit tricky to do since user IDs within the Docker container don't necessarily match up with user IDs on the host system, so if you hard code a user ID in the Dockerfile that might result in the container process running as an essentially random user. That's certainly confusing behavior, but it's an arguably better solution than just always running as root, and you can reduce confusion by updating the docs to tell users to explicitly specify which user ID to run the container as.

@Ajedi32 Ajedi32 changed the title Run Dockerized server process as unprivileged user Run Dockerized server process as unprivileged user by default May 14, 2018
@joohoi
Copy link
Owner

joohoi commented May 14, 2018

Yeah, that sounds good. My Docker-fu runs short right about here though. If someone with strong knowledge of best practices in this area would like to help here, it would be more than welcome!

@tcely
Copy link

tcely commented Mar 1, 2019

For anyone else that needs a bit of help, here is my full Dockerfile for running unprivileged.

FROM joohoi/acme-dns AS release
  
FROM tcely/alpine-aports

EXPOSE 10053/tcp 10053/udp 10080/tcp 10443/tcp

ENTRYPOINT ["/usr/local/bin/acme-dns"]
COPY --from=release /root/acme-dns /usr/local/bin/acme-dns

RUN mkdir -p /etc/acme-dns /var/lib/acme-dns && chown -R postgres:postgres /var/lib/acme-dns

VOLUME ["/etc/acme-dns", "/var/lib/acme-dns"]

RUN apk --no-cache add ca-certificates

WORKDIR /var/lib/acme-dns
USER postgres:postgres

Here is the service entry from docker-compose.yml I'm using for this:

  acme:
    image: 'tcely/acme-dns'
    build:
      context: './build/acme-dns'
    restart: 'unless-stopped'
    ports:
      - '53:10053'
      - '53:10053/udp'
      - '80:10080'
      - '443:10443'
    volumes:
      - './data/acme-dns/etc:/etc/acme-dns:ro'
      - './data/acme-dns/lib:/var/lib/acme-dns'

The UID and GID for postgres are both 70 so when you create the data/acme-dns/lib directory you may need to change the owner and/or group.

Put your config.cfg file under data/acme-dns/etc and be sure it is readable.

Then just drop the Dockerfile in the build/acme-dns sub-directory before running docker-compose up -d --build and you should be ready to go.

@bitsofinfo
Copy link

did this ever go anywhere? does anyone have a published latest version out there that runs non-root?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants