Container Scanning Workflow¶
Overview¶
The CBOM Generator can scan container filesystems to inventory cryptographic assets. This is accomplished by exporting a container's filesystem and scanning it using cross-architecture mode.
Key Concept: Container scanning analyzes the contents of a container image or exported container. This is different from detecting services running inside containers on your host system.
Prerequisites¶
- Docker or Podman installed
- CBOM Generator built (
./build/cbom-generator) - Sufficient disk space for extracted filesystem (typically 50MB - 2GB depending on image)
Quick Start¶
Scanning a Running Container¶
# 1. Export the container filesystem
docker export my-container | tar -xf - -C /tmp/container-fs
# 2. Scan with cross-arch mode
./build/cbom-generator \
--cross-arch \
--crypto-registry registry/crypto-registry-alpine.yaml \
--format cyclonedx --cyclonedx-spec 1.7 \
--output container-cbom.json \
/tmp/container-fs
# 3. Clean up
rm -rf /tmp/container-fs
Scanning a Container Image¶
For images (not running containers), create a temporary container first:
# 1. Create temporary container from image
docker create --name cbom-scan-temp nginx:alpine
# 2. Export the filesystem
mkdir -p /tmp/container-fs
docker export cbom-scan-temp | tar -xf - -C /tmp/container-fs
# 3. Remove temporary container
docker rm cbom-scan-temp
# 4. Scan
./build/cbom-generator \
--cross-arch \
--crypto-registry registry/crypto-registry-alpine.yaml \
--format cyclonedx --cyclonedx-spec 1.7 \
--output nginx-alpine-cbom.json \
/tmp/container-fs
# 5. Clean up
rm -rf /tmp/container-fs
Podman Support¶
The workflow is identical for Podman:
# Export running container
podman export my-container | tar -xf - -C /tmp/container-fs
# Or from image
podman create --name cbom-scan-temp docker.io/library/nginx:alpine
podman export cbom-scan-temp | tar -xf - -C /tmp/container-fs
podman rm cbom-scan-temp
# Scan
./build/cbom-generator \
--cross-arch \
--crypto-registry registry/crypto-registry-alpine.yaml \
--output container-cbom.json \
/tmp/container-fs
Alpine Linux Containers¶
Most lightweight containers are based on Alpine Linux. The crypto-registry-alpine.yaml registry includes patterns for:
Crypto Libraries: - OpenSSL (libcrypto.so.3, libssl.so.3) - LibreSSL (libtls.so) - libsodium - GnuTLS - mbedTLS - NSS
Common Services: - OpenSSH - nginx - haproxy - stunnel - WireGuard - BusyBox (with SSL applets)
Example: Scan an Alpine-based nginx Container¶
# Pull and create container
docker pull nginx:alpine
docker create --name nginx-scan nginx:alpine
# Export and scan
mkdir -p /tmp/nginx-fs
docker export nginx-scan | tar -xf - -C /tmp/nginx-fs
docker rm nginx-scan
./build/cbom-generator \
--cross-arch \
--crypto-registry registry/crypto-registry-alpine.yaml \
--format cyclonedx --cyclonedx-spec 1.7 \
--output nginx-cbom.json \
/tmp/nginx-fs/usr/sbin \
/tmp/nginx-fs/usr/lib \
/tmp/nginx-fs/etc/nginx
rm -rf /tmp/nginx-fs
Scanning Specific Directories¶
For faster scans, target specific directories within the container:
# Scan only binaries and libraries (skip docs, locales, etc.)
./build/cbom-generator \
--cross-arch \
--crypto-registry registry/crypto-registry-alpine.yaml \
--output container-cbom.json \
/tmp/container-fs/usr/bin \
/tmp/container-fs/usr/sbin \
/tmp/container-fs/usr/lib \
/tmp/container-fs/etc
Common paths to scan:
| Path | Contents |
|---|---|
/usr/bin, /usr/sbin |
Application binaries |
/usr/lib |
Shared libraries |
/etc |
Configuration files, certificates |
/usr/local/bin |
Custom binaries |
/app or /opt |
Application code (varies) |
CI/CD Integration¶
GitHub Actions Example¶
name: Container CBOM Scan
on:
push:
branches: [main]
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build container
run: docker build -t myapp:latest .
- name: Export container filesystem
run: |
docker create --name scan-target myapp:latest
mkdir -p /tmp/container-fs
docker export scan-target | tar -xf - -C /tmp/container-fs
docker rm scan-target
- name: Run CBOM scan
run: |
./build/cbom-generator \
--cross-arch \
--crypto-registry registry/crypto-registry-alpine.yaml \
--format cyclonedx --cyclonedx-spec 1.7 \
--output container-cbom.json \
/tmp/container-fs
- name: Upload CBOM
uses: actions/upload-artifact@v4
with:
name: container-cbom
path: container-cbom.json
- name: Cleanup
run: rm -rf /tmp/container-fs
GitLab CI Example¶
container-cbom:
stage: security
image: docker:latest
services:
- docker:dind
script:
- docker build -t myapp:scan .
- docker create --name scan-target myapp:scan
- mkdir -p /tmp/container-fs
- docker export scan-target | tar -xf - -C /tmp/container-fs
- docker rm scan-target
- ./build/cbom-generator
--cross-arch
--crypto-registry registry/crypto-registry-alpine.yaml
--format cyclonedx --cyclonedx-spec 1.7
--output container-cbom.json
/tmp/container-fs
- rm -rf /tmp/container-fs
artifacts:
paths:
- container-cbom.json
One-Liner Script¶
For convenience, here's a reusable script:
#!/bin/bash
# scan-container.sh - Scan a container image for cryptographic assets
set -e
IMAGE="${1:?Usage: $0 <image:tag>}"
OUTPUT="${2:-cbom-$(echo $IMAGE | tr '/:' '-').json}"
WORKDIR=$(mktemp -d)
echo "Scanning image: $IMAGE"
echo "Output: $OUTPUT"
# Create and export
docker create --name cbom-scan-$$ "$IMAGE"
docker export cbom-scan-$$ | tar -xf - -C "$WORKDIR"
docker rm cbom-scan-$$
# Scan
./build/cbom-generator \
--cross-arch \
--crypto-registry registry/crypto-registry-alpine.yaml \
--format cyclonedx --cyclonedx-spec 1.7 \
--output "$OUTPUT" \
"$WORKDIR"
# Cleanup
rm -rf "$WORKDIR"
echo "CBOM written to: $OUTPUT"
Usage:
chmod +x scan-container.sh
./scan-container.sh nginx:alpine
./scan-container.sh redis:7-alpine redis-cbom.json
Security Considerations¶
- Temporary Files: Always clean up extracted filesystems after scanning
- Permissions: Use restrictive permissions on temp directories (
chmod 700) - Secrets: Container exports may contain secrets - handle with care
- Disk Space: Large images can consume significant space when extracted
Secure Workflow¶
# Create secure temp directory
WORKDIR=$(mktemp -d)
chmod 700 "$WORKDIR"
# ... export and scan ...
# Secure cleanup
rm -rf "$WORKDIR"
Troubleshooting¶
No Components Found¶
Problem: Scan returns empty or minimal results.
Solutions:
1. Verify the container has cryptographic libraries installed
2. Check you're scanning the right paths (binaries in /usr/bin, libs in /usr/lib)
3. Ensure the crypto registry matches the container's base image
# Verify crypto libraries exist
ls -la /tmp/container-fs/usr/lib/libcrypto* /tmp/container-fs/usr/lib/libssl*
Wrong Library Versions¶
Problem: Version detection shows incorrect versions.
Solution: In cross-arch mode, version detection uses ELF VERNEED symbols. This is expected behavior when the host package manager cannot be used.
Large Output File¶
Problem: CBOM file is very large.
Solution: Scan only relevant directories instead of the entire filesystem:
./build/cbom-generator --cross-arch \
/tmp/container-fs/usr/lib \
/tmp/container-fs/usr/bin \
/tmp/container-fs/etc/ssl
Limitations¶
-
Running Container Introspection: This workflow scans exported filesystems. It cannot introspect libraries of services running inside containers from the host. For running services, the container process is visible but its internal library dependencies are not accessible due to filesystem namespace isolation.
-
Multi-Stage Builds: Only the final image layer is scanned. Intermediate build stages are not included in the exported filesystem.
-
Scratch Images: Containers based on
scratchor distroless images may have minimal or no standard library paths.