Anchore Security Policy Bundles and Container Security Fundamentals
Recently, I’ve been talking a lot about how to install Anchore and use it to provide container security, but my focus has largely been on the integration between Anchore and the other parts of your software development and delivery lifecycle. This week I begin a new series talking about Anchore Security Policy Bundles, the mechanism by which you set the controls that determine which containers are secure and which are not.
For more details on the security policy bundles and Anchore, check out these documents:
- Policies: https://anchore.freshdesk.com/support/solutions/articles/36000074706-policies
- Policy mappings: https://anchore.freshdesk.com/support/solutions/articles/36000075104-policy-mappings
- Policy bundles and evaluation: https://anchore.freshdesk.com/support/solutions/articles/36000074705-policy-bundles-and-evaluation
- Anchore Engine overview: https://anchore.freshdesk.com/support/solutions/articles/36000020381-overview
Anchore Security Policy Bundles
A policy bundle is a JSON document that consists of several sections to effectively build a complete set of security policies. You can have many security policy bundles, but when evaluating images in the Anchore Engine, you specify the bundle to use or default to the currently active one.
The main section of the polcy bundle is the policies section which contains named sets of rules and actions. These are the main controls that will determine whether an image will be stopped, a warning will be issued, or the image will pass. There are a wide range of rules that you can specify that address a number of different security aspects which I’ll talk about in a moment.
Another section of the policy is whitelists, which allow you to specify exclusions to the rules set in the policies. Policies in general will be relatively broad in order to ensure that the security threshold is kept high, but there will always be exceptions, and the whitelists provide a way to specify the exceptions. This makes logical sense, as you would rather have your security policy be a little strong and have to make exceptions rather than having it be too loose and having to deal with issues getting through.
The mappings section of a bundle is how you map images to policies. There are three fields for the mapping, registry, repository and image (the registry is the server where images are held, the repository refers to the collection of images with the same name, and image in this case refers to a particular tag or version). You can specify specific values or wildcards interchangably for all three fields, giving a wide range of scope for the mapping. For the matching registries, repositories, and images, you can specify one ore more policies and one or more whitelists.
Finally, policy bundles also allow you to specify specific images (specific combinations of registry, repository and image) to always pass via a whitelisted images section or to always fail via a blacklisted images section.
So what kinds of rules would you put into security policies? There’s a lot of different aspects to consider, and it helps to look a little deeper into the subject of container security.
Containers by their very nature provide some security that doesn’t exist for processes not running in containers. Two Linux kernel features, cgroupsand namespaces, are key parts of what make containers work, and the original intention of containers was to put extra controls around processes. The cgroups part limits how much access processes get to resources like CPU, memory, and I/O, and namespaces gives container processes their own set of resources like files, users, pids, and hostnames.
Although these features can make containers seem like virtual machines, there are some important differences. The processes running inside of those containers use the same kernel as processes running outside the containers. This actually makes containers less secure than virtual machines, as an attack that compromises a virtual machine is not able to affect the host (having said that, some platforms that host multiple virtual machines do have the issue that a compromised virtual machine can affect other virtual machines running on the same platform).
Container processes are also still subject to a lot of the same security issues as processes not running inside containers. Even if the process is controlled inside a container, if someone can compromise it, they may still be able to access sensitive data, start a denial of service attack, or use the container to launch attacks on other systems. The controls that cgroups and namespaces provide can’t limit all the possible types of attacks that exist. So clearly, we need to address the issue of software vulnerabilities.
Software is typically built upon a lot of common core libraries and frameworks. When a vulnerability is discovered in one of these core libraries, it can have massive impacts on the security of all of the software that depends on it. As of this writing, common vulnerabilities and exposures, known as CVEs are being found at a rate of over 40 a day. Over 90 organizations known as CVE Numbering Authorities report issues that are gathered together into databases so that everyone can be aware of these issues.
You could stop using any software that had any known CVEs, but that would be really difficult. A lot of common core software has known vulnerability issues, but most critical issues are patched within a matter of weeks, and the remaining issues are generally less severe or apply in much rarer cases. Vulnerability-free software unfortunately is the exception rather than the rule, so just trying to steer clear of vulnerabilities is not likely going to work.
Instead, the better approach is to be aware of the software that has vulnerabilities and define policies that determine whether the software with these vulnerabilties are safe to use or not. The reports that used for detailing CVEs contain important information such as how attacks are waged, how complex the attack is, whether the attacks can expose sensitive info, and whether software exists to automate the attack. It would be really great if the process of evaluating these reports and generating policies could be automated, but it is unfortunately a really hard problem and generally will require analysis from experts in the field of security.
Other Security Concerns
There are other security concerns to be aware of besides vulnerabilities. Containers are created from images that are built and often made available to a large audience. Any confidential data stored inside container images can also be a security issue, and doesn’t require an attacker to use any special attacks to get the information if the images are easily available. Passwords, authorization tokens, ssh keys and other senstivie files sometimes get included in a built image without realization that this could pose a security threat.
Another key component of security is really keeping privileges to the least amount required. What user you run your process in a container can affect the level of security pretty dramatically. For example, Docker doesn’t namespace users by default, so if you specify that you want to run the container as user root, it will be the actual root user of the host. This means that system calls executing on the kernel will be root, which could allow that process to bypass some of the controls enforced by cgroups and namespaces.
Finally, some companies have stricter than normal controls around permitted software. This can mean that some libraries and packages may not be allowed, even if they don’t have critical CVEs. You may want to be enforcing that the most recent versions are always in use. There could be limitations on the types of licensing that you need to check for.
OpenShift and Other Container Platforms
A lot of us don’t just run containers using Docker directly. We utilize container platforms like OpenShift or Kubernetes. Do these platforms provide solutions to some of the security concerns I have talked about? The answer is both yes and no.
I talked above about how software running inside containers can have vulnerabilities. No matter where you run a container, if it is compromised, you will still have to deal with possible issues of data compromise, trustworthiness of the system, and possible attacks on other components. OpenShift does have controls that prevent running containers as root, so there is some additional control there, but not all attacks require elevated access. These platforms can provide additional network security controls which can contain the attacks, but they can’t necessarily eliminate them.
OpenShift and other container platforms also don’t necessarily have controls in place to limit what is inside the container image that you want to run. If there is sensitive data inside the container, OpenShift isn’t necessarily going to check for that. As I wrote in a previous article, there are some upcoming methods in Kubernetes and OpenShift by which you can call out to external systems to do the checks, but they aren’t built in.
This is largely why we still need a container image scanning solution like the Anchore Engine. It allows us to complement the security controls in these platforms by ensuring that the images that will be running on them are secure according to policies that are really flexible and comprehensive.
In this article, I have talked about Anchore Security Policy Bundles which allow you to specify rules, whitelists and blacklists to address security concerns when evaluating images in the Anchore Engine. I talked about how containers provide some security controls, but still have issues with software vulnerabilities and other security concerns that may be less obvious. Although container platforms like OpenShift and Kubernetes have security controls in them, it is still better to complement them with image scans that can secure the images before they are put into containers.
Next week, I’ll be expanding upon this by building out a security policy bundle and discussing the specifics of the bundle to address some sample use cases.
Originally published on September 24, 2018.