Dive¶
What Is It?¶
Dive is an interactive terminal tool for exploring the contents of a Docker image one layer at a time. Where docker history only shows you the build commands and sizes, Dive lets you walk through the actual filesystem changes each layer introduced — added files, modified files, removed files — and see the layer's content digest.
In a system administration context, Dive's main use is manual image audit: confirming that a third-party image contains only what you expect, and identifying suspicious files that may have been planted by a malicious image author. Tools like Trivy do automated CVE scanning, but they are blind to purposeful, custom-written malware. Dive is what you reach for when you don't trust the image and want to look at the actual bytes.
Installation¶
Dive is not packaged in CentOS Stream's repositories, but the project ships an RPM with every release on GitHub. Install it directly with dnf:
# Pick the latest release tag from https://github.com/wagoodman/dive/releases
DIVE_VERSION="0.13.1"
sudo dnf install -y \
"https://github.com/wagoodman/dive/releases/download/v${DIVE_VERSION}/dive_${DIVE_VERSION}_linux_amd64.rpm"
Verify:
dive --version
Expected output (version number may differ):
dive 0.13.1
Key Files and Directories¶
Dive itself has no on-disk state. It reads images from your local Docker daemon cache. The image must already be pulled (sudo docker pull <image>) before Dive can inspect it.
| Path | Purpose |
|---|---|
/usr/local/bin/dive | The Dive binary (location may vary by RPM version) |
/var/run/docker.sock | Docker socket — Dive talks to the daemon through this |
Configuration¶
Dive runs interactively and needs no configuration for normal use. The defaults are sensible.
Important Keybindings¶
Once Dive is running, the interface has two main panels — the layer list (left) and the file tree (right). The most useful keys:
| Key | Action |
|---|---|
Tab | Switch between the layer list and the file tree |
↑ / ↓ | Move up and down in the current panel |
Ctrl+U | In the file tree: hide files unmodified in the selected layer |
Ctrl+F | Filter files in the file tree |
Ctrl+Space | Collapse or expand a directory |
Q or Ctrl+C | Quit |
The bottom bar always shows the available shortcuts for the current context.
Common Commands¶
# Audit an image already in the local cache
sudo dive registry.hpc.ut.ee/public/lab10-consultancy:latest
# Audit an image you've built locally
sudo dive myapp:v1
# Pull-then-audit one-liner
sudo docker pull <image> && sudo dive <image>
sudo is needed because Dive talks to /var/run/docker.sock, which is owned by root:docker and not readable by an unprivileged user.
What to Look For When Auditing¶
When you open an image in Dive, the question to ask of every layer is: "Does this change make sense for what the image claims to do?" Specifically:
- Walk the layer list top-to-bottom. For each layer, check the
Command:field — this is the Dockerfile instruction that produced the layer. ARUN apk add nginxlayer in an image that claims to be a web server is expected; aCOPY backdoor.sh /usr/local/bin/layer is not. - Use
Ctrl+Uin the file tree to hide files that were not modified by the selected layer. This focuses you on exactly what changed. - Watch for files in unexpected paths.
/usr/local/bin/,/opt/, and/etc/cron.d/are common places for an attacker to plant a script while making the image look normal. - Note the layer's
Digest:field. It is the SHA256 content hash of the layer and uniquely identifies it across pulls. If you ever need to reference a specific layer (for example, to record which layer a malicious file was introduced in), this is the value to record. - Open the file content by selecting a suspicious file with the cursor. If the script's contents include things like
curl | bash, environment exfiltration, or hardcoded URLs to attacker-controlled domains, you have your answer.
Logging and Debugging¶
Dive does not produce persistent logs. If the tool fails to start, the most common causes are:
- Image not present locally. Pull it first:
sudo docker pull <image>. - Docker socket permission denied. Run Dive with
sudo. Adding the user to thedockergroup is discouraged on this course (it's equivalent to handing out passwordless sudo). - Image is too large for your terminal. Use a larger terminal window — Dive's UI is dense.
Security Considerations¶
- Dive talks to the Docker daemon, which means anyone who can run Dive on the host can also start any container — including one that mounts the host filesystem as root. Treat Dive access the same as Docker access.
- Dive only reads from the local Docker cache. It does not modify images and does not touch the registry. You can safely re-run it as many times as you want against any pulled image.
- Auditing alone is not enough — combine with Trivy for automated CVE scanning. The two tools cover different blind spots: Trivy catches known vulnerabilities in known packages, Dive lets you see custom-planted files that no scanner has a signature for.
Further Reading¶
Related Documentation¶
- Concepts: Containers
- Technologies: Docker, Trivy
- SOPs: Container Operations