DEV Community

Cover image for New Type of Docker : Rootless + Safer : for every Docker user.
manish srivastava
manish srivastava

Posted on • Edited on

New Type of Docker : Rootless + Safer : for every Docker user.

In this article, we will discover:

1. How hackers know vulnerabilities of my docker containers.
2. How to make docker more secure – rootless

Docker and containers are becoming ever more popular and settling into the standard toolkit of developers and ops folks. Docker runs as a daemon named “dockerd”, which serves as the top-level interface to Docker’s core functionality. The “docker” command line tool for example, talks to dockerd to get your task done. The API that dockerd exposes, variously called the Docker API or the Docker Remote API. The port 2375 is the de-facto standard for the Docker API. As it stands, the endpoint is unauthenticated and unencrypted. see: IANA allocates port 2375 to docker

Now, let us go to a search engine to find the how many docker daemons are available to hack via default port 2375 port of Docker. On 1 June 2020, at 11 Am , Indian Standard Time (GMT :+5.30) by using shodan.io , I found 5,209 docker daemons are prone to hackers.

Alt Text

Top Docker hosts version with the remote API exposed publicly.
18.06.1-ce: 3,604
17.05.0-ce: 672
19.03.8: 293
1.13.1: 164
18.05.0-ce: 29

Even the latest Stable release 19.03.8 / March 10, 2020 is inviting hackers.

But what hacker’s do with your docker container?

The possibilities for attackers after spawning a container on hacked Docker hosts are endless. The most of the exposed Docker remote API IPs are running a cryptocurrency miner for a currency called Monero. Monero transactions are obfuscated, meaning it is nearly impossible to track the source, amount, or destination of a transaction. Mining cryptocurrency is just one example.

• Access files on the Docker host and mounted volumes.
• Scan the internal network
• Credentials leakage
• Data Leakage

They can also be used to:
• Launch more attacks with masked IPs
• Create a botnet
• Host services for phishing campaigns
• Steal credentials and data
• Pivot attacks to the internal network.

Vulnerabilities related to docker / popular docker images:

Alt Text

Source: National Vulnerability Database (NVD – USA) lists various vulnerability related to docker or popular images of docker in its hub: https://nvd.nist.gov/vuln/search/results?form_type=basic&results_type=overview&search_type=all&query=docker&startIndex=20

Solutions?

(a)Choosing another container technology.
(b)If you can’t switch to another technology then make your docker more secure.

(a)Choosing another container technology:

Alt Text

Alt Text

From above table , we found lxd, rkt and podman being daemon less can secure your containers from hackers. Also , being daemonless, single point failure issues are already mitigated.

Learn: LXC / podman in 5 minutes : Podman is 100% similar in usage like docker. Same Commands including use of docker hub is also allowed. You will not find any difference.
Learn more here: https://dev.to/manishfoodtechs/5-minutes-challenge-to-css-php-non-devops-peoples-to-learn-about-lxc-docker-networking-cloud-diy-yourself-35ia
Its time to say bye bye docker: Introducing Podman : https://dev.to/manishfoodtechs/time-to-say-bye-bye-docker-era-of-docker-is-over-2n06

(b)If you can’t switch to another technology then make your docker more secure.

So why are we rootless in need?

In reality, the Docker is built by default to be safer. It comes with a bunch of security features including namespaces for isolating processes such as mount namespace, and network namespace.
And there are also Cgroups to restrict application access and seccomp to restrict systems calls, and even AppArmor and SELinux to control permissions for file access.
So, you don't need to think about rootless mode, in principle. But in fact, there are bugs in every program, so the root user in a container can break out a container with exploitation of these bugs. Here are several instances of the glitches.
The weakness of the runC was CVE-2019-5736. It allowed the binary of runC to be replaced with '/proc / self / exe.' And Docker 's weakness was CVE-2019-14271. By hiding the 'docker cp' procedure, it allowed a malicious library to be injected into the host system .
National Vulnerability Database (NVD – USA:Lists various vulnerability related to docker or popular images of docker in its hub: https://nvd.nist.gov/vuln/search/results?form_type=basic&results_type=overview&search_type=all&query=docker&startIndex=20)

Often people make errors and reveal an internet Docker API socket without a customer authentication. There are thousands of these malconfigured hosts on the Internet, researchers say. The solution to these bugs and malfunctions is therefore not rootless mode itself.

Rootless mode means running the Docker daemon and even containers as an unprivileged user to protect the root user from future attacks on the host system.

Rootless mode was introduced in Docker version 19.03 as an experimental feature and it had some disadvantages, particularly it did not support cgroups and also did not support OverlayFS, so you couldn't define resource limitations for rootless containers. But, Docker's next version comes with complete rootless mode support, and now ready for your development.

We 're talking about running the whole stack, like dockerd, containerd, runC, libnetwork and a whole host of other things, not just containers. Effectively this mode protects the host system from potential attacks that exploit vulnerabilities or Docker daemon misconfiguration, or containerd or runC.

Installing Rootless Docker:

Getting started with rootless mode is quite easy. You just need to download a shell script from get.docker.com/rootless andalso you'll need to set a single environment variable $DOCKER_HOST. That's all of the installation steps.
For installing rootless mode you do not need root privileges, and of course, you don't need a sudo, and all binaries can be installed under your home directory, so you don't need to have write access or /user/bin or /user/local/bin.

1.Create a user say manish
2.useradd -m -d /home/manish -p $(openssl passwd -1 password) manish .
The user is also not able to access Docker as previously this required them to have root permissions.

3.curl -sSL https://get.docker.com/rootless | sh
After this has finished, proceed to the next step to setup the user environment and start launching containers.

4.The daemon can be started using the following script:
`export XDG_RUNTIME_DIR=/tmp/docker-1001
export PATH=/home/lowprivuser/bin:$PATH
export DOCKER_HOST=unix:///tmp/docker-1001/docker.sock

/home/manish/bin/dockerd-rootless.sh --experimental --storage-driver vfs`

5.Click the following command to launch a second terminal window and change the context to run as roootlessuser
sudo su manish
You will get result something like this : "Second Terminal running as lowprivuser"

6.To access Docker, set the following environment variables. This specifies connecting to the Docker instance running for the user with id 1001, which should match the id of manish.
export XDG_RUNTIME_DIR=/tmp/docker-1001
export PATH=/home/manish/bin:$PATH
export DOCKER_HOST=unix:///tmp/docker-1001/docker.sock

7.Now creating containers:
‘docker pull ubuntu:latest`

Please Note:

1.And there are a number of similar things, but quite different, to the rootless Docker.

(a)The sudo docker is the sudo docker. It's totally different from rootless mode, of course.
(b)Secondly, to add an unprivileged user account in a Linux group named 'docker,' the user can have access to a socket file: '/var/run/docker.sock' which is different from that for rootless mode, because the daemon still runs root and the user can use root privileges against the host.
(c)The 'docker run - user' is also distinct from 'rootless' mode. It runs the container as an unprivileged user, but the daemon still runs as kernel. And the rootless mode also varies from 'dockerd' mode.

This mode is much like rootless but the daemon still runs as root.
They all act as the core of the daemon. It allows a user to gain host device privileges simply by running 'docker execute-v/:/host' or simply running "docker execute —privileged".

2.Rootless mode works under the hood.

(a)In above session the user name is "manish" not "root". But if we execute unshare command with --user and --map-root-user, the user name changes into "root". So did we gain the root privileges as in sudo command? Lets verify that question by trying to write a file in the root directory. So we run touch /evil, and it fails with a "Permission denied" error. So we didn't gain root privileges, but we are faking the environment for emulating root privileges that are enough to run containers.
(b)With user namespaces we can create other namespaces such as mount namespace, network namespace, UTS namespace, and IPC namespace. And we can do some operations, like changing the host name or mounting bind-mount file systems.
(c)For example, we can create a UTS namespace along with a user namespace by running unshare --uts, and now we can execute hostname command to change the host name.
(d)This host name is valid only inside of this namespace, and it does not affect the whole system.

3.Snapshotting:

(a)On "rootful" Docker we use OverlayFS so that we can create containers for an image. without duplicating files. But it's basically not available for rootless users because of the limitation of the kernel.

(b)But if you're using Ubuntu or Debian the kernel is patched to enable OverlayFS so you can use OveralyFS in rootless mode. If you're using other distros, you need to use vfs driver which is slow and wasteful. But the next version of Docker, Version 20.0x supports OverlayFS for any distro with kernel 4.18 or later by using a FUSE filesystem.

4.Networking:

With user namespaces, we can create network namespaces without root. But we still cannot create virtual Ethernet interfaces. So we use user-mode
TCP/IP stack instead of virtual Ethernet interfaces. For example, we can use VPNKit which is spun out from MirageOS, and it's also used by Docker for Mac and Docker for Windows. We also support slirp4netns which is spun out from QEMU. These stacks are slightly slow but should be enough for most use cases. And for the best performance, we also support using a SETUID binary called lxc-user-nicso that you can use virtual Ethernet interfaces. But this is currently experimental and it slightly sacrifices the security. So it is still recommended to use VPNKit or slirp4netns. Previously the rootless mode didn't support cgroups,

so you couldn't specify resource limitations, such as docker run --cpus, or docker run -- memory, and docker run --pids-limit.

Now cgroups is fully supported in the next version of Docker version 20.0X, but it requires cgroup version 2 and systemd. Cgroup version 2 is enabled by default if you are using Fedora.

But other distributions require changing kernel command line via GRUB bootloader configuration. You need to specify systemd.unified_cgroup_heirarchy=1. There are several features still not supported by rootless mode including specifying AppArmor profiles, docker checkpoint, and docker run --net=host, exposing SCTP ports and also setting up overlay networks.

But in 99% of use cases, you don't need these features, so basically you don't need to care about them.

Here are some frequently asked questions and answers:

Question :Is rootless mode still experimental?

So, yes it is still experimental in the current version 19.03 but it's going to graduate from experimental in the next version of Docker, version 20.0X. This version will be released in the next couple of months.

Question : Is rootless mode the panacea that solves all of the problems?

The answer is no, definitely not. If Docker has a vulnerability, the attacker still may be able to dig out crypto currencies like Bitcoin or abuse the host as a springboard to attack other hosts on the Internet for
the sake of hiding the attacker's real IP address.

And also ,rootless mode is not effective for vulnerabilities of kernel, or VM or hardware.

Question: Whether we can use docker run -p to expose expose ports.

Yes,you can, but be aware that port numbers below 1024 are called privileged ports and not available for rootless users. So basically, you need to use unprivileged port like 8080. So if you want to run HTTP server, you need to run docker run -p 8080:80. But if you really need to expose privileged ports you can do that by adjusting sysctl /proc/sys/net/ipv4/ip_unprivileged_port_start or by setting CAP_NET_BIND SERVICE capability on binary port rootlesskit.

This is a slightly advanced topic. So, basically it's better to specify an unprivileged port number such as 8080.

Docker vs rootless Podman

Podman. Podman is yet another implementation of Docker created by RedHat and supports rootless mode as well. Docker and Podman have been mutually exchanging a lot of codes for supporting rootless mode, and they have almost the same features with almost the same performance. So
basically there is no difference, but the only visible difference
is the network lifecycle.

Rootless Docker doesn't support specifying docker run --net=host, but on the other hand, Rootless Podman doesn't support creating custom networks with docker network create`.

But if you really need to use docker run --net=host, Podman might be a better choice for you in my opinion.

I hope you people like the above article and learned something.

IMP REQUEST:
You are most welcome to join my team form for joining .
Also you are most welcome to join OPEN SOURCE INTELLIGENT SYSTEM (OSINT)if you can help in open source project regarding safeguarding humans from various diseases like CORONA outbreak
https://github.com/Manishfoodtechs/OSINTHRH/wiki

Contact email: Manishfoodtechs@gmail.com.

If you have any problem, our team is also engaged in professional consultancy and delivery.

Top comments (0)