Harden a Docker Image with a Profile File

Part 1: Harden without a Profile File

First, we will stub, test, and harden the NGINX Docker image. 
For more detailed information, please refer to the Getting Started: Stub and Harden a Container Image with Docker tutorial.
Step 1.1: Pull the NGINX Docker Image 
docker pull nginx:latest
 
Step 1.2: Generate a Stub Image 
rfstub nginx:latest
 
Step 1.3: Run the Stub Image 
docker run --rm -it --name=rf-test --cap-add=SYS_PTRACE -p9999:80 nginx:latest-rfstub
 
Step 1.4: Test the Stub Image 
curl localhost:9999
 
Step 1.5: Stop the Running Instance 
docker stop rf-test
 
Step 1.6: Harden the Stub Image 
rfharden nginx:latest-rfstub
 
Step 1.7: Run the Hardened Image
Run the hardened image: 
docker run --rm -it --name=rf-test -p9999:80 nginx:latest-rfhardened
 
Step 1.8: Explore the Hardened Image
Attach to the running instance: 
docker exec -it rf-test sh
 
Try to run cat. 
cat --help
sh: cat: not found
 
 
Now try to run ls. 
ls
sh: ls: not found
 
Use it or lose it! cat and ls were removed from the hardened image because these were not exercised while profiling the stub image.
Stop the running instance. 
docker stop rf-test
 

Part 2: Harden with a Profile File

We will create a profile file and generate a new hardened image using the profile file.
Step 2.1: Create a Profile File
Create a text file called nginx_profile:
nginx_profile 
cat
ls
 
If an item in the profile file has dependencies, the profile file must specify all dependencies as well.
Step 2.2: Harden with the Profile File
Harden the stub image with the profile file. 
rfharden nginx:latest -p nginx_profile
 
Step 2.3: Run the Hardened Image
Run the hardened image again. 
docker run --rm -it --name=rf-test -p9999:80 nginx:latest-rfhardened

Step 2.4: Explore the Hardened Image

Attach to the running instance. 

docker exec -it rf-test sh
 
Verify that cat and ls are now available. 
cat --help
ls
 
Verify that the hardened image does not contain any files in the folders in /usr/share/doc.
For example: 
ls /usr/share/doc/sed
 
The files in the folders in /usr/share/doc were not exercised during profiling. We will update the profile file to keep everything in /usr/share/doc.
Stop the running instance. 
docker stop rf-test
 
Step 2.5: Update the Profile File
Add /usr/share/doc to the nginx_profile file:
nginx_profile
cat
ls
/usr/share/doc
 
Step 2.6: Harden with the Updated Profile File
Harden the stub image with the updated profile file: 
rfharden nginx:latest -p nginx_profile
 
Step 2.7: Run the Updated Hardened Image
Run the new hardened image: 
docker run --rm -it --name=rf-test -p9999:80 nginx:latest-rfhardened
Step 2.8: Explore the Updated Hardened Image
Attach to the running instance. 
docker exec -it rf-test sh
 
Verify that the hardened image now contains files in the folders in /usr/share/doc.
For example:
 
ls /usr/share/doc/sed
cat /usr/share/doc/sed/copyright
 

Summary

We generated a stub image, ran and tested the stub image to generate the runtime profile, and then hardened the stub image.
We verified that the hardened image did not contain some items that we wanted to keep. These items were not detected as being used during profiling and were therefore removed during the hardening process.
Therefore, we created a profile file that contained files and directories that we wanted to keep in the hardened image. We generated a new hardened image using the profile file and verified that the hardened image contained the items that we wanted.