Links

Getting Started: Stub and Harden a Container Image with Podman

Use the RapidFort Command Line Interface (CLI) tools to stub and harden a container image with Podman

Prerequisites

You will need the following:
  • Client system with the RapidFort Command Line Interface Tools and dependencies installed
    • Python3 and pip3
    • Podman (RapidFort recommends version 4.2.0 or later)
  • RapidFort server (SaaS or On-Premises) and account

Stub and Harden the NGINX Container Image

In this tutorial, we will stub, test, and harden the NGINX container image from Docker Hub.
Original Image: The NGINX container image available directly from Docker Hub. The original image has not yet been optimized and secured by RapidFort and may have known vulnerabilities.
Stub Image: The original image with additional dependencies necessary for RapidFort to trace the runtime behavior and generate the runtime profile. The stub image must be deployed with additional requirements (in particular, the SYS_PTRACE Linux kernel capability must be added) or else RapidFort will not be able to trace the runtime behavior.
Hardened Image: The optimized and secured image generated by RapidFort. The hardened image does not contain any RapidFort dependencies for runtime tracing.

Part 1: Get and Run the Original Image

Before we start using RapidFort, we will get the original NGINX container image from Docker Hub and verify that we can run and test this.

Step 1.1: Pull the NGINX Container Image

Pull the latest NGINX container image:
podman pull docker.io/nginx:latest
Run podman images and verify that the image is available:
podman images | grep nginx

Step 1.2: Run the Original Image

Run the original NGINX image:
podman run --rm -it -p9999:80 --name=rf-test docker.io/nginx:latest
Please note that we mapped port 9999 on the host to port 80 within the container.

Step 1.3: Test the Original Image

Open another terminal window and run the following command:
curl localhost:9999
You should see a welcome message from NGINX if everything is working as expected.
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
Stop the container:
podman stop -t 1 rf-test

Part 2: Generate, Run, and Test the Stub Image

Step 2.1: Log Into RapidFort

Run rflogin to log into RapidFort. Enter your password if prompted.
rflogin <email>

Step 2.2: Generate a Stub Image

Run rfstub to generate a stub image:
rfstub docker.io/nginx:latest
This creates a new image, docker.io/nginx:latest-rfstub. The stub image contains dependencies necessary for RapidFort to trace the runtime behavior.
Run podman images to view the stub image:
podman images | grep nginx

Step 2.3: Run the Stub Image

Run the stub image. When running the stub image, you must add the SYS_PTRACE Linux kernel capability so that RapidFort is able to trace the runtime behavior:
podman run --rm -it -p9999:80 --cap-add=SYS_PTRACE --name=rf-test docker.io/nginx:latest-rfstub
If you do not add the SYS_PTRACE capability (--cap-add=SYS_PTRACE) when running the stub image, then you may see the following error message:
ptrace: Operation not permitted [/bin/dash]
ERROR 48e: did you forget to add SYS_PTRACE capability (--cap-add=SYS_PTRACE)?

Step 2.4: Test the Stub Image

After the stub image has been deployed, run tests to exercise the application. RapidFort will trace the runtime behavior of your application and generate a runtime profile. The runtime profile is required to harden (optimize) the image.
For example, run the following command:
curl localhost:9999
You should see the same welcome message from NGINX if everything is working as expected.

Step 2.5: Verify that Tracing Information is Propagated to RapidFort

Log into the RapidFort dashboard. You should see an image list.
Select the docker.io/nginx:latest image.
In the left column, select Logs. Verify that the Logs table contains tracing information. You should see file accesses, system calls, and so forth. The Logs table contents are updated in real time.
If the Logs table is empty, please verify the following:
  • The stub image (docker.io/nginx:latest-rfstub) is deployed and running
  • The podman run command specified --cap-add=SYS_PTRACE
  • The client system has access to the RapidFort server
Please correct any issues and go back to Step 2.3. RapidFort cannot harden an image unless it has runtime profile information.
When you generate a stub image, RapidFort also scans the original image for packages and known vulnerabilities. You may optionally view the vulnerabilities and packages found in the original image from the RapidFort dashboard.

Step 2.6: Stop the Container

When you are finished with testing your application, stop the container:
podman stop -t 1 rf-test

Part 3: Generate, Run, and Test the Hardened Image

Step 3.1: Harden the Stub Image

Run rfharden to harden the stub image.
rfharden docker.io/nginx:latest-rfstub
This creates a new image, docker.io/nginx:latest-rfhardened.
Run podman images to view the hardened image:
podman images | grep nginx
If you get the following error message when hardening the image, please go back to Steps 2.3-2.5 and deploy and test your stub image again.
Error: No stub instances have run yet...
This indicates that RapidFort did not receive runtime profile information for this image. RapidFort must have a runtime profile in order to harden an image.

Step 3.2: Run the Hardened Image

Run the hardened image and test it again to verify that your application is working as expected:
podman run --rm -it -p9999:80 --name=rf-test docker.io/nginx:latest-rfhardened
curl localhost:9999
You should see the same welcome message from NGINX.
When you are finished with testing your application, stop the container:
podman stop -t 1 rf-test
The hardened image does not contain any RapidFort dependencies for runtime tracing.
You do not need to add the SYS_PTRACE capability when running the hardened image.

Step 3.3: View Image Information

To view information on a RapidFort image, run rfinfo <rapidfort_guid>:
rfinfo <rapidfort_guid>
Optionally, to save reports to your local system, run rfinfo with the -s parameter.
rfinfo -s <rapidfort_guid>
You can also visit the RapidFort dashboard for more information.

Review

Stub: Run rfstub to generate a stub image from the original image. The stub image contains dependencies necessary for RapidFort to trace the runtime behavior.
Test: Run and test the stub image instead of the original image.
When running the stub image, add the SYS_PTRACE Linux kernel capability by specifying --cap-add=SYS_PTRACE so that RapidFort can trace the runtime behavior.
Verify that tracing information is being propagated to the RapidFort server by visiting the RapidFort dashboard and viewing the logs for the stub image.
Harden: Run rfharden to generate a hardened image. The hardened image does not contain any RapidFort dependencies for runtime tracing.
Test Again: Run and test the hardened image again. Verify that the hardened image has the same runtime behavior as the original image.
View the Results: View the attack surface, known vulnerabilities, packages, and files in the original and hardened images. You can also download reports.
Congratulations! You have successfully stubbed and hardened a container image!

Notes

Stub images cannot be used as base images. If you need to make updates, please build a new original image with the updates and then generate a new stub image.