Kali Linux In a Docker Container

Update: this post has been updated and works as of June 2020 (official Offensive Security image names have changed).

Background

Docker is a great alternative to virtualization when playing with various tools or for creating isolated environments. Docker is lightweight (runs natively on Linux, no hypervisor layer), and is ideal for use cases not requiring GUI (you probably can make it work, though I’m not particularly inclined to try). Offensive Security have created an official Kali Linux Docker image named kalilinux/kali-rolling, which we’ll be using below.

docker pull kalilinux/kali-rolling
docker run -ti kalilinux/kali-rolling /bin/bash

First Things First

First thing you would want to do is to update Kali packages and install the tools you’ll be using, such as Metasploit. Start a container using the docker run command above, then run the following in the Kali shell:

apt update
apt dist-upgrade
apt autoremove
apt clean
apt install kali-tools-top10
docker ps -a
CONTAINER ID        IMAGE                         COMMAND             CREATED              STATUS                     PORTS               NAMES
2a08d58bcfa8 kalilinux/kali-rolling "/bin/bash" About a minute ago Exited (0) 2 seconds ago thirsty_snyder
docker commit <CONTAINER ID> my-kali
docker run -ti my-kali /bin/bash

Persistence Strategies

Option 1 — Volumes

You would want to save the data in the following folders so that you don’t start from scratch when the container is deleted:

  • /var/lib/postgresql— Postgres database files (used by Metasploit)
docker run -ti --rm --mount src=kali-root,dst=/root --mount src=kali-postgres,dst=/var/lib/postgresql my-kali
  • --rm switch makes Docker delete the container once it stops (i.e. once you exit the shell). This is perfectly fine (and preferred behaviour — you don’t want to waste storage on a bunch of stopped containers) as you have all the components — the image and the two volumes — to recreate it.
docker run -ti --rm --mount type=bind,src=/some/path/kali-root,dst=/root --mount type=bind,src=/some/path/kali-postgres,dst=/var/lib/postgresql my-kali bash

Option 2 — Within the Container

This option is a Docker anti-pattern and I would recommend against it, but it’s still workable and I’ll leave it up to you to judge. This option is worse from performance perspective due to the copy-on-write magic Docker has to do for any file system changes within the container as compared to the image.

docker ps -a
docker start --attach <CONTAINER ID>

Docker Cleanup

When working with Docker, you might end up with a bunch of stopped containers. Use the following command to delete all stopped containers:

docker container prune

Random rumblings about #InfoSec. The opinions expressed here are my own and not necessarily those of my employer.