News for hackers. Stuff that matters.
Re:Escaping Docker container using waitid() – CVE-2017-5123 by oblio on Friday December 29, 2017 @01:49PM (#16031112)
As a somewhat of a container noob, could you expand on "per-container usernamespaces"?
Re:Escaping Docker container using waitid() – CVE-2017-5123 by hacknat on Friday December 29, 2017 @01:59PM (#16031173)
Sure. User namespace-ing is a feature of container security that allows you to grant a process root access to a filesystem that itself is not root. To the running process it appears that it is or can run as root, but on the host it actually isn’t root, but some uid:gid offset. Here’s an article explaining more: http://man7.org/linux/man-pages/man7/user_namespaces.7.html

The gist is that a container is further sandboxed by the kernel that is agnostic of the higher level security precautions. It’s not perfect by itself, but used in conjunction with other features like AppArmor or SELinux and SecComp it can make a container virtually sandboxed.

Re:Escaping Docker container using waitid() – CVE-2017-5123 by baq on Friday December 29, 2017 @01:52PM (#16031133)
Follow-up question: And why docker doesn't do that by default?
Re:Escaping Docker container using waitid() – CVE-2017-5123 by hacknat on Friday December 29, 2017 @02:03PM (#16031205)
Because the Docker project doesn’t make money off of security. It is actually quite infuriating, because they have become the de facto container image standard. Most of their security has actually come from Twistlock (I am not a Twistlock employee, FYI). My recommendation to most Admins or Devs that are serious about container security is to let your developers use docker, but run your images with CRI-O on your servers: http://cri-o.io/
Re:Escaping Docker container using waitid() – CVE-2017-5123 by raesene9 on Friday December 29, 2017 @03:19PM (#16031722)
The docker project has done quite a bit of work on container security, so I'm not sure it's entirely fair to say that them not enabling user namespace by default is for that reason.

For example the work that was done on their seccomp filtering and apparmor profiles.

My guess would be that it's as User namespacing can introduce some issues (e.g. where mounting host filesystems), that they've decided the trade-offs aren't worth it.

Also looking at the CRI-O trello (https://trello.com/c/Ak2yMcpf/714-epic-cri-o-support-for-use...) it seems like user namespaces isn't even an option there yet?

Re:Escaping Docker container using waitid() – CVE-2017-5123 by eikenberry on Friday December 29, 2017 @03:18PM (#16031715)
Viewing docker containers as anything more than a bundling and deployment system is a mistake. While they might help with security they will never be completely secure and you should architect your deployments with that in mind.

Unless you are a giant enterprise shop with the resources to staff a decent sized K8s team, you should use the hosted solutions.

Re:Escaping Docker container using waitid() – CVE-2017-5123 by cpuguy83 on Friday December 29, 2017 @03:13PM (#16031689)
There are trade-offs to using userns and many ppl don't like the current set of trade-offs. In addition changing a default like this is a breaking change. Admins can enable userns by default in a daemon, but making it a hard-coded default is much more difficult.

It's not just a matter of enabling user ns. There is no support at the vfs layer for uid/gid mapping. This means in order to use it, images must be chowned with the remapped ID's. Per-container mappings are not supported for this reason (it would require copying and chowning the entire image for each container mapping).

Do you care to qualify your statement about CRI-O?

Re:Escaping Docker container using waitid() – CVE-2017-5123 by ecnahc515 on Friday December 29, 2017 @05:47PM (#16032552)
I recall seeing some patches submitted to make it possible to pass an uid/gid offset to the mount syscall at one point when people were implementing usernamespaces for container runtimes like docker. So is this fixable without having to make every file system implement this feature, or is there something else holding back better support for doing uid shifting for use with user namespaces?
Re:Escaping Docker container using waitid() – CVE-2017-5123 by cpuguy83 on Friday December 29, 2017 @05:52PM (#16032566)
That has not been accepted into the kernel. It's called "shiftfs", which basically let's you perform the uid/gid shift on mount.
Re:Escaping Docker container using waitid() – CVE-2017-5123 by zenlikethat on Friday December 29, 2017 @05:59PM (#16032600)
Nah, Docker has taken lots of strides in the right direction for security over the years, Twistlock or not, albeit with a few weird dangling remainders. They'd love to turn user ns on by default but it'd break lots of existing stuff. Many more users would be mad about having that on by default than leaving it off.

Disclaimer: I worked at Docker for 3 years.

Re:Escaping Docker container using waitid() – CVE-2017-5123 by nvarsj on Friday December 29, 2017 @02:10PM (#16031267)
CRI-O is bleeding edge. I'm not sure it's ready for production usage. But it looks very promising. The sooner we can all dump docker in kubernetes the better.
Re:Escaping Docker container using waitid() – CVE-2017-5123 by fpoling on Friday December 29, 2017 @04:23PM (#16032080)
Docker excels in image building especially now with multi-image Dockefile support. It seems all those alternatives to the Docker just gave up on providing anything on their own. The documentation typically starts "lets pull a docker image".

On the other hand the container runtime is straightforward. I recently discovered that one can run a docker image with a bash script and the unshare command and get a very tight security setup. That explains proliferation of various alternatives to Docker to run its images.

Re:Escaping Docker container using waitid() – CVE-2017-5123 by andbberger on Friday December 29, 2017 @03:52PM (#16031903)
Maybe because it breaks things?

I just enabled user namespaces after reading this post. Broke Jenkins and there doesn't appear to be an easy solution. I mount the docker socket in the Jenkins container, which is not an option with user namespaces as the user Jenkins now runs as does not have permission to access the socket.

It seems to be possible to provide this user access to the socket through a socket proxy, but since all containers use the same user this seems to defeat the purpose of using namespaces in the first place.

Cherry on top: although `docker run` supports running containers with custom userns settings, docker swarm, which I use to run Jenkins, does not.

So as far as I can tell my only options are:

1. Go back to not using user namespaces 2. Make the docker daemon on the host available over HTTP, which is really something I was trying to avoid...

Anyone have a more elegant solution?

Re:Escaping Docker container using waitid() – CVE-2017-5123 by zenlikethat on Friday December 29, 2017 @05:42PM (#16032530)
Mm, if you're bind mounting in the Docker socket, enabling user namespaces won't help much. You just have to deal with the fact that you have a privileged container (Docker API access == root, at least unless you're using authz). It'd be nice if we could see more RBAC around Docker API so you could do things like "grant only permission to run this one container".
Re:Escaping Docker container using waitid() – CVE-2017-5123 by andbberger on Friday December 29, 2017 @05:58PM (#16032597)
Totally. But the vast majority of containers I use do not get a bind mount to the Docker socket... for which user namespaces would be a very nice feature.
Re:Escaping Docker container using waitid() – CVE-2017-5123 by zenlikethat on Friday December 29, 2017 @06:02PM (#16032616)
Yeah, definitely turn it on where possible, just important to realize that it's not a panacea (some people really hyped it up to be before the feature was released and criticized Docker for not having it at all). As always, gotta try and find the right sweet spot between convenience and attack surface.
Re:Escaping Docker container using waitid() – CVE-2017-5123 by nassyweazy on Saturday December 30, 2017 @09:53AM (#16035456)
disclaimer: I'm a member of Docker Security team

We're working on a solution that would please most people for docker containers and services called the Docker Entitlements: https://github.com/moby/libentitlement

These Entitlements are high-level privileges for containers and services that could be baked in images, same way as macOS/iOS apps. These permissions would allow to create custom {seccomp+capabilities+namespaces+apparmor+...} profiles (effectively security profiles) for a better granularity in app sandbox configuration by app developers and ops.

The current POC has `docker run`, `docker service create` and even build mechanism working. The integration is actively being worked on and PRs are being prepared.

The issue you mentioned is already opened here: https://github.com/moby/libentitlement/issues/44

Feel free to have a look at it and open issues/participate or reach out through Github as I'm the lead and would love to discuss use-cases :)

Re:Escaping Docker container using waitid() – CVE-2017-5123 by LaGrange on Friday December 29, 2017 @05:23PM (#16032437)
As far as I remember things, because it breaks overlay filesystems, which are a major space saver in Docker world. Something might have changed, but last time I checked, you couldn't "offset" uids/gids on a filesystem overlay, so every layer of the container would have to be copied and chowned (slowly).

This would obviously only work for minimal containers (i.e. ones that don't contain a distribution), but software has to be pretty much built for such a case (e.g. statically linked, no dependencies on common tooling — popular with Go, but your Python application won't work edit: unless you copy all the layers, that is).

You can read the docs here: https://docs.docker.com/engine/security/userns-remap/#prereq..., and note that it stores image/container layers in subdirectories under /var/lib/docker.

Tl;dr: user namespaces are inherently incompatible with many of the usability features Docker brings over other solutions, while they're not particularly useful for many popular use cases (no shared hosting, minor differences in consequence between escalating to the root of the container and its host - though that's an assumption frequently wrongly made).

Re:Escaping Docker container using waitid() – CVE-2017-5123 by zenlikethat on Friday December 29, 2017 @05:54PM (#16032575)
Also, people hold their bind mounts to the host near and dear, and user namespaces would break all kinds of things people expect to "just work" with bind mounts. Having user namespaces on by default would break tons of existing scripts, Compose/Kube files, etc. that do things like mount /var/lib/mysql into the container for persistence.
Re:Escaping Docker container using waitid() – CVE-2017-5123 by fpoling on Friday December 29, 2017 @04:03PM (#16031969)
I tried it a couple of months ago. It immediately broke build of one of the images. It was a known bug. So I guess I just wait one more year to try.

In the mean time, I make sure that all my containers runs as non-root with max security restrictions. The exception so far was sshd from OpenSSH and mostly due to incorrect porting from OpenBSD in portable ssh.