A few years ago, containers were an obscure technology. They allowed us to isolate applications from the operating system without using virtual machines, but they also required a bleeding-edge kernel, and sometimes, even custom patches to that kernel.
Today containers are mainstream, and all the large players support them. Although the technology is Linux-centric, they are even supported natively in recent versions of Microsoft Windows. In other words, containers are ubiquitous. But are there any security implications for using them?
In this article, we’ll explore the security challenges containers can bring, and how to address them.
So What Exactly Are Containers?
Containers are standardized units of software packaging. Just as shipping containers revolutionized logistics, software containers are changing the way we think about deploying software. Instead of provisioning machines, installing applications, and configuring them, you now simply move containers from one place to another. They contain everything the application might need: a runtime, a configuration, and an application.
Containers all look the same, and they present the same interface. Whether an application is in Python, Node.JS, or C++, the exact same commands will run it. Currently, the most popular container tool is Docker. (Here’s an introduction to Docker.)
The popularity of containers is also connected with microservices architecture. True, you can achieve this pattern without using containers, but it’s simply more convenient to isolate all the processes at the container level. When each process functions on its own, it’s easier to avoid tightly-coupled solutions.
Are Containers Secure by Design?
Some say containers are secure by design. After all, each process lives in its own namespace, without access to the underlying operating system or processes inside other containers. Everything is isolated and protected at the kernel level against breaches.
But does this mean that when you use containers, you don’t have to worry about security? Not quite! Perfect isolation applies only to perfectly standalone applications , with no interfaces to other services, and no network traffic flowing in or out. Even if such an application were possible, it’s obviously not relevant to a typical use case.
Containers should be more secure than applications running in a common namespace. But this doesn’t mean you are fully protected. There are still potential risks you have to take into account.
How Security Is Threatened — and What to Do About It
To think of the security threats that containers may pose, we need to examine the applications they host, and the ways in which they might be vulnerable to compromise.
First of all, can you trust the runtime the application uses? What about its various dependencies (like NPM packages or Python libraries)? And how well is the application itself protected? Malicious code injected into popular third-party components is nothing new. One article highlighted how easy it is to upload such code to the public repository.
The security of your system is only as good as its weakest element. Even though the operating system may be hardened, and the containers protect processes from one another, one exposed endpoint can ruin everything. This often occurs from human error: for example, forgetting to close ports that were left open during development, or that were originally planned to be exposed but no longer need to be, due to subsequent design changes.
As a general rule, the ways that an application is allowed to interact with its surroundings should be minimized, to limit the damage that would be possible if the application were ever compromised. One important aspect is file access. Applications should have access only to those files to which access is necessary. (And auditing them regularly isn’t a bad idea either.)
Another important aspect is how the application communicates over the network.
Network interfaces between containers and the outside world can create security holes. But you can limit access to those interfaces, and you can protect the traffic as it’s transmitted. For example, only required ports should be left open.
Another best practice is to always protect the traffic with TLS, both internal and external. Not only will this make eavesdropping difficult, but you can also authenticate two services against each other.
Understanding the network flow of microservices is crucial to making them secure. Logging and analyzing the traffic can help you spot malicious access attempts. In order to do this, you should be able to differentiate regular traffic from suspicious traffic. In short, the more you know about your application, the better you can protect it.
The Container Lifecycle
Another area of focus, after application and networking, is the container’s lifecycle. Building images, storing them, and deploying to the target environments pose their own risks. The best solution is to keep as little of the original operating system inside the container image as possible. Ideally, your statically-linked application will be the only binary available. If that’s not feasible, consider minimalistic operating systems designed with containers in mind. Remove every binary that will not be used by your application. This reduces the attack surface.
For storing images, a tool called Notary may be helpful. It eases the process of cryptographically signing and verifying container images, just like you would with native Operating System packages.
Orchestrators and Security
The topic of containers often goes together with the topic of orchestrating workload. In general, an orchestrator’s role is to make sure the appropriate services run in the necessary quantity. This generally requires managing the workload across a number of different machines.
Among the most popular orchestration engines are Kubernetes, Rancher, and Docker Swarm, which offload some of the tasks for which you would normally be responsible. They make sure the services are connected, monitor the containers, and restart or scale them according to your needs.
But this increased convenience doesn’t mean you can lower your guard. All of the previous pieces of advice are still relevant. What’s more, you’ll also have to protect the API access to the orchestrators themselves. The good news is that Kubernetes offers a Role-Based Access Control (RBAC) with secure API endpoints and different privilege levels. You can treat it as another weapon in your security arsenal.
How the Cloud Can Help
When containers are used to run applications in the cloud, this simplifies many of the security issues discussed above.
For example, cloud applications naturally lend themselves to using microservices, with all the advantages that they bring. For better isolation, they can use VPCs. For connectivity, they can use VPNs, which adds another layer of protection. For orchestration, many cloud providers offer managed solutions to do the initial cluster setup for you, with features such as secret management which would normally require a standalone setup.
Of course, containers still offer benefits even when used on-premise. But in-cloud is where they really shine, and as time goes on, more (exclusively) cloud-native tools are becoming available.
Conclusion: The Road to Security
Containers offer many advantages. Although they include a few new security issues, these are not severe. Addressing them carefully will allow organizations to enjoy the numerous benefits of containers, without adding security risks. This can be especially true when containers are used in the cloud.
However, this does require careful consideration of the providers you choose for protecting your containers (or web assets in general). Cloud platforms do not all provide the same level of security. In fact, there are significant differences among them.
When evaluating a cloud security provider, ask if that platform offers features such as cloud-native security, DevOps and DevSecOps support, single-tenant Virtual Private Clouds for each customer, API schema ingestion and enforcement, adaptive threat detection via machine learning, and accurate multivariate bot detection and mitigation. These are some of the features that will help you to distinguish among platforms.
At Reblaze, we not only protect cloud-native customers, we’re a cloud-native shop ourselves. We’re happy to answer any questions you might have about containers or other related issues.