I really want to like docker for end user applications. However, until the problem of sanely sharing users into the container is solved, it is something that merely works well right up to the point you try to do something useful.
I suppose this can be sidestepped by allowing root in all of your containers for the applications. I am curious if that actually provides security benefits, though.
An example is easiest. I have my machine setup to provide who I am to machines I ssh to. Now, launch a container that you want to pull data from a machine that you have ssh access to.
First, you'll find that the user used to setup the container was not you. So you can't even just map in your .ssh dir.
So you'll try modifying the image to work with specified user at start up. Only, again, it wasn't setup that way. You will start modifying the entire image to work, but will hit tons of assumptions on user name. (You may get lucky here. I didn't.)
So then you think to just run as root so that the user in the container will have permission to your .ssh files. At first you forget to specify user name on ssh commands, since the command thinks you are root now. easy enough, at least.
Only, you forgot you have proxy commands in your config and other scripts that you now have to edit because they rely on your user name. So you can fix that.
Now you can finally do what would have been trivial for an app installed on your machine.
I have been making end-user apps for myself and for folks at work that require such identity, in one case, ~/.ssh, and in another, ~/.gnupg.
My solution isn't particularly novel or clever, but it works well.
The docker image of the command-line app is the same for all users, and so lacks their identity built in.
The hack is to drive invocation of the docker image with a shell script that makes a temporary directory, copies in the necessary identity files from ~, and does a docker run that maps those identify files into the docker image.
After the docker image exits, the bash invocation script cleans up.
It's a hack, but it works surprisingly well. In my tests, it adds about 100ms of invocation latency for a python program. That is, running the docker image containing a python program that copies some files in as described is about 100ms slower than just running the same python program directly.
It would be nice to have a more elegant solution to this, but it's not too bad.
disclaimer: I am not a security expert. Reader beware!
If you're using ssh-agent, maybe you could bind-mount your host's $(dirname $SSH_AUTH_SOCK) into the container, and then set the SSH_AUTH_SOCK environment variable to point at it when you run the Docker container. That way you're not even sharing the private key with the container.
I imagine you could do the same with gpg-agent, too.
I think this is the common solution. It definitely feels like a hack, though.
I thought of the ssh-agent trick, but never thought of how to actually do it and moved on to other problems.
I would love to hear thoughts on better ways to fix this. Apologies for not responding earlier, as I really want this conversation to end somewhere. I just feel ashamed that I don't know how to continue it.
I do want to throw out there that this should not keep folks from trying docker. Please try it. Even better, suggest ways to advance this use case.
This doesn't really change anything. I want to put data in and then take derived data out. All while maintaining access protections to my user on the host system.
That is what they do nominally. But for existing data, it falls flat. Hard.
Again, an example is easiest. (Will also shed light on if I am actually doing something wrong. Entirely in the realm of plausible.)
So, you have a file share with your data, scoped to user "cheez". You can ssh to machine "remote" and see this data. You can copy this data over to your machine, call it "local" and it will still be scoped to your user, "cheez". This is great, as you don't have to worry about someone else accidentally getting access to it.
However, you decide to use "container A" to run some analysis on this data. The folks that setup "container A" did so using the username "container". You mount your data on a volume to "/my/data". You check, and the container can now see it, but user "container" does not have permission to do anything with it.
You have plenty of options at this point. You can give public permissions to see the data in the directory. You can launch ssh from in the container and copy the data in. (Note that this way will have the data in the container as belonging to "container" which will make similar concerns on egress.)
You can also run the container as "root" which will clearly have permission. However, recognize the concerns with this approach, as this also gives you permission to see any other file in that directory that "cheez" wouldn't normally have permission to see.
You can also recreate the container such that "cheez" is the user that is created in the container. This sounds great, but redoing the entire setup of the image has a few problems. Not to mention the security implications this has, since you could also recreate the image with the user of your boss and circumvent some other security measures of your machine.
Now, if your container doesn't set anything up in userspace (defined as "not root") until launch of the container, much of this concern goes away. Not all of it, I believe, but most. However, anything that you want to run "in the container" using your identity from "out of the container" seems to fall into this trap. It is subtle, but gets in the way of a lot of use cases.
I'm not seeing anything there that addresses this.
To be clear, as a service deployment mechanism, this is fine. As an end user tool, this blows. Unless every container builds in support for LDAP or Kerberos, then each container is effectively a new computer on the network without auth setup in a meaningful way.
What it's saying is that you have a container you use only to store the data, then share that container's volume with the target container. Finally, because it's on your hard drive, you can access it.
Basically, instead of host -> container, you do container -> container.
And yeah, the container is supposed to be effectively a new computer, but you can build images to create the auth environments you need and base everything off those.
But that doesn't work unless you do everything with public permissions. Seriously try it. Make a container that you share a volume with. Do something in that container on some data and see who owns it according to your computer.
The use case I have above is a real one. Somehow try to share your .ssh folder with a utility container sometime.
User namespaces somewhat help. But fall flat for the case of "still being you" on a container.
It can be comical even for the intended two containers choice. Unless both use the same uid:gid to write files, one container will not be able to read the other containers data.
So here is how I would think about your problem: am I doing this the way the tool wants me to do this? Does the tool even support this use case? If not, how should it be done? Is it impossible, or do I just not like the aesthetics of the solution?
If it's just the aesthetics of the solution, then you have a way forward. But if it is literally impossible to get data on and off a container, then you have a problem.
Apologies for the slow response on this post. I would love to think of ways to fix this. I think most uses of docker today involve deploying applications that you do want completely sandboxed. And for those, this works rather well. Hopefully this doesn't keep you from trying it. (Indeed, you may have a nice solution to this that escaped me.)
That is certainly a path I considered. However, having to setup either of those is not exactly trivial. And not something I care to do for a user application.
As I read this again I'm quite confused what this announcement means. The mention of snap package makes it seems like "apt-get install docker..." would be a separate binary. A wild guess would be that 99% of Ubuntu users will never buy CS Docker Engine so will that 99% of users be running the debian/ubuntu packaged docker.io binary that exists today?
At a not so distant future point, Docker will be delivered as a snap package. Users installing docker via `apt-get` will ultimately be installing the snap.
We are working through the final technical details of this portion now. We'll make sure to keep everyone updated as this transition happens, but current best practices should continue to Just Work.
i had a quick question - do you see a convergence of Flatpak and snap at some point ? because it seems that RedHat and Fedora are beginning another divergence on static packaging.
Actually, there's quite a bit of cross-distro compatibility around Snaps. Beyond Ubuntu, Snaps are known to work in Arch Linux, Debian, Gentoo, Fedora, openSUSE, Yocto, and OpenWRT. Snaps simply require a modern systemd and snapd daemons. With the appropriate SELinux profiles and an updated snapd, it's entirely feasible for the same docker.snap to run on both Ubuntu and Fedora (as well as others). You can learn more about Snaps and Linux distributions at snapcraft.io.
And the same thing is true for Flatpak...but are we really looking forward to another 20 years of multiple packaging formats for Linux ?
The push towards static packaging is a great time to unify. The problem is that snap is based on deb..not sure about Flatpak. So we again have a political split.
I really think this is the opportunity to unify Linux packaging - anything, I don't care..but let us please have one package format.
It would be great if there was a cohesive roadmap showing how Snaps fit in with Canonical's overall strategy wrt System and Application containers across Cloud and Embedded systems.
Lots of little "islets", not so much an "archipelago".
Snaps are just a package format, an alternative to .deb which puts control of updates in the hands of the upstream. They enable an upstream to deliver a set of stable releases across versions of Ubuntu and other distros. In this case, it means Docker Inc can offer 1.x, 2.x, 3.x of Docker and provide security and feature updates directly.
Thanks for answering. Flatpak is unavailable for Ubuntu official repositories (it has an unofficial ppa) while Snap is only installable on Fedora using a copr.
A new packaging format would have been great time for Linux to converge around the biggest usability+discoverability+ availability problem that the platform has. While developers need to release one binary for osx or Windows...they need to release atleast 4 for different Linux flavors.
Is there any chance that there could be convergence around the new static packaging that everyone is reinventing?
I'm worried about Docker living up to its valuation, and I haven't seen the business model that will meet the expectation of their valuation long-term yet.
They have built a great open source product, but now that there has been a collective shift to understanding the benefits of containers, the docker runtime + container format will/should be commoditized by infrastructure companies (Google, RedHat, MS etc).
So where is the value-add of Docker the company going to come from?
There's more than one type of container. Docker, and docker flavors (runc, rkt, etc). LXD is a machine container, it's the same technology that Docker was first built off of, but it's a hypervisor for really dense machines that are as light as process containers.
Snaps is a package format that gives you a cross (linux) platform distribution, atomic updates, security, and isolation. It's not really like docker as it's not a density story, there's no unique TCP/IP stack, etc.
Calling rkt and runc docker flavors is a bit misleading. Runc is an OCI standard container runtime which docker itself also uses. Although rkt can consume docker images it is an entirely different container runtime with several distinct execution stages. For instance, you can run rkt containers with an LKVM stage1 instead of systemd-nspawn.
like xen? I sat on a 10 minute presentation during openstack meetup, Ubuntu dude presented LXD...then I asked myself...xen does all this...then again choice is always welcomed
The VM experience ("guests") without the VM overhead. A virtual machine like Xen or KVM or ESX lets you run a guest kernel of a different OS, like WIndows. LXD avoids the overhead of hardware virtualisation and the guest OS, which means it only supports Linux guests, but they run at native speeds.
Any local kernel vulnerability will let you attack other containers on the same machine. This is a much bigger attack surface than Xen or KVM. It's nice in that it gives the same experience as "traditional" hypervisors (at least the basic features), but it's only applicable if you trust that the application inside the container will not be compromised.
On the flip side, when there is a kernel vulnerability, there's only 1 kernel to update! If you're running the Canonical Livepatch Service, for instance, critical security vulnerabilities are patch in real time, without reboot, and all containers running immediately benefit from the patch. Conversely, if you're running 50 Linux Xen or KVM machines, you have 51 kernels to update. So yeah, do think about what "attack surface" actually means, when comparing LXD and Full Virtualization.
On the same vein, there are plenty of Xen machines that are vulnerable despite the host OS being updated (which, honestly, I don't thing happens as quickly as it should considering it requires a restart for new kernel params). With things like live-patching, updating the kernel once, while running, makes sure all guests are also updated as well.
It's a trade off, but one that seems to trend towards more secure despite potentially a few quirks.
LXD supports using different id maps per container, which mitigates some of that.
I get that containers will always have a larger attack surface than Xen/KVM. Just thought it was worth mentioning that some container approaches are thinking about security more than others.
Sure, Xen is a hypervisor - just like KVM and a whole host of others, but Xen is /very/ heavy from a resource utilization. Xen doesn't produce lightweight VMs, they're traditional virtulation. You can produce 13 times more density with no performance trade off. No virtio, no paravirtualization, using native kernel primitives to get you machines that feel like "docker" containers, but are actual full machines.
Docker and LXD don't compete. Docker is great for running clustered processes - cloud-native apps - where Docker gives you hyperelasticity. CS Docker Engine provides more coordination facilities for those cloud-native apps.
LXD is more like KVM in that gives you "guests" that feel like a full OS. You can run existing apps in there in exactly the same way you would run them in a VM.
So these are two counterparts in the container continuum, and it's useful to understand them both so you use the right thing at the right time.
I'm well aware of LXC, I do understand them both. And LCX is not more like KVM. KVM is full virtualization, it emulates hardware, and nothing like LXC.
LXC is based on cgroups and kernel namespaces - the exact same things that enable Docker-based containers. LXD and Docker engine are competing "container"-based virtualization engines.
LXC can can be run as app-based containers just like Docker. This is what lxc-execute does. You don't have to run init as pid 1 in LXC.
By the way "Cloud-native" is little more than a marketing term.
This makes me feel good about going with CentOS for Docker. Red Hat has a custom, stable Docker version which is rock-solid (albeit somewhat old, 1.10).
Depending on your use case, that may not be such a great idea. Unless Red Hat have back-ported it, 1.10 misses several important security advances that have come into Docker in recent versions...
Red Hat has a vested interest in the failure of Docker. So... It's up to you if you want to continue using (or trusting!) any "Docker" software released by Red Hat.
First time I've ever seen this abbreviation. I only clicked because I wanted to find out what it meant. I probably wouldn't have clicked if I had known it meant "Commercially-Supported".
I suppose this can be sidestepped by allowing root in all of your containers for the applications. I am curious if that actually provides security benefits, though.