Hardening Docker Containers: Disable SUID Programs

Hardening_Docker_Containers

When most people think about hardening a Docker container, the first thing they think of is setting the default user to a non-root account. Before an attacker can break out of a container they would need to gain root in that container. By running as a non-root account, you’ve made an attack that much more difficult.

You can start a container as any non-root user that exists in the target image by using the -u, or –user option on docker run or docker create. You might be able to tell what users exist in an image by using docker history and looking for adduser commands. You can see if there was a default user set by looking for USER commands. Or, just start up a container from the image and launch a shell to investigate manually. If you don’t feel like digging around you can usually use the “nobody” user.

I don’t believe Tutum currently provides an interface to specify the run-as user for your container. So if you want to run as a non-root user, you should make sure that the Service that you’re starting uses an image with the default USER set to a non-root account.

Running as a non-root user is a good first start but there are several things you can do to improve on this. One of the more interesting things is unsetting the SUID flag on files where it is set, or deleting those files from your image altogether. Now you might be thinking, “What the heck is a SUID flag?”

The SUID flag is a Linux file permission. Most Linux users have a basic understanding of Linux file permissions. The familiar 9 flags describe the permissions that the file owner, group, or just any user has on a particular file. For example:

"-rwxr-xr-x 1 root root" (or 755)

  • the file owner can read, write, or execute the file
  • users in the file group can read or execute the file
  • any user can read or execute the file

The SUID flag is a specialization of the executable flag. It tells Linux to set the effective group or user to the owning group or user when executing the file.

"-rwsr-xr-x 1 root root"
or
"-rwxr-sr-x 1 root root"

There are many occasions when a general user needs access to a program that requires elevated privileges to work. One of my favorite examples is the ping command. I like this example because it is something that seems trivial or harmless to most users. Ping requires root privileges because it uses the ICMP protocol. There are several such tools included with a typical Linux installation. I counted 22 programs with SUID set that ship with the ubuntu:latest image.

/sbin/unix_chkpwd
/usr/bin/chage
/usr/bin/passwd
/usr/bin/mail-touchlock
/usr/bin/mail-unlock
/usr/bin/gpasswd
/usr/bin/crontab
/usr/bin/chfn
/usr/bin/newgrp
/usr/bin/sudo
/usr/bin/wall
/usr/bin/mail-lock
/usr/bin/expiry
/usr/bin/dotlockfile
/usr/bin/chsh
/usr/lib/eject/dmcrypt-get-device
/usr/lib/pt_chown
/bin/ping6
/bin/su
/bin/ping
/bin/umount
/bin/mount

The following example demonstrates the SUID flag in action. Consider the following Dockerfile:

FROM ubuntu:latest

RUN chmod u+s /usr/bin/whoami

RUN adduser --system --no-create-home --disabled-password --disabled-login --shell /bin/sh example

USER example

CMD printf "Container running as:          %s\n" `id -u -n` && printf "Effectively running whoami as: %s\n" `whoami`

Building and running an image from this Dockerfile will yield output like:

docker build -t tutumblog/suid_whoami . \
&& docker run --rm tutumblog/suid_whoami

Container running as:                  example
Effectively running whoami as:  root

In this example, I start with a base Ubuntu image and set the SUID flag on the whoami command. I go on to add an example user to the image and make that user the default user for containers created from the image. The default command demonstrates the problem by displaying the current user two different ways. When the example user executes whoami, Linux executes it as root because its SUID flag has been set for the owner and the file’s owner is root.

Now obviously whoami is not a program that needs to run as its owner. In fact it displays the wrong result if it is. The question that you need to ask is, “Do I need programs with SUID set at runtime?” Most of the time I think the answer will be, “No.”

I’m sure that you could make a case for using some of these at runtime. Some people will need crontab. Others will want ping available for troubleshooting. But what happens if there is a bug in any one of these 22 programs? Well, if the SUID flag is set and an attacker exploits the bug then they have taken control of the container.

You can fix the problem by unsetting the SUID flag. You might consider adding a line to your application Dockerfiles (those that you do not intend to extend) that unsets all SUID flags in your image. Consider the following Dockerfile:

FROM ubuntu:latest

RUN adduser --system --no-create-home --disabled-password --disabled-login --shell /bin/sh example

RUN for i in `find / -perm +6000 -type f`; do chmod a-s $i; done

USER example

CMD /bin/bash

Alternatively, you could fix the issue by removing the programs:


RUN for i in `find / -perm +6000 -type f`; do rm -f $i; done

Containers are all about isolation not virtualization. In that spirit, Docker images are about shipping a small file set that an application or service requires to launch. If you have a concrete need for some of these programs to run as root, then you can always pick and choose which to harden and which to ignore. But it is important to recognize the risk you take if you leave them intact.

nickoloff_cover150This subject and others are covered in detail in my book Docker in Action. Electronic copies are currently available through the Manning Early Access Program.

About

Jeff Nickoloff is a software engineer and author. He is currently writing Docker in Action, consulting, working on a privacy conscious content discovery project, and mentoring a few new engineers. Until recently he worked with Amazon.com in engineering and leadership. He spent that time building and iterating on the high volume microservices powering the largest document processing workflow engine at Amazon. He has contributed libraries used by teams all over Amazon. Connect with Jeff via Twitter @allingeek or follow his blog at https://medium.com/@allingeek/.

Tagged with: , , ,
Posted in Tutorial
5 comments on “Hardening Docker Containers: Disable SUID Programs
  1. dontemailme says:

    How come I have the Manning Early access but did not see such chapter?

  2. xxx says:

    If some one wɑnts to be updated with latest technologies then he must be visit this web site and be up to date
    daily.

  3. […] 原文链接:Hardening Docker Containers: Disable SUID Programs (翻译:崔婧雯) […]

Leave a Comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories
%d bloggers like this: