Container Security Best Practices
Most people think containers are less secure because if the host kernel has vulnerabilities, all the containers running on it are vulnerable. This is true, but it is also true for the hypervisor technology used for hosting VMs. One of the practices that developers and vendors do is signing their images to prevent untrusted containers from being deployed.
Most of the Linux distributions are too feature-heavy. Some distributions are specially developed for running containers like CoreOS, RancherOS, Photon OS, Project Atomic Host, and Ubuntu Core. Docker can also run on Windows or cloud platforms like Amazon EC2, Microsoft Azure Virtual Machine, Google Compute Engine, and Rackspace.
Container Threats according to OWASP
- Insecure User Mapping (containers run privileged)
- Outdated software (container images, host, orchestration tool)
- Network Segmentation and Firewalling (use white lists)
- Maintain Security Contexts (do not mix dev and prod or front end and back end)
- Resource Protection (limit resources, use r/o mounts)
- Follow Immutable Paradigm (create only read-only containers)
- Secrets management (don’t hard code secrets)
- Hardening (Harden container images, orchestration tool, and host)
- Logging (log everything)
- Image integrity (sign images and use signed images)
Top 10 Docker Security Best practices:
The best practices are ordered according to the procedure of the creation of containers.
- Harden, the host/ use a container optimized OS
Use an OS that is optimized for containers that have only the tools that are needed for running containers.
- Don’t store secrets in configuration files (Dockerfile) or environment variables
Some containers need credentials to access services like APIs, databases, etc. Don’t store secrets like passwords, API keys, etc., in Dockerfiles or environment variables because they are easy to capture for malicious users. If an attacker gets access to the secrets, he/she can use them to access the service used by the container.
Here is an article about what happened to IBM because they left TLS keys in containers.
- Harden images
Hardening the images reduces the attack surface, and the system has fewer weak points. An image should contain only the software that is used. By using a hardened OS, the attack surface becomes even less.
- Scan the images for known vulnerabilities and malware
Images should be scanned for known vulnerabilities to avoid compromise and mitigate the vulnerabilities in time.
- Sign the images
Images should be signed in to avoid image spoofing.
- Run containers as a non-root user
Privileged containers have access to all namespaces on the host. It means that the container has full control over the host.
- Set read-only root file system
By setting the read-only root file system, the tempering threat is mitigated. A read-only filesystem means that even if the container is compromised, the attacker will not be able to modify any file on the host.
- Limit the resources used by containers
Containers should have a limited amount of resources that they can use. By limiting the kernel resources, threats like denial of service are mitigated.
- Use Seccomp and AppArmor/SELinux
Seccomp is used to filter for what a container can do, specifically system calls. It is like a firewall for the kernel call interface. AppArmor is a security module available on Debian and Ubuntu, and SELinux is available on CentOS, Fedora, RHEL, and Oracle Linux. Both allow defining actions (network operations, reading files, etc.) and targets (files, protocols, IPs). Both should be enabled on the host.
- Monitor containers during runtime
Container runtime security is the last layer of security for containers. By monitoring container anomalies during runtime, 0-day attacks could be detected that can’t be detected by static vulnerability scanning.
Top 10 Kubernetes best practices:
- Upgrade always Kubernetes to the last version
By regularly upgrading to the latest stable version of Kubernetes, new security features and bug fixes are applied, and potential known vulnerabilities are mitigated.
- Control network access to sensitive ports/ limit access to Kubernetes API
Control who has access to the Kubernetes API; most applications don’t need access.
- Enable Role-Based Access Control (RBAC)
Enable RBAC if it is not enabled by default and disable Attribute-Based Access Control (ABAC).
- Use namespaces to isolate different components
Better separation of the components is achieved by using namespaces. It is easier to apply security policies like network policies when all the components are separated in namespaces.
- Create network security policies for the cluster
Network security policies allow controlling inbound and outbound connections of the components in the containerized environment.
- Scan container images
Regularly scanning container images will make sure that there are no pods with known vulnerabilities.
- Create a pod security policy
A pod security policy is used to set defaults of how pods should run in the cluster. By dropping some of the capabilities, certain classes of attacks can be defeated. For example, by dropping the NET_RAW capability, some network spoofing attacks are mitigated.
- Encrypt ETCD files
Encrypt the ETCD files to avoid information disclosure in case the cluster gets compromised
- Enable access logs for all API requests.
Logging and monitoring the API requests will help detect live attacks and perform forensics.
- Monitor pods during runtime
By continuously monitoring the pod’s anomaly behaviour, zero-day vulnerabilities can be detected.
In conclusion, Docker containers are quite secure by default, especially if the services running on them have non-root privileges. An extra layer of security can be added by enabling AppArmor, SELinux, or any other hardening system.
Kubernetes can be insecure if it is not configured properly or has known vulnerabilities. The best way to keep it secure is to apply best practices and always upgrade it to the last stable version.