🐳Basic Container Security Labs

🎯 Objective

Learn how to use Docker containers securely by applying best practices and reducing attack surfaces.


🧰 Prerequisites

  • Docker installed

  • Root or sudo access

  • Terminal and Docker basics


πŸ”Ή Lab 1: Use Minimal Base Images

Step 1: Compare image sizes

docker pull ubuntu
docker pull alpine
docker images | grep -E 'ubuntu|alpine'

βœ… Expected: Alpine is much smaller.

ubuntu       latest    a0e45e2ce6e6   12 days ago    78.1MB
alpine       latest    aded1e1a5b37   2 months ago   7.83MB

🧠 Smaller images = fewer vulnerabilities and faster deploys.


πŸ”Ή Lab 2: Run Containers as Root User

Step 1: Create a Dockerfile

Step 2: Build and run

βœ… Expected: You are root inside the container.

🧠 Violates the principle of Least Privilege.


πŸ”Ή Lab 3: Run Containers as Non-Root User

Step 1: Create a more secure Dockerfile

Step 2: Build and run again

βœ… Expected: You are not root inside the container.

🧠 Follows the principle of Least Privilege.


πŸ”Ή Lab 4: Drop Unnecessary Capabilities

Step 1: Run a minimal-capabilities container

βœ… Expected: Privileged actions fail.

🧠 Capabilities like CAP_NET_RAW are dangerous if not required.


πŸ”Ή Lab 5: Use Seccomp to Restrict Syscalls

Step 1: Run with Docker’s default seccomp profile

Docker now runs by default using a default seccomp profile. By default this profile allows executing the potentially dangerous strace command.

First, get the default seccomp profile from github:

Open the file with nano default.json and search for the entry ptrace (using Ctrl-W) and delete the corresponding line and exit nano using Ctrl-X and type Y to store the file.

Now run the following docker container using the modified seccomp profile:

Inside the container try:

🧠 Seccomp blocks risky syscalls.

See more details at https://docs.docker.com/engine/security/seccomp


πŸ”Ή Lab 6: Apply AppArmor Profiles

Step 1: View active profiles

Step 2: Run with a profile

When you run a container, it uses the docker-default AppArmor policy unless you override it with the security-opt option.

You can also specify the profile explicitly:

🧠 Use docker-default or custom profiles for app restrictions.

See more details at https://docs.docker.com/engine/security/apparmor


πŸ”Ή Lab 7: Secure Secrets Handling

Step 1: Avoid baking secrets into images

Bad (insecure):

Step 2: Use runtime secrets

βœ… Expected: Secret is not in the image, only on runtime mount.

Check for secret in the container located at /run/secrets/db_pass.

Docker provides native secrets support only in swarm mode. See more details at https://docs.docker.com/engine/swarm/secrets. We will look more in depth into secrets in the correspondig section.


πŸ”Ή Lab 8: Scan Images for Vulnerabilities

Step 1: Use Trivy or Docker Scout

Install Trivy:

Step 2: Scan the Alpine image

Step 3: Scan the Ubuntu image

βœ… Expected: CVE results and recommendations.

🧠 Scan early, scan often.


βœ… Wrap-Up

  • βœ… Minimal base images

  • βœ… Run as non-root

  • βœ… Drop unnecessary caps

  • βœ… Use seccomp/AppArmor

  • βœ… Handle secrets securely

  • βœ… Scan images


Last updated