For the past year and a half, I’ve been working in two teams in Information Services at OSU as a student developer. My first year in SIG (Shared Infrastructure Group) gave me an opportunity to work on the open source CoprHD project and regularly collaborate with the community members and the developers from the industry. As the team leader, besides the work assigned to me, I was also responsible for tracking the progress of my team members, assuring the on-time delivery of the features. Giving presentations of our work based on different purposes to the audience from various backgrounds was another important part of this project.

My role in the second team was one of the developers in the team. This team involved more diverse tasks allowing me to grasp many skills in a short period. Similar to the previous work, presentations were also frequent activities. Team members share knowledge through demoing or explaining the work to the team members. On the other hand, I went through several interviews for the past year, which gave me a sense of desired skills in the industry. If I look back to the experiences of interview processes and my job, there are some tips I could share with the students who want to be developers, and some of which I wish I could have done better.

Communication Skills

I know this might sound cliche, but it is one of the most highly effective skills that can help you reach your goal whether to get the work done or the help you need. Specifically, being able to ask questions wisely will bring you the answer you need, reduce avoidable mistakes or get out of the tar pits. In addition, communication over emails is another routine. A clear and concise email not only shows your professionality but also leads up to prompt replies.

Moreover, as described above, presentations are commonplace at work, so being capable of showing your work through the presentations is not just desirable but also necessary. During interviews, it’s very likely to be asked to introduce the projects you have done, while at work it’s even more frequent to demonstrate your work/ideas to your team or even a larger audience. Therefore, capable of delivering your thoughts clearly or even vividly will be a big plus in the job market.

Technical Skills

Technical skills are your core competencies, and it’s very critical to keep strengthening the skills you already have. Further, being able to learn new skills and learn them quickly on demand might be even more valuable. It is very common that you are not familiar some of the techniques used in your project, which can be a programming language, a framework or a tool. Being able to grasp the knowledge and applying them to the project is also a demonstration of your ability to work.

Another suggestion is to be aware of your thought process and try to identify and form the most efficient one for yourself. The thought process, such as how you learn things, how you debug and how you figure out a problem will change over time along with your experience. And an awareness of the changes will help you improve your efficiency, which is also helpful for your interviews since a lot of interviewers will try to identify your thought process from the way you answer their questions.

Additionally, putting down the notes for the work you have done is one of the things that I wish I could have done better. No matter how confident you thought you would remember the work, after leaving it aside for couple months or even weeks, everything will look completely new to you.

In a nutshell, technical skills and the communication skills are the way to becoming a professional developer. I believe if one could continue enhancing the skills discussed above and be able to show them to the employers, he/she will be a strong hire in the job market.

This article summarizes the current security solutions for  Docker containers. The solutions in this blog post have been discussed and designed by the Docker community. You can also find valuable tips on how to enhance security while running a Docker in a production environment.

Possible Security Issues in a container-based environment

Before we jump into the security solutions, let’s explore some security issues of container-based systems. Generally speaking, there are three types of attack models, which are caused by the vulnerabilities of the container-based systems.

Types of Attacks:

  • Container compromise: result in illegitimate data access and affect control flow of instructions
  • DoS(Deny of Services): disturb normal operation of the host or other container
  • Privilege escalation: obtain a privilege which is not originally granted to the container

Disclosed Vulnerabilities:

  • Namespacing Issues -Docker containers utilize Kernel namespaces to provide a certain level of isolation. However, not all resources are namespaced:
    • UID: Causing “root” user vulnerability
    • Kernel keyring: containers running with a user of the same UID will have access to the same keys if they are handled by kernel keyring
    • Kernel & its modules: Loaded modules become available across all containers and the host
    • Devices: includes disk drives, sound-cards,GPU, etc.
    • System time: The SYSTEM_TIME capability is disabled by default, but if it’s enabled, we will need to worry about it.
  •  Kernel Exploit – Container-based applications share the same host kernel, namely, flaws in  the host kernel might allow malicious containers to escape and gain access over the over whole system.
  • DoS Attacks – Since all containers share kernel resources, if a container or user consumes too much capacity of a certain resource, it will starve out other containers on the host.
  • Container Breakout – Because users are not namespaced, any process that breaks out of the container will have the same privileges on the host as it did in the container. For example, if you were root in the container, you will be root on the host. It’s a typical privilege escalation attack , unlikely to happen, but possible.
  • Poisoned Images – It’s possible for attackers to modify/embed malicious programs into the image and trick users to download such corrupt images
  • Compromising secrets – Applications need credentials to access databases or backend services. An attacker who can get access to these credentials will also have the same access as the application. This problem becomes more acute in a microservice architecture in which containers are constantly stopping and starting.

Current Solutions:

Now Let’s take a look at what security solutions that come with the current Docker implementation and what strategies or techniques can be used in production.

Least Privileges

One of the most important principles to achieve container security is Least Privileges: each process and container should run with the minimum set of access rights and resources it needs to perform its function. This includes the actions to reduce the capabilities of containers:

–  Do not run processes in a container as root to avoid root access from attackers.

–  Run filesystems as read-only so that attackers can not overwrite data or save malicious scripts to file.

–  Cut down the kernel calls that a container can make to reduce the potential attack surface.

–  Limit the resources that a container can use

This Least Privileges approach reduces the possibility that an attacker can access or exploit data or resources via a compromised container.

Internal Security Solutions

Containers can leverage the Linux Namespace and Control group to provide a certain level of isolation and resource limitation.

Namespace

Docker provides process, filesystem, device, IPC and network isolations by using the related namespace.

  • Process Isolation: Docker utilizes PID namespace to separate container processes from the host as well as other containers, so that processes in a container can’t observe or do anything to the other processes running in the host or in other containers.
  • Filesystem Isolation: Use mount namespace to ensure that for each mount space, a container only have impact inside the container.
  • Device Isolation: The container cannot access to any devices unless it’s privileged.
  • IPC Isolation: Utilize IPC namespace to prevent the processes in a container from interfering with those in other containers.
  • Network Isolation: Use network namespace so that each container has its own IP address, IP routing tables, network device, etc.

Control Group

Docker employs Cgroup to control the amount of resources, such as CPU, memory, and disk I/O, that a container can use. Under this control, each container is guaranteed a fair share of the resources but preventing from consuming all of the available resources.

Linux Kernel Security Systems

The kernel security system is present to harden the security of a Linux host system. We can also use them to secure the host from containers.

By default, containers disable a large amount of Linux capabilities from its containers in order to prevent an attacker to damage the host system when a container is compromised. And it also allows configuration of capabilities that a container can use.

Linux Security Module (LSM)

Two most popular LSM will be AppArmor and SELinux:

  • SELinux is a labeling system, that implements Mandatory access control using labels. Every object, such as process, file/directory, network ports, devices, etc, has a label. Rules are put in place to control the access to objects.
  • AppArmor is a security enhancement model to Linux-based on Mandatory Access Control like SELinux. It permits the administrator to load a security profile into each program, which limits the capabilities of the program.

Another Approach

Seccomp

The Linux seccomp (secure computing mode) facility can be used to restrict the system calls that can be made by a process. namely, containers can be locked down to a specified set of system calls.

In Production

When running Docker in a production environment, you will want to leverage one of the security solutions listed above and apply proper precautions to provide a more secure and robust system. There are three major security tips in to keep in mind when running Docker in production.

Segregate Containers by Host

The main reason to place each user on a separate Docker Host is to minimize the loss when container breakout happens. If multiple users are sharing one host, if a user monopolizes all the memory on the host, it will starve out other users. Even worse, if container breakouts happen, a user could possibly gain access to another users’ containers or data through the compromised container.

Therefore, although this approach is less efficient than sharing hosts between users and will result in a higher number of VMs and/or machines than reusing hosts, it’s important for security.

Another similar solution would be separate containers with sensitive  information from less-sensitive ones for the similar reason.

Applying Updates

Just like what is recommended for Windows system, it’s recommended to apply updates regularly. This includes updating base images and dependent images to fix the vulnerabilities in common utilities and framework. At times, we need to update Docker daemon to gain access to new feature, security patches or bug fixes. Removing unsupported drivers is also important, because those could be a security risk since they won’t be receiving the same attention and updates as other parts of Docker.

Image Provenance

To safely use images, you need to have guarantees about their provenance:

  • where they came from
  • who created them
  • ensure you are getting the exactly the image you want

There are three solutions  for image provenance: secure hash, secure signing and verification infrastructure and use Dockerfile properly.

  • Secure Hash:  Secure Hash is like a fingerprint for data. It’s a small string that is unique to given data. If you have a secure hash for some data and the data itself, you can recalculate the hash for the data then compare.  In docker, it’s called docker digest, a SHA-256 hash of a filesystem layer or manifest (a metadata file describing the parts of an image, containing a list of constituent layer identified by digest)
  • Secure Signing and Verification Infrastructure:  Data could be changed / copied if it travels over unsecure channels (e.g. HTTP), so we need to ensure we are publishing and accessing content using secure protocols. Notary project is an ongoing secure signing and verification infrastructure project in docker, which compares a checksum for a downloaded file with the checksum in Notary’s trusted collection for the file source (e.g. docker.com). For more details, please check https://github.com/docker/notary
  • Dockerfile:  Not as we expected, dockerfile is likely to produce different images over time, so as time goes, it’s hard to be sure what is in your images. To use docker properly, you would:
    • Always specify a tag in FROM instruction, and use digest to pull the exactly same image each time
    • Provide version numbers when installing software from package managers. However, since package dependencies can change over time, sometime we need to use tools (e.g. aptly) to take a snapshot of the repository
    • Verify any software or data downloaded from the internet by using checksums or cryptographic signatures.

 

This blog post is a glance of the current security solutions for docker containers, if you are interested, please refer to the reference articles for more details. Are you using Docker in production? Have you implemented some of these security models?

References

[1] Analysis of Docker Security

[2] Docker Security – Using Containers Safely in Production

[3] Docker Doc – Docker Security