-
Notifications
You must be signed in to change notification settings - Fork 60
You should not run as root #38
Comments
Some details: |
Some take aways on this topic:
Thoughts? |
That is only an issue for host-mount based volumes and is a known aspect everybody runs docker in production is aware of, when using host mounts. I would not focus on that "volume" aspect too much here - it's the same for all projects using Not sure how traefik needs /etc/passwd at all / ever, but rather work with right group access if needed at all. AFAIK Traefik does not need anything that is system-specific / distro specific, everything can be created just for Traefik with the right permissions for it. Did i miss something here?
A good way could be here, start with root, create the folders for traefik on the volume and then degrade to the Traefik user. AFAIR that is still secure, but i am not entirely remembering it right now, we would need to double check if dropping privileges this way is to be considered secure for the initial attack vector
Well i would say that's a very know thing also, using 8080/8443 for those LB kind of images. Surely when the default is changed, this needs a fat-warning in the release notes of the docker-image or even a Traefik release notice, which introduces the new image. In the end, the person just remaps the ports to 80/443 when mapping on the host, i rarely matters what the dest port.
Totally agree that we should just do that for the docker-image, not for the binary using parameters.
|
@EugenMayer Points taken. The goal of my comment was to underline some technical facts to have them written and shared, because not everyone is having them as principal concerns. Let's hear what the others members of the community would want to say about this topic. |
From awesome-traefik, I found this article: "How to run Træfik as a non-root user ? Part 1" https://medium.com/@zepouet/how-to-run-tr%C3%A6fik-as-non-privileged-user-4a824bc5cc0 Traefik could also instead drop privileges at startup? (Does it already? Nginx and Apache drop privileges after binding 80 and 443. edit: traefik/traefik#1434 ... https://github.com/tmiller/setuidgid/blob/master/main.go) if (getuid() == 0) {
/* process is running as root, drop privileges */
if (setgid(groupid) != 0)
fatal("setgid: Unable to drop group privileges: %s", strerror(errno));
if (setuid(userid) != 0)
fatal("setuid: Unable to drop user privileges: %S", strerror(errno));
} Though, "syscall: Setuid/Setgid doesn't apply to all threads on Linux" golang/go#1435 (comment) ... FWIW, "Docker integration: Exposing Docker socket to Traefik container is a serious security risk" traefik/traefik#4174 |
Compared to just running as non-root and updating the docs - and maybe the seclist -- to say 'You need to map the port now', setcap is less than optimal, because it doesn't limit access to other ports < 1024 (which shouldn't be mapped anyway, and nobody should be using source ports for any firewall rules):
But in terms of least privileges, setcap should be unnecessary if the app is running as non-root. Filesystem privileges can be set with an entrypoint script or in a traefik init routine (prior to dropping privileges). |
Having similar requirements for security reasons, we also investigate the non-root options. @westurner : Can you please clarify a bit more what breaks in your approach at #43 ? did you try the user: "${UID}:${GID}" option in compose (instead of creating your own image) |
I haven't yet tried specifying the UID/GID. That might be less to maintain; but it won't solve for the port remapping issue. (Nonroot cannot bind ports less than <1024 without CAP_NET_RAW, which is really unnecessary particularly for a frontend service). This solved; though I'm not sure if I've forgone any features (?) by creating the redirect with the port number specified instead of just referencing the other entrypoint by name: [entryPoints]
[entryPoints.http]
address = ":8080"
[entryPoints.http.redirect]
#entryPoint = "https"
regex = "^http://(.*):8080/(.*)"
replacement = "https://$1/$2"
[entryPoints.https]
address = ":8443"
[entryPoints.https.tls]
#[[entryPoints.https.tls.certificates]]
#certFile = "/certs/website.crt"
#keyFile = "/certs/website.key"
|
FWIW, Traefik runs perfectly fine as a user with these options in a systemd service file:
CAP_NET_BIND_SERVICE allows it to bind to 80 and 443. I basically run it with almost all options enabled in here: https://github.com/containous/traefik/blob/master/contrib/systemd/traefik.service, except that it does not run with |
In case traefik runs within a container (which is the whole point of the issue), this shouldn't be necessary anyway, right? |
That is known, but you have to use a port greater then 1024 in the container / image, which would change the current default 80/443 and that is the whole point of the discussion |
Now would be a good time to revisit this, since v2 that was just released is has backward incompatible changes requiring manual upgrade. |
Just FYI got this working with Caddy with Let's Encrypt. You can de-escalate your privileges from Set an You can see an example of this in action in the mysql and jenkins containers currently but I'll be submitting a patch to Caddy soon, if you'd like a reference. For this to work you also need to remember to set |
you should not run traefik as root in the docker image.
The text was updated successfully, but these errors were encountered: