7 Security Recommendations

Ensure that your infrastructure and containerized applications remain secure by following security recommendations and guidelines. Oracle recommends that in addition to the information provided here, you review upstream security guidelines such as those provided at https://docs.docker.com/engine/security/.

Best Practices for Docker Components

It is important to follow security guidelines at all levels within the infrastructure for an environment to best mitigate against exploitation. You should follow the best practice guidelines for each component at play within the environment.

Note that while containerization provides resource separation between applications running on the same host, the separation is not complete and it is possible to break out of a container or to exploit a container in such a way that it could affect other containers running on the same host. If you have different tenancies within your organization or if you have different customers that are using the same infrastructure, it is imperative that their containers run on different hosts or on different virtual machines to achieve more complete separation and to prevent the likelihood of a serious data breach.

Host

  • Regularly update the host kernel and operating system software

    Oracle regularly releases security patches and bug fixes for the kernel and operating system software as issues are resolved. It is highly recommended that you keep the operating system current with the most recent software updates. Subscribe the system to the latest software channels or repositories; run regular yum update operations; and consider using Ksplice to keep your system software up to date.

  • Use a minimal operating system and ensure that it is following security best practices

    Where possible, use a minimal operating system installation and ensure that it follows the security best practices described in Oracle Linux 7: Security Guide. Most importantly, you should reduce the number of services running on the same system. Ideally, move all other services to reside within containers controlled by Docker or move them to other systems entirely. This helps to contain damage in the event of container breakout.

  • Regularly scrutinize the operating system and kernel for safety

    Be vigilant that the operating system is regularly scrutinized for safety and potential vulnerabilities.

  • Use a mature kernel that provides the best possible security feature set

    Oracle requires that you use UEK R5 or later with Oracle Container Runtime for Docker. This helps to ensure that kernel-based features such as kernel namespaces, private networking and control groups are mature, reliable and heavily tested. Since the kernel capabilities that are required for Docker are equally required to support other tools and features such as LXC (Linux Containers), the required kernel capabilities are all tested regularly within the supported UEK releases.

Docker Engine

  • Restrict who can create and control containers using the Docker engine

    The Docker engine is typically run with root privileges on the host system. You must, therefore, restrict who can create a new container on a system, or who has access to the Docker engine to start a container. Some operations, such as loading or pulling images could be potentially exploited through other inputs. Make sure that the users that have access to perform actions using the Docker engine are all trusted users.

  • Regularly update the Docker engine software

    As with all software on the operating system, regular updates are critical to ensure that you are running the latest security patched binaries.

  • Use current recommended drivers

    Do not use the legacy LXC driver. Oracle strongly recommends using btrfs-based storage in production environments. OverlayFS is acceptable for testing purposes, but developers are cautioned that there are known issues due to its lack of maturity. The default device-mapper option is not recommended as it is very slow and prone to running out of space inside the container.

  • Minimize Docker engine client ports

    Run the Docker Daemon with only the single default Unix socket port if possible. If other sockets must be used, configure them for TLS.

  • Ensure sufficient storage capacity for Docker containers and images

    Docker stores container and image data in a directory (/var/lib/docker by default). This space may fill up fast, so to prevent denial-of-service of Docker, the containers, and the Docker host, ensure sufficient storage capacity.

    Create a separate partition (logical volume) for storing Docker files.

  • Protect Docker service and configuration files

    Set appropriate permissions and ownership for service and configuration files to prevent unauthorized access. The default values are usually appropriate, but the following guidelines may help when performing and audit.

    Ensure that the following Docker engine system files have secure permissions set (owner/group is root:root and permissions are 644 or more restrictive):

    • /usr/lib/systemd/system/docker.service

    • /usr/lib/systemd/system/docker-registry.service

    • /usr/lib/systemd/system/docker.socket

    • /etc/sysconfig/docker

    • /etc/default/docker

    • /etc/sysconfig/docker-network

    • /etc/sysconfig/docker-registry

    • /etc/sysconfig/docker-storage

    Ensure that the following Docker engine system files have secure permissions set (owner/group is root:root and permissions are 755 or more restrictive):

    • /etc/docker

    Ensure that the following Docker engine system files have secure permissions set (owner/group is root:root and permissions are 444 or more restrictive):

    • /etc/docker/certs.d/<registry-name>/*

    • TLS CA certificate file (the file given with the --tlscacert parameter)

    • Docker server certificate file (the file given with the --tlscert parameter)

    Ensure that the following Docker engine system files have secure permissions set (owner/group is root:root and permissions are 400 or more restrictive):

    • Docker server certificate key file (the file given with the --tlskey parameter)

    Ensure that the following Docker engine system files have secure permissions set (owner/group is root:docker and permissions are 460 or more restrictive):

    • /var/run/docker.sock

  • Monitor and audit Docker system files

    Audit all Docker engine activities using a system logging facility like auditd. The service logging level should be "info" (default). Ensure enough storage space is available for audit logs to grow. Monitor the following files and directories:

    • /var/lib/docker

    • /etc/docker

    • /usr/lib/systemd/system/docker-registry.service

    • /usr/lib/systemd/system/docker.service

    • /var/run/docker.sock

    • /etc/sysconfig/docker

    • /etc/sysconfig/docker-network

    • /etc/sysconfig/docker-registry

    • /etc/sysconfig/docker-storage

    • /etc/default/docker

Docker Images

  • Ensure that images come from verified and trusted sources

    Verify that Docker images are received and deployed unchanged from a source with a trusted reputation and which has been authenticated.

    When pulling images from remote sources, ensure that the connection is protected and that you are using HTTPS for the pull request. Do not use insecure image registries that are not protected by TLS.

    Ideally, you should pull images by pre-verified hash rather than by tag and if possble, export these images and host them on more secure media servers under your own control.

    Where possible, Docker images should come from and be based on a curated, trusted collection of image suppliers.

  • Create reliably reproducible images

    When using Dockerfiles to build new images, review base images and installed software for security. To help ensure that new images use base images and software that you have properly reviewed for security vulnerabilities:

    • Specify a fixed version in the base image in an image Dockerfile.

    • Specify fixed versions in package pulls in the build steps of an image Dockerfile (note that dependencies of dependencies can still be a reliability problem).

    • Ensure the that package pulls in the build steps are using trusted and verified sources

  • Minimize packages installed on images

    Do not install unnecessary packages into new image builds. Review Dockerfiles to remove unnecessary installation steps so that images remain limited to their function.

  • Use Linux security modules

    Within your images, use the appropriate security modules where possible:

    • Run SELinux on Red Hat distributions

    • Run AppArmor on Debian and Ubuntu distributions

  • Regularly update images

    Containers must be regularly scanned to detect out of date or unpatched software. Since containers must be immutable, you cannot patch the software, you must instead replace it with a newly built image. Consider rolling your own new patched image if you are relying on a third party image to be updated and you can't wait.

    Vendors tend to focus on the current stream of development. Instead of patching your containers and images, rebuild the images from scratch and instantiate new containers from the newer builds.

Docker Containers

  • Run containers as a non-root user

    Unless otherwise specified, Docker runs each container as root. Since the UIDs are shared across the host, the root user in a container is the root user on the host. When possible ensure that containers are started as a non-root user by using the --user flag. You can start a container to run as the current user by taking advantage of the id command. For example, use --user $(id -u):$(id -g) when starting a container.

  • Limit container memory and CPU usage

    Create and launch containers with limited container memory and CPU boundaries using the -m and --memory-swap options for memory and swap memory; and the -c option for CPU.

  • Limit container restarts

    To prevent potential denial-of-service resulting from a container that spins out of control, limit container restarts using the --restart=on-failure:N option when creating or launching a container.

  • Monitor container resource usage

    Docker provides facilities to monitor container resource usage, such as memory consumption, CPU time, I/O and network usage. Review container resource usage for performance, error detection and anomalous behavior. Consider using tools to monitor real-time resource usage for anomalous activity such as utilization of resources, suspicious traffic and unexpected user activity.

  • Limit container file access

    When creating and launching containers, limit container file access using the --read-only flag or the -v <host dir>:<container dir>:ro option. Explicitly create volume(s) for container applications to write in and monitor changes to files in these volumes. Ensure that volumes that are dedicated for container write access are reviewed for sprawl and are cleaned up regularly.

    Do not mount sensitive host system directories at container runtime:

    • /

    • /boot

    • /dev

    • /etc

    • /lib

    • /proc

    • /sys

    • /usr

  • Regularly review containers for safety

    Consider using tools that help to automate container safety checks and to monitor for changes within containers. For example, Docker Bench for Security (CIS) and Docker Diff can be helpful for this purpose. See https://github.com/docker/docker-bench-security and https://docs.docker.com/engine/reference/commandline/diff/ for more information.

    Systematically remove images and containers that are not needed from the host system to avoid image and container sprawl and to help prevent the accidental usage of an old, unused image or container that has potentially avoided security scrutiny.

  • Limit kernel capabilities in containers

    When creating and launching containers, limit kernel capabilities using the --cap-add and --cap-drop options. Note that you can set the value for either of these options to all. Try to apply the minimal set of kernel capabilities required by the containerized application.

    By default, the following kernel capabilities are granted to a container:

    • CHOWN

    • DAC_OVERRIDE

    • FSETID

    • FOWNER

    • MKNOD

    • NET_RAW

    • SETGID

    • SETUID

    • SETFCAP

    • SETPCAP

    • NET_BIND_SERVICE

    • SYS_CHROOT

    • KILL

    • AUDIT_WRITE.

    By default, the following notable kernel capabilities are removed from a container:

    • SYS_TIME

    • NET_ADMIN

    • SYS_MODULE

    • SYS_NICE

    • SYS_ADMIN

    Do not use the --privileged option when starting containers.

  • Limit kernel file handle and process resources in containers

    When creating and launching containers, limit kernel resources by using the --ulimit option or set container defaults using the --default-ulimit when starting the Docker service.

  • Limit container networking

    Limit container networking completely using the --icc=false option when starting the Docker engine if you do not need your containers to communicate at all. By disabling inter-container communication, no network traffic is allowed between containers, but they are still able to publish ports on the host.

    When publishing ports to the host, specify the IP address of the interface that you wish the port to bind to so that the attack surface is reduced to the network interface where the container should be listening. Docker publishes to all interfaces (0.0.0.0) by default if an IP address is not specified when using the -p or --publish option.

    Do not run SSH inside of containers.

    Do not map privileged ports (< 1024) inside of containers.

    Do not use the --net=host mode option for containers when they are started or run.

  • Do not share host namespaces with your containers

    Do not share host namespaces such as the PID or IPC namespaces when starting or running containers.

  • Do not expose host devices into containers

    Do not expose host devices into containers when you start or run them.

Containerized Applications

  • Minimize kernel calls in containerized applications

    Since the kernel is shared between containers, kernel calls increase risk to other containers running on the host system. Avoid kernel calls within containerized appliactions wherever possible.

  • Run Container applications as a non-root user

    Unless otherwise specified, Docker runs each container as root. Ensure that containerized applications run as a non-root user. Since the UIDs are shared across the host, the root user in a container is the root user on the host.

    If you ever need to change the user, consider using gosu instead of sudo because gosu creates a single process, instead of the two processes that sudo creates. This can avoid issues where container signals are forwarded. See https://github.com/tianon/gosu for more information.

  • Remove or minimize the use of setuid and setgid in containerized applications

    Most applications don’t need any setuid or setgid binaries. If you can, disable or remove such binaries. By doing so, you remove the chance of them being used for privilege escalation attacks. If you discover binaries that have setuid or setgid permission flags, remove them altogether or try to remove the permission flags to remove the risks that are associated with these permissions on a binary.

  • Design containerized applications to be impermanent

    As much as is possible, design applications to be stateless, rollable, instantly migrateable microservices container apps if possible. If using applications outside of your own design, take this approach into consideration when selecting software that you intend to run within your containers. This quality can be helpful in maintaining service during and in the time following a breach or accident in the system.

Additional Deployment and Development Tools

  • Avoid deploying or using development tools in production environments

    There are many development tools available that can aid in the use of Docker, including boot2docker, Kitematic, VMware Fusion, and Vagrant. Avoid deploying these to production environments to reduce the attack surface.

    Development tools are often less security hardened so avoid employing them in production environments.