Secure User in Docker
Tags: docker, kubernetes
Published: 2018-06-20 06:18:38

---
title: Secure User in Docker
published: true
description: How to create users for secure docker container
tags: docker, kubernetes
---

# TL; DR

Create users in Dockerfile as following:

```dockerfile
RUN groupadd -g 61000 docker
RUN useradd -g 61000 -l -M -s /bin/false -u 61000 docker
```

# Secure User in Docker

Running docker container as a root user is risky because the root user in containers has same uid 0 as the host root user. So you have to change the user in containers to non-root user as possible.

Most simple and effective way is to create a user in `Dockerfile`. For example:

```dockerfile
FROM debian

RUN useradd docker
USER docker

CMD ["bash"]
```

You can also change the user with `-u` option of `docker run`. With Kubernetes, you can use SecurityContext to modify the user.

This `Dockerfile` is fine, but `useradd` has many options. Let me describe which options should be used in Dockerfile.

Options often used with Dockerfile are:

```
$ useradd --help
Usage: useradd [options] LOGIN
       useradd -D
       useradd -D [options]

Options:
  -g, --gid GROUP               name or ID of the primary group of the new
                                account
  -l, --no-log-init             do not add the user to the lastlog and
                                faillog databases
  -m, --create-home             create the user's home directory
  -M, --no-create-home          do not create the user's home directory
  -r, --system                  create a system account
  -s, --shell SHELL             login shell of the new account
  -u, --uid UID                 user ID of the new account
  -U, --user-group              create a group with the same name as the user
```

Let's review each option.

* `-g` specifies uid. Because the same gid as uid is easy to understand, you should use `-g`.
* `-l` looks good because lastlog and faillog have few meanings.
* If you have to operate with shell in containers[^1], use `-m` to create home directory. If not, use `-M`.
* `-r` option makes user as a system account. uid is configured from `/etc/login.defs` and home directory doesn't be created. You should not use this option because you will use `-u` to specify uid and use `-m/-M` to configure home directory.
* `-s /bin/false` can forbid remote login. You can execute shell with `docker exec -u $uid sh`, even if `/bin/false` or `/bin/nologin` is set. This option might protect from direct remote login, so you should use `-s /bin/false`.
* `-u` specifies uid. When `-u` was not used, uid is assigned automatically. To manage simply, you should use this option.
* `-U` creates a group named same as the user but gid can differ from uid. `-g` is preferred to `-U`.

[^1]: For example, you often use `bundle exec rails console`.

In conclusion, you should use following instructions to create users:

```dockerfile
RUN groupadd -g 61000 docker
RUN useradd -g 61000 -l -M -s /bin/false -u 61000 docker
```

If you need home directory:

```dockerfile
RUN groupadd -g 61000 docker
RUN useradd -g 61000 -l -m -s /bin/false -u 61000 docker
```

Because major distributions reserve uid from 1000 to 60000, I proposed 61000 as uid. By the way, worker nodes of GKE reserve uid from 5000 to 60000. If you use 5000 as uid, they conflict.