Introduction
Container technology has radically changed the way that applications, are, being developed and deployed. Notably, containers dramatically ease dependency management, so shipping new features or the code is faster than the ever. While Docker containers and kubernetes are great for DevOps, they also present new security challenges Practitioners and developers must understand with diligence. Docker ' team's security experts has built some valuable security features to the Docker platform over the last several Years. This blog post offers up valuable tips and practical suggestions in how containers and hosts can is hardened as a St EP Toward a more secure container environment. A brief look at containers to security perspective
In essence, Docker containers are a wrapper around Linux control groups (cgroups) and namespaces. Cgroups are used in the Linux kernel for monitoring and restricting resources among a group of processes. Namespaces determine what a process can. For example, the PID namespace restricts which processes can be seen within a container.
Each container running on a host shares a common underlying kernel. Containers are isolated from one another, which–from a security standpoint–is advantageous. However, if the host OS is compromised, all containers running to it are at risk. Similarly, if a container is using a vulnerable library, it could being exploited to gain access to the underlying host.
Securing the Host OS
The underlying host OS needs to is secured in order to prevent container breaches from affecting the host. For this, the Linux provides several Out-of-the-box security modules. Some of the popular ones are SELinux, AppArmor and Seccomp. One can also develop custom security modules the using Linux Security modules (LSMS). SELinux
SELinux is a type of the mandatory Access control (MAC) security module based on type enforcement. Type enforcement revolves around defining a type and assigning privileges to those. Here's a simple example of the using an SELinux policy:
Policy_module (Localpolicy, 1.0)
gen_require ('
type user_t;
Type var_log_t;
)
Allow user_t Var_log_t:dir {getattr search open read};
This is allows any Linux process to execute file operations (such as GetAttr, search, open, read) for which user_t and Var_lo G_t are applied.
Even though SELinux is comprehensive that you can have a policy language is pretty hard to get right. Often users would end up creating different SELinux policies the over time to address different scenarios. AppArmor
AppArmor is another MAC solution. It is based on file system paths rather than defining types. Users can specify a file path to a binary and the permissions they have. Here's a simple example of confining Nginx:
#include <tunables/global>/usr/sbin/nginx {#include <abstractions/apache2-common> #include <abstrac Tions/base> #include <abstractions/nis> capability dac_override, capability Dac_read_search, capability n Et_bind_service, capability Setgid, capability setuid,/data/www/safe/* R, deny/data/www/unsafe/* R,/etc/group
R,/ETC/NGINX/CONF.D/R,/etc/nginx/mime.types R,/etc/nginx/nginx.conf R,/etc/nsswitch.conf R,/etc/passwd R, /ETC/SSL/OPENSSL.CNF R,/run/nginx.pid RW,/usr/sbin/nginx Mr,/var/log/nginx/access.log W,/var/log/nginx/erro R.log W,}
This apparmor profiles blocks reading from unsafe directories. It May is suitable for all situations; Users may have to customize it. AppArmor is good a for restricting application access. However, it requires a learning curve to is able to write good enforcement profiles. Seccomp
Seccomp (short for ' Secure Computing ') are another security module included in many Linux distributions that allows users T o Restrict system calls. Users can specify custom actions to was taken when a certain system call is executed. The actions are allow, kill, err, and trap. Seccomp can be used to sandbox applications this handle untrusted user inputs to a subset of system calls.
The the "the" in using Seccomp are to determine the system calls a application makes when it runs. This can being a difficult and error-prone exercise that should being conducted the application is written. Users can use tools like audit to profiles all the system calls this it makes by exercising it in different ways.
SECCOMP policies are defined using JSON files. A Sample Seccomp policy looks like this,
{
"defaultaction": "Scmp_act_allow", "
syscalls": [
{
"name": "MkDir",
"action": "Scmp_act_ ERRNO "
},
{
" name ":" Chown ",
" action ":" Scmp_act_errno "
}
]
}
This policy causes a error to is returned when mkdir or Chown are.
The drawback with Seccomp are that the profiles has to be applied during the launch of the application. The granularity of restricting system calls is too narrow and requires extensive, working of Linux to knowledge up come H Good profiles. Capabilities
The Linux capabilities are groups of permissions that can is given to the child processes. Child processes cannot acquire newer capabilities. The idea behind capabilities are that no process should have all privileges, but instead, have only enough privileges to PE Rform their intended service. By bootstrapping processes with limited privileges, we can "contain" the damage this can occur if they are ever compromise D.
Some capabilities give excessive privileges to processes such as:
Sys_admin:this gives processes many privileges, some of which are the only to the root user.
Setuid:many of the Linux distributions ship binaries This run with the SETUID bit set to give root privileges by default. Instead of setuid bit, they can is replaced with capabilities to provide more granular privileges.
These options work are on the host OS, but it can is challenging to adapt them for containers. Let's look in some of the relevant attack surfaces and practical ways to secure the Docker container.
Container Runtime Security Practices
There are various factors to consider when adopting Docker for containers. When it comes to running Docker container securely, the users can follow these recommendations. Unix sockets (/var/run/docker.sock)
By default, the Docker client communicates with the Docker daemon using the UNIX socket. This socket can also is mounted by the any other container unless proper permissions are into place. Once mounted, it is very easy to spin up any container, create new images, or shut down existing containers.
Solution:set up appropriate selinux/apparmor profiles to limit containers the this socket. Volume Mounts
Docker allows mounting to sensitive host directories. Also, the contents of the host file system can is changed directly from the container. For application containers with direct Internet exposure, it are important to are extra careful when mounting sensitive host Directories (/etc/,/usr/). Any breach can leads to damaging data loss.
Solution:mount host-sensitive directories as read-only. Privileged Containers
Privileged containers can do almost anything a host can do. It runs with the all capabilities.
Solution:use capabilities to grant fine-grained privileges instead. SSH within Container
Running SSH service within containers makes managing SSH keys/access policies. This should is avoided if possible.
Solution:do not run SSH services inside a container. Instead, run SSH on the host and use Docker exec or Docker attach to interact with the container. Binding Privileged Ports
By default, the Docker allows binding privileged ports (<1024) to a container. Normal users cannot access these ports. In many cases, mapping HTTP port and HTTPS port 443 are necessary for running servers in a container.
Solution:list all containers and their port mappings using the code below to ensure, the container ' s ports are not MA Pped to host ports below port 1024.
Docker PS--quiet | Xargs Docker Inspect--format ' {{. ID}: ports={{. Networksettings.ports}} ' exposing Ports
Ports not necessary for the service must is exposed.
Solution:list all the containers and their exposed ports using the following:
Docker PS--quiet | Xargs Docker Inspect--format ' {{. ID}: ports={{. Networksettings.ports}} '
Ensure that there are no unnecessary ports exposed. Running without default Apparmor/selinux or Seccomp
Docker runs containers with default Apparmor/selinux and Seccomp profiles. They can be disabled with the--unconfined option.