Actually for all people below, here are my reasons:
Docker adds another Layer. This also adds another attack target (docker). Saying a software is more secure while adding another layer is just naiv.
Docker is good for some companies and it definitiv is true that you can make it to run a PaaS, it's still not more secure as the world before.
Also some other people also pointed out other things.
With docker you add a lot of complexity to your actual software, that is negligible if your big since you have a total different set of problems.
Still when it comes to docker it's mostly buzzword bingo. I mean just looking at the table... oh god it's like half the things there could just be done without docker in a way more secure way, without LXC, Docker or RKT.
Also I always tought that docker should make the deployment easier, which would be a hugh bonus in security since the process of understanding and everything beyond would be more understandable. however the more docker grows the worse the complexity gets. Docker once looked shiny but than the enterprise hit it and it's direction more and more makes it less secure since they try to add more and more stuff and stops focusing on the stuff docker was firstly invented.
How could adding a ton of abstraction (which grows every release) making something more secure? I just keep that as an open question to everybody.
Why, exactly? The article's argument is that containerization limits the vulnerable area - even if an attacker gains root access to a container, they still can't do as much damage as they would had they gotten root access in a host machine.
I don't mean to sound adversarial - but what's your counterpoint to that?
Is that really true? I have always read that cgroups based containerization on Linux is kind of a joke and that root in the container more or less equals root on the host.
Has there been significant improvement in this area lately?
There isn't one. It's just a narrative regurgitated by people with an axe to grind. The anti-Docker crowd. User namespacing arrived in 1.10, which brought a lot of great possibilities for further compartmentalization with it. Alpine is the default base image. Lots of great, positive changes have gone into this blog post.
Great points, we're working on a bunch of this stuff.
Docker 1.12 in swarm mode, for example, does automatic key rotation and issuance of the TLS certs assigned to every node in the cluster. These certs are used for automatic TLS between every node in the control plane of the Docker Swarm. This is all automatic and transparent to the user -- no manual management of certificates is required.
Now that we have cryptographic identities assigned to every node in the cluster we can use that to build secrets/key management in to the system.
Additionally Docker 1.12 is swarm mode has overlay networking with encryption possible for container to container communications.
In terms of logs, Docker supports log drivers that allow all logs within Docker containers to be exported to off-host logging services.
How is the overlay network encrypted? I couldn't find any information. https://github.com/docker/docker/issues/24253 says it's not encrypted by default and must be enabled manually.
The bundling of all your software's dependencies into your container means that you can't upgrade 1 .so on a machine, and all software be updated. Great example recently was libgcypt's security bugs.
You have to upgrade all containers, which requires figuring out which ones need upgrading.
The concern isn't generally that someone will escalate and then delete some other container's filesystem.. it's that once they get remote execution in a container that has connections to your database, http to your discovery service etc, they can steal your customer information.
I will say however that this post is showing that by using docker or frankly other well manicured execution enviroments, large swaths of attacks will hopefully not work (selinux & seccomp being great examples).
Well, Docker containers are really meant to be short-lived. On the order of milliseconds (e.g. run a batch operation) to days (run a web server application). They're also meant to be mostly immutable. So a vulnerability in a particular library that allows an attacker access to the container won't necessarily allow them to do much.
The other benefit of short-lived containers is that any given vulnerability only lasts as long as the container (assuming you're rebuilding your image with the latest & greatest software/libs before each deployment). Whereas with a full OS/VM you have to find down time to patch that sucker and that might take a month or even a quarter or longer.
Even if you keep deploying new versions of containers every few days because you use them to deploy new features, how about the db and web server containers? And how about the vulnerabilities that won't be patched until you make a new deploy? We should build a new container after each apt-get for security patches, right?
Running a traditional relational DB inside a container is pretty stupid. It can take a while for those suckers to stop & start and they often don't work properly if placed behind a load balancer with random distribution of connections. Also, if a connection gets cut off in the middle of a transactions things can go very, very wrong.
On the other hand, if you architect your database usage in such a way as to ensure that cutoff transactions get detected and retried without relying on persistent connections it can be a good idea to use containers for hosting your database(s). Of course, your use case needs to fit this kind of model for it to work. If your use case requires mostly serial transactions and can't work with "eventual consistency" then containers are probably a no-go.
> We should build a new container after each apt-get for security patches, right?
Yes. That's the idea. Here's when and why you re-deploy:
* A new, updated version of software/a package is out.
* You've made changes to your app. Even something as simple as a typo.
* Your container has been up too long (e.g. 24 hours).
Replacing existing containers multiple times a day in a production environment is the norm. "The only constant is change" and the more often things change the more often you'll be swapping out your containers for new ones.
The whole point of containers is that they can be brought up and down in an instant without impact (if you architect things correctly). So even a VM that runs "apt-get update ; apt-get -y upgrade" every night may not be as up-to-date or secure as the same software running inside a container.
If you're using an image tagged "latest" (e.g. FROM ubuntu:latest), updates are already being pulled into your containers by default. Since containers are ephemeral, fixing security bugs can be as simple as just rebuilding and redeploying your containers.
That's a good point, for sure. But on the other hand, some upgrades may be delayed or left undone because more services depend on the same library, so the risk of breakage is higher. So, there's at least some incentive to using more recent versions, because there's less surface area to test.
Not sure how much this affects what's in the wild, though - I mean, I have no data to show that people really do tend to upgrade more often while containerized than not.
The important metric with patching vulnerabilities is time-to-patch. Docker based environments are able to significantly reduce time-to-patch precisely because the libs are bundled with the application. Most orgs have trouble rolling out patches to system libs because the testing matrix for rolling out patches mandates testing across the board for all application and system-level consumers of the lib. This can often take weeks or months. When the lib travels bundled with the app, just the app in isolation can be patched and rolled out immediately.
It is important to have an inventory so you can do patching across the board and have notifications that it's needed. This is why there are now a number of security scanners for Docker containers, including Docker's own: https://blog.docker.com/2016/05/docker-security-scanning/
So it's the static/dynamic linking argument all over again.
Personally, as a sysadmin, I dislike docker. Not that there's anything wrong with its implementation in particular, but because I can no longer confidently say what is actually in our stack (we run 4 different versions of Python, last I checked -- it's absolute madness).
Now, I grant Docker's argument: if you're going to do something like that, Docker is pretty much the best way around to do it. Fair enough: it's the best available tourniquet for the self-inflicted wound of bad stack management. But to me, the ease of redeploying gets outweighed by the increased complexity of the security reasoning you have to do.
Docker containers run with default seccomp profiles, namespacing (filesystem, PIDs, mounts, etc), LSM policies (AppArmor, SELinux), and capability dropping.
These are all common sense security controls that aren't widely available because they're typically hard to use. Docker makes them defaults for everyone. This makes classes of remote attacks against applications far more difficult. Tangible example: read-only filesystems + mount namespacing make vulns that require filesystem modification or directory traversal far more difficult.
At this point arguing against running in Docker is like arguing in favor of IE6's security model instead of Chrome's.
You guys are doing a great job! Some security-related sandboxing options to docker run that people may not be aware of, which are hard to assemble individually from Linux pieces:
I argue against using docker but simply due to the fact that docker encompasses too much when everything docker does could be accomplished by simple single use tools like unshared, cgexec, etc. Git does this and it works very well.
The reasoning that "more layers of abstraction necessarily equals less security" does not seem true to me. Granted, it increases the "surface area" that is exposed to attacks, and there's indeed a tradeoff involved, but this tradeoff may swing either way - either it does pay off or not.
Taking this reasoning to the extreme, there are plenty of abstractions that pay off for secutiry. One simple example is that software written in Java (for example) is by default more buffer-overflow-resistant than software written in C, due to managed memory/bounds-checking. In this case, the tradeoff was performance vs security.
> How could adding a ton of abstraction (which grows every release) making something more secure?
One example is the "buffer overflow resistence" in Java vs C mentioned above.
Actually we are a 100% Java Shop but the JVM has a lot of Bugs, Bugs that you won't have in C. Yes you can run into your own code smell, Bugs or whatever, but the same could happen on Java, too.
The biggest problem with docker is the tone of stuff they try to put into. While most stuff is just possible without docker and the big abstraction.
Hell you can start your programs under Linux with user namespaces just without docker.
Actually trust me it's way easier to control a single stack instead of managing a stack on top of another. Especially networking is no fun. Maybe it's cool and easy / shiny if you can have everything in the cloud, but that just won't apply to everybody.
> the JVM has a lot of Bugs, Bugs that you won't have in C
There will be different classes of bugs, of course, but I find it hard to believe that it will be more bugs, or more serious bugs, or most costly-to-fix bugs. Otherwise, your own company would have decided to use C instead of Java, right?
> Hell you can start your programs under Linux with user namespaces just without docker
Sure you can, but if Docker (or any other solution, for that matter) makes it easier or faster to do that, more people would do that. There's a more or less fixed number of work units to dedicate on a certain project, if you have to use them all to set up security solutions, your lunch will be eaten by other people.
> most stuff is just possible without docker and the big abstraction
Most stuff is "just possible" without any abstraction at all. However, one has to learn to leverage abstracted-away stuff, otherwise one will spend a lot of time and accomplish very little valuable stuff.
> trust me it's way easier to control a single stack instead of managing a stack on top of another
Easier does not equal safer, faster, or more business-valuable.
> it's cool and easy / shiny if you can have everything in the cloud
Not sure where "the cloud" enters the equation? You can use Docker (or whatever else) to manage even your on-premises stack.
---
I don't know the specifics of your situation at all, but if your only argument against a particular piece of tech is "it abstracts away stuff, therefore it is worse", you might want to consider some self-reflection on whether you're not just suffering of NIH Syndrome (https://en.wikipedia.org/wiki/Not_invented_here)
Umm they misspelled "you are a sucker by default" they had a brain fart and actually wrote "secure by default". I think someone was dreaming of OpenBSD.
We are on the case right now. The solution is going to be really, really good. We had to get cryptographic node identity rolled out first and we're designing secrets management on top of that.
If you're playing to the 'secure by default' crowd, they aren't going to just trust that you're on the case if you don't communicate. Platitudes are something people watch out for when security is on the line, and they'll chose another solution if they think you're full of shit.
You have to show, at all times and all things, how you're thinking about the problem. 15 months of dead air is a lot to atone for.
I'm building a secret management solution for my team right now that will work securely with docker. I think it's pretty cool - I'll write how I'm doing it later today.
"Secure by default" is a great philosophy to have. I hope Docker continues to push into this direction.
However, where is image signing? Where is pulling images by their hash instead of mutable tags? Where is restricting what images run according to their hashes? Where is Docker not running a daemon as root? How about Docker doing more hardening releases and fewer feature releases?
There's a lot of low hanging, security related fruit which haven't been picked. Why not?
Process isolation is a fantastic. There just really needs to be more, in my opinion.
The coolest bit here is to be able to do threshold signing. Essentially k-of-n signing for containers and verification gates that only allow containers with enough signatures in order to deploy. For some more background check out the blogpost here: https://blog.docker.com/2016/08/securing-enterprise-software...
> "Secure by default" is a great philosophy to have. I hope Docker continues to push into this direction.
Thank you. We will absolutely keep pushing.
> However, where is image signing?
Docker supports image signing out-of-the-box. It's based on TUF which is the state if the art in secure content distribution. Along the way we open-sourced our underlying TUF implementation so thaf others can reuse it: https://github.com/docker/notary
> Where is pulling images by their hash instead of mutable tags?
That's also available out of the box: "docker pull NAME@DIGEST"
> Where is restricting what images run according to their hashes?
That's not available out of the box, but a popular way to implement it is to funnel images through a trusted private registry, only allow pulls from that registry, and then controlling what you push to it.
Another possibility is to use the new auth plugin system, although I haven't tried.
> Where is Docker not running a daemon as root?
Docker runs unprivileged by default, but only on relatively recent kernels with user namespace support (it drops itself to "fake root" so it can still create containers without actually having uid0).
On older systems (or if you don't trust user namespaces) I agree we could break up some parts of the daemon (for example push/pull) to drop privileges further. That requires serious refactoring which we have been working on gradually for some time.
> How about Docker doing more hardening releases and fewer feature releases?
We follow the linux methodology: every release includes many hardening improvements, as well as whatever features have been deemed stable enough to merge. We don't control what pull requests the community sends, but we work hard to maintain a high quality bar and encourage quality-oriented contributions. The Docker core engineering team invests more time on hardening than features.
> There's a lot of low hanging, security related fruit which haven't been picked. Why not?
I'm sure there are :) Security is a process, we will never be done. The important thing for us is to take it seriously, invest appropriately (Docker core team employs 6 full time security engineers and funds various third-party security efforts), and make sure we are perpetually improving.
On top of that, Docker is known for making powerful technology more accessible to more people. We want to use that "superpower" to make security more usable by non-experts. We think that contributes to making everyone more secure.
> Process isolation is a fantastic. There just really needs to be more, in my opinion.
Docker security is about much, much more than process isolation.
Thanks for the feedback. We hope to see you on the github repo, we value bug reports :)
> It's based on TUF which is the state if the art in secure content distribution.
Sounds great in theory, but there hasn't been much traction on that project, at least from their own website, for over 6 months. Not much in terms of peer review of their method, or practical audits of their technology. Even your own audit is over a year old now, despite constant changes to the codebase.
That said, I do recall now when this was announced originally, and I'm glad that it at least exists. That it has skipped my memory makes me wonder why there has been little to no press about it since then. How broadly adopted has this been? Can we get signed images for, say, Ubuntu from docker hub?
> docker pull NAME@DIGEST
A great feature to have. Can you point me at the digest for the ubuntu repo on docker hub?
> serious refactoring which we have been working on
Good to hear. Also, interesting to note that runc still requires root access to make cgroups; I was not aware of this restriction.
> The Docker core engineering team invests more time on hardening than features.
I find this to be an interesting position to take, considering that a core component of docker has been historically re-written with every other release: registry in 1.6, disk plugins in 1.7, networking in 1.9, runc in 1.11. IIRC, networking was re-written again in 1.12, to support yet another version of clustered networking. That's a lot of churn for less than a year and a half worth of time.
> We hope to see you on the github repo, we value bug reports
That hasn't gone well for me in the past.
devicemapper errors in ubuntu 14.04, prior to dynamic linking: not our problem.
devicemapper dropping mounts sporadically: move to overlayfs.
Low level mutexes being shared between containers: that's nodejs' problem.
It's frankly become easier to create and use workarounds like spam-unmounting orphaned devicemapper mounts, or custom-compiling and distributing docker, or disabling docker-managed networking, and so on.
I feel bad for ragging on Docker like this, especially since I do end up using it frequently; but as a system administrator Docker is a nearly daily headache. Our developers love it, but the rest of us... not so much. I guess it's one of those "technologies everyone complains about" vs "technologies nobody uses" things. It's just really frustrating.
Cool, that mostly just works (had a socket error the first time I tried).
However, there's some usability problems here that I'd like to bring to your attention:
- There is no indication that the pull is different; no output from trust verification that it is indeed signed. This means I have to trust that Docker did the right thing, with no means of verification.
- Inspecting the image after pulling gives no indication that the image is signed, and gives me no way to do my own signature validation on the image.
- It does fail properly when pulling an unsigned image. Yay!
- Docker run initiates a connection back to notary, and fails if it can not connect. This makes me uneasy - it makes me wonder what data is passed, how it's being used, what changes are being made according to the response, and so forth.
- Using trust is a per-command decision, instead of a daemon setting.
- There's no clear method to revoke a signing key if identified to be malicious.
- This seems like a good candidate for "secure by default" once some of the usability issues are resolved.
> I find this to be an interesting position to take, considering that a core component of docker has been historically re-written with every other release: registry in 1.6, disk plugins in 1.7, networking in 1.9, runc in 1.11.
To be fair, runC was its own project for quite some time. Docker just switched from importing the runC code to actually running the binaries through containerd as a proxy in 1.11 (a design decision I'm still trying to wrap my brain around, but that's a separate issue).
> Docker runs unprivileged by default, but only on relatively recent kernels with user namespace support (it drops itself to "fake root" so it can still create containers without actually having uid0).
Is that right? As far as I'm aware, runC doesn't have support for anything like that (and Linux's method of handling network namespaces under an unprivileged user namespace doesn't allow you to even have a network connection to the outside world). Sure, in runC we're working on rootless containers, but that's a while away from being done and Docker might not ever be able to support rootless containers completely (since it needs to handle networking and some other things that still need some quite significant kernel work to complete).
We use Docker to containerize apps in cloudron. One issue we have faced is that --readonly and user namespaces don't work together. Is there any on-going effort on this front? I can't find a link now but this limitation is hidden somewhere deep inside the docker docs :/ For cloudron apps, we simply decided that readonly was more important than user namespaces for now.
The chart is very out of date. rkt has support for userns, the capability set is identical to that of Docker, and so is the default seccomp configuration. The SELinux policy used by rkt has always been identical to the one used by Docker (I have no idea why the chart claims there was a difference), and it's used by default if SELinux is enabled on the system. Rkt has no apparmor policy support, the set of files under /proc restricted by rkt is still slightly smaller than that restricted by Docker, and the cgroup difference doesn't actually appear to be discussed in the NCC paper so it's hard to comment on the difference there.
I don't want to criticise Docker here from a security perspective - several security features in rkt are based on the implementation in Docker, and running your apps isolated under Docker is definitely more secure than running them all on the same unconfined host.
(Disclaimer: I work at CoreOS, though not primarily on rkt)
The chart will be a bit old now coming from a white paper that was published 4 months back and was in the works for some time before that. (disclaimer - I work for NCC but didn't work on that paper)
One of the big challenges with the containerization landscape is keeping up with changing product capabilities as there's a lot of movement all over the place.
The default seccomp configuration in rkt is not the same. It is based on the Docker one, yes, but as it does not support parameter filtering it is significantly weaker, eg it allows namespace creation, and all use of the personality syscall, allowing users to disable ASLR.
“Gartner asserts that applications deployed in containers are more secure than applications deployed on the bare OS”
Gartner is like a financial ratings agency. I wouldn't rely on their recommendation if I were concerned about the security of any application or platform.
Can anyone from Docker speak to the status of content trust? The fact that I can still `docker pull whatever` without explicitly trusting the source seems to conflict with the chart in this post. Will/shouldn't content trust be turned on by default at some point?
To add to Justin's comment, we merged what we've called "trust pinning" into Notary. We're still iterating on exactly the right scopes to pin to, but anticipate that making it into docker in the not too distant future. That will enable you to hard fail when pulling images not signed by an explicitly approved source.
From what I've seen Docker has added a lot of security functionality in the last couple of releases which is great, although I'd like to see more work at the Docker engine level on authentication and authrorization which still feels kind of all or nothing (I know there's a plugin framework, but there's not a load of good options there at the moment). Also at the moment implementing additional security options is a bit bitty, as the planned security profile work hasn't landed yet.
the other thing to note is that when deploying Docker engine the defaults tend to go towards making everything work and aren't necessarily the most secure, so its very much worth doing some additional hardening where possible.
Specfically things like
- enabling user namespacing
- disabling icc
- removing capabilities (e.g. NET_RAW)
- not using the default docker0 network
- disabling userland proxy
There is a CIS standard which is pretty much up to date and has some, hopefullly, decent sets of things to look at hardening (disclaimer I helped work a bit on the latest version...)
Does anyone know of a guide to using Docker, or an alternative, on Windows to help isolate various software (say, Steam games, multiple Visual Studio installations, .NET and Java runtimes/SDKs)?
Both the Docker blog post and the Gartner piece seem to be silent on the topic of out of date and vulnerable software in Docker images, which has been much talked about.
Looks like Docker have put out a content scanner service to mitigate the problem this still seems to be a weakness relative to the pre-Docker way of building VMs.
59 comments
[ 247 ms ] story [ 2554 ms ] threadActually for all people below, here are my reasons:
Docker adds another Layer. This also adds another attack target (docker). Saying a software is more secure while adding another layer is just naiv.
Docker is good for some companies and it definitiv is true that you can make it to run a PaaS, it's still not more secure as the world before.
Also some other people also pointed out other things. With docker you add a lot of complexity to your actual software, that is negligible if your big since you have a total different set of problems.
Still when it comes to docker it's mostly buzzword bingo. I mean just looking at the table... oh god it's like half the things there could just be done without docker in a way more secure way, without LXC, Docker or RKT.
Also I always tought that docker should make the deployment easier, which would be a hugh bonus in security since the process of understanding and everything beyond would be more understandable. however the more docker grows the worse the complexity gets. Docker once looked shiny but than the enterprise hit it and it's direction more and more makes it less secure since they try to add more and more stuff and stops focusing on the stuff docker was firstly invented.
How could adding a ton of abstraction (which grows every release) making something more secure? I just keep that as an open question to everybody.
I don't mean to sound adversarial - but what's your counterpoint to that?
Has there been significant improvement in this area lately?
I'm not sure I agree, I'd offer some improvements:
- Gartner "studies" are usually paid advertisements
- The comparison table is missing columns for DOM0/1 VM's and BSD jails
- Encryption in-transit or at-rest isn't mentioned
- Nothing about key management or key rotation
- Non-mutable / exported log files aren't in the defaults
Docker 1.12 in swarm mode, for example, does automatic key rotation and issuance of the TLS certs assigned to every node in the cluster. These certs are used for automatic TLS between every node in the control plane of the Docker Swarm. This is all automatic and transparent to the user -- no manual management of certificates is required.
Now that we have cryptographic identities assigned to every node in the cluster we can use that to build secrets/key management in to the system.
Additionally Docker 1.12 is swarm mode has overlay networking with encryption possible for container to container communications.
In terms of logs, Docker supports log drivers that allow all logs within Docker containers to be exported to off-host logging services.
You have to upgrade all containers, which requires figuring out which ones need upgrading.
The concern isn't generally that someone will escalate and then delete some other container's filesystem.. it's that once they get remote execution in a container that has connections to your database, http to your discovery service etc, they can steal your customer information.
I will say however that this post is showing that by using docker or frankly other well manicured execution enviroments, large swaths of attacks will hopefully not work (selinux & seccomp being great examples).
The other benefit of short-lived containers is that any given vulnerability only lasts as long as the container (assuming you're rebuilding your image with the latest & greatest software/libs before each deployment). Whereas with a full OS/VM you have to find down time to patch that sucker and that might take a month or even a quarter or longer.
Even if you keep deploying new versions of containers every few days because you use them to deploy new features, how about the db and web server containers? And how about the vulnerabilities that won't be patched until you make a new deploy? We should build a new container after each apt-get for security patches, right?
On the other hand, if you architect your database usage in such a way as to ensure that cutoff transactions get detected and retried without relying on persistent connections it can be a good idea to use containers for hosting your database(s). Of course, your use case needs to fit this kind of model for it to work. If your use case requires mostly serial transactions and can't work with "eventual consistency" then containers are probably a no-go.
Yes. That's the idea. Here's when and why you re-deploy:
Replacing existing containers multiple times a day in a production environment is the norm. "The only constant is change" and the more often things change the more often you'll be swapping out your containers for new ones.The whole point of containers is that they can be brought up and down in an instant without impact (if you architect things correctly). So even a VM that runs "apt-get update ; apt-get -y upgrade" every night may not be as up-to-date or secure as the same software running inside a container.
Not sure how much this affects what's in the wild, though - I mean, I have no data to show that people really do tend to upgrade more often while containerized than not.
It is important to have an inventory so you can do patching across the board and have notifications that it's needed. This is why there are now a number of security scanners for Docker containers, including Docker's own: https://blog.docker.com/2016/05/docker-security-scanning/
Disclaimer: I manage security at Docker.
Personally, as a sysadmin, I dislike docker. Not that there's anything wrong with its implementation in particular, but because I can no longer confidently say what is actually in our stack (we run 4 different versions of Python, last I checked -- it's absolute madness).
Now, I grant Docker's argument: if you're going to do something like that, Docker is pretty much the best way around to do it. Fair enough: it's the best available tourniquet for the self-inflicted wound of bad stack management. But to me, the ease of redeploying gets outweighed by the increased complexity of the security reasoning you have to do.
Docker containers run with default seccomp profiles, namespacing (filesystem, PIDs, mounts, etc), LSM policies (AppArmor, SELinux), and capability dropping.
These are all common sense security controls that aren't widely available because they're typically hard to use. Docker makes them defaults for everyone. This makes classes of remote attacks against applications far more difficult. Tangible example: read-only filesystems + mount namespacing make vulns that require filesystem modification or directory traversal far more difficult.
At this point arguing against running in Docker is like arguing in favor of IE6's security model instead of Chrome's.
Disclaimer: I manage security at Docker.
There is also --pids-limit=<some number> against fork bombs.
EDIT - this git repo has more links to security related articles etc. https://github.com/wsargent/docker-cheat-sheet#security
The reasoning that "more layers of abstraction necessarily equals less security" does not seem true to me. Granted, it increases the "surface area" that is exposed to attacks, and there's indeed a tradeoff involved, but this tradeoff may swing either way - either it does pay off or not.
Taking this reasoning to the extreme, there are plenty of abstractions that pay off for secutiry. One simple example is that software written in Java (for example) is by default more buffer-overflow-resistant than software written in C, due to managed memory/bounds-checking. In this case, the tradeoff was performance vs security.
> How could adding a ton of abstraction (which grows every release) making something more secure?
One example is the "buffer overflow resistence" in Java vs C mentioned above.
Actually trust me it's way easier to control a single stack instead of managing a stack on top of another. Especially networking is no fun. Maybe it's cool and easy / shiny if you can have everything in the cloud, but that just won't apply to everybody.
There will be different classes of bugs, of course, but I find it hard to believe that it will be more bugs, or more serious bugs, or most costly-to-fix bugs. Otherwise, your own company would have decided to use C instead of Java, right?
> Hell you can start your programs under Linux with user namespaces just without docker
Sure you can, but if Docker (or any other solution, for that matter) makes it easier or faster to do that, more people would do that. There's a more or less fixed number of work units to dedicate on a certain project, if you have to use them all to set up security solutions, your lunch will be eaten by other people.
> most stuff is just possible without docker and the big abstraction
Most stuff is "just possible" without any abstraction at all. However, one has to learn to leverage abstracted-away stuff, otherwise one will spend a lot of time and accomplish very little valuable stuff.
> trust me it's way easier to control a single stack instead of managing a stack on top of another
Easier does not equal safer, faster, or more business-valuable.
> it's cool and easy / shiny if you can have everything in the cloud
Not sure where "the cloud" enters the equation? You can use Docker (or whatever else) to manage even your on-premises stack.
---
I don't know the specifics of your situation at all, but if your only argument against a particular piece of tech is "it abstracts away stuff, therefore it is worse", you might want to consider some self-reflection on whether you're not just suffering of NIH Syndrome (https://en.wikipedia.org/wiki/Not_invented_here)
https://github.com/docker/docker/issues/13490
It's not 'secure by default' if secrets are flying around through the system with no formal way to prevent it.
If you're playing to the 'secure by default' crowd, they aren't going to just trust that you're on the case if you don't communicate. Platitudes are something people watch out for when security is on the line, and they'll chose another solution if they think you're full of shit.
You have to show, at all times and all things, how you're thinking about the problem. 15 months of dead air is a lot to atone for.
However, where is image signing? Where is pulling images by their hash instead of mutable tags? Where is restricting what images run according to their hashes? Where is Docker not running a daemon as root? How about Docker doing more hardening releases and fewer feature releases?
There's a lot of low hanging, security related fruit which haven't been picked. Why not?
Process isolation is a fantastic. There just really needs to be more, in my opinion.
The coolest bit here is to be able to do threshold signing. Essentially k-of-n signing for containers and verification gates that only allow containers with enough signatures in order to deploy. For some more background check out the blogpost here: https://blog.docker.com/2016/08/securing-enterprise-software...
Disclaimer: I manage security at Docker.
> "Secure by default" is a great philosophy to have. I hope Docker continues to push into this direction.
Thank you. We will absolutely keep pushing.
> However, where is image signing?
Docker supports image signing out-of-the-box. It's based on TUF which is the state if the art in secure content distribution. Along the way we open-sourced our underlying TUF implementation so thaf others can reuse it: https://github.com/docker/notary
> Where is pulling images by their hash instead of mutable tags?
That's also available out of the box: "docker pull NAME@DIGEST"
> Where is restricting what images run according to their hashes?
That's not available out of the box, but a popular way to implement it is to funnel images through a trusted private registry, only allow pulls from that registry, and then controlling what you push to it.
Another possibility is to use the new auth plugin system, although I haven't tried.
> Where is Docker not running a daemon as root?
Docker runs unprivileged by default, but only on relatively recent kernels with user namespace support (it drops itself to "fake root" so it can still create containers without actually having uid0).
On older systems (or if you don't trust user namespaces) I agree we could break up some parts of the daemon (for example push/pull) to drop privileges further. That requires serious refactoring which we have been working on gradually for some time.
> How about Docker doing more hardening releases and fewer feature releases?
We follow the linux methodology: every release includes many hardening improvements, as well as whatever features have been deemed stable enough to merge. We don't control what pull requests the community sends, but we work hard to maintain a high quality bar and encourage quality-oriented contributions. The Docker core engineering team invests more time on hardening than features.
> There's a lot of low hanging, security related fruit which haven't been picked. Why not?
I'm sure there are :) Security is a process, we will never be done. The important thing for us is to take it seriously, invest appropriately (Docker core team employs 6 full time security engineers and funds various third-party security efforts), and make sure we are perpetually improving.
On top of that, Docker is known for making powerful technology more accessible to more people. We want to use that "superpower" to make security more usable by non-experts. We think that contributes to making everyone more secure.
> Process isolation is a fantastic. There just really needs to be more, in my opinion.
Docker security is about much, much more than process isolation.
Thanks for the feedback. We hope to see you on the github repo, we value bug reports :)
Sounds great in theory, but there hasn't been much traction on that project, at least from their own website, for over 6 months. Not much in terms of peer review of their method, or practical audits of their technology. Even your own audit is over a year old now, despite constant changes to the codebase.
That said, I do recall now when this was announced originally, and I'm glad that it at least exists. That it has skipped my memory makes me wonder why there has been little to no press about it since then. How broadly adopted has this been? Can we get signed images for, say, Ubuntu from docker hub?
> docker pull NAME@DIGEST
A great feature to have. Can you point me at the digest for the ubuntu repo on docker hub?
> serious refactoring which we have been working on
Good to hear. Also, interesting to note that runc still requires root access to make cgroups; I was not aware of this restriction.
> The Docker core engineering team invests more time on hardening than features.
I find this to be an interesting position to take, considering that a core component of docker has been historically re-written with every other release: registry in 1.6, disk plugins in 1.7, networking in 1.9, runc in 1.11. IIRC, networking was re-written again in 1.12, to support yet another version of clustered networking. That's a lot of churn for less than a year and a half worth of time.
> We hope to see you on the github repo, we value bug reports
That hasn't gone well for me in the past.
devicemapper errors in ubuntu 14.04, prior to dynamic linking: not our problem.
devicemapper dropping mounts sporadically: move to overlayfs.
Low level mutexes being shared between containers: that's nodejs' problem.
It's frankly become easier to create and use workarounds like spam-unmounting orphaned devicemapper mounts, or custom-compiling and distributing docker, or disabling docker-managed networking, and so on.
I feel bad for ragging on Docker like this, especially since I do end up using it frequently; but as a system administrator Docker is a nearly daily headache. Our developers love it, but the rest of us... not so much. I guess it's one of those "technologies everyone complains about" vs "technologies nobody uses" things. It's just really frustrating.
However, there's some usability problems here that I'd like to bring to your attention:
- There is no indication that the pull is different; no output from trust verification that it is indeed signed. This means I have to trust that Docker did the right thing, with no means of verification.
- Inspecting the image after pulling gives no indication that the image is signed, and gives me no way to do my own signature validation on the image.
- It does fail properly when pulling an unsigned image. Yay!
- Docker run initiates a connection back to notary, and fails if it can not connect. This makes me uneasy - it makes me wonder what data is passed, how it's being used, what changes are being made according to the response, and so forth.
- Using trust is a per-command decision, instead of a daemon setting.
- There's no clear method to revoke a signing key if identified to be malicious.
- This seems like a good candidate for "secure by default" once some of the usability issues are resolved.
To be fair, runC was its own project for quite some time. Docker just switched from importing the runC code to actually running the binaries through containerd as a proxy in 1.11 (a design decision I'm still trying to wrap my brain around, but that's a separate issue).
> Docker runs unprivileged by default, but only on relatively recent kernels with user namespace support (it drops itself to "fake root" so it can still create containers without actually having uid0).
Is that right? As far as I'm aware, runC doesn't have support for anything like that (and Linux's method of handling network namespaces under an unprivileged user namespace doesn't allow you to even have a network connection to the outside world). Sure, in runC we're working on rootless containers, but that's a while away from being done and Docker might not ever be able to support rootless containers completely (since it needs to handle networking and some other things that still need some quite significant kernel work to complete).
edit: found the link - https://docs.docker.com/engine/reference/commandline/dockerd...
I don't want to criticise Docker here from a security perspective - several security features in rkt are based on the implementation in Docker, and running your apps isolated under Docker is definitely more secure than running them all on the same unconfined host.
(Disclaimer: I work at CoreOS, though not primarily on rkt)
One of the big challenges with the containerization landscape is keeping up with changing product capabilities as there's a lot of movement all over the place.
Gartner is like a financial ratings agency. I wouldn't rely on their recommendation if I were concerned about the security of any application or platform.
the other thing to note is that when deploying Docker engine the defaults tend to go towards making everything work and aren't necessarily the most secure, so its very much worth doing some additional hardening where possible.
Specfically things like
- enabling user namespacing
- disabling icc
- removing capabilities (e.g. NET_RAW)
- not using the default docker0 network
- disabling userland proxy
There is a CIS standard which is pretty much up to date and has some, hopefullly, decent sets of things to look at hardening (disclaimer I helped work a bit on the latest version...)
Looks like Docker have put out a content scanner service to mitigate the problem this still seems to be a weakness relative to the pre-Docker way of building VMs.