Iโll show you how to manage container compliance in Alpine Linux! This ensures your containers meet security standards and regulations. Itโs crucial for keeping your containerized apps safe and compliant!
๐ค What is Container Compliance?
Container compliance means making sure your containers follow security rules and best practices. Think of it like a safety inspection for your containers - checking theyโre built properly, configured securely, and running safely. This is essential for production environments!
Why manage compliance?
- Meet regulatory requirements
- Prevent security breaches
- Ensure consistent standards
- Pass security audits
- Build trust with users
๐ฏ What You Need
Before starting, youโll need:
- Alpine Linux installed
- Docker or Podman installed
- Basic container knowledge
- Root access
- About 20 minutes
๐ Step 1: Install Compliance Tools
Letโs get the tools we need:
# Update packages
apk update
# Install Docker (if not installed)
apk add docker docker-cli docker-compose
# Or install Podman
apk add podman
# Install scanning tools
apk add git curl bash
# Install Python for tools
apk add python3 py3-pip
# Install OpenSCAP for compliance
apk add openscap openscap-utils
# Start Docker service
rc-update add docker
rc-service docker start
๐ Step 2: Set Up Container Scanning
Install container security scanners:
# Install Trivy for vulnerability scanning
wget https://github.com/aquasecurity/trivy/releases/download/v0.45.0/trivy_0.45.0_Linux-64bit.tar.gz
tar zxvf trivy_0.45.0_Linux-64bit.tar.gz
mv trivy /usr/local/bin/
chmod +x /usr/local/bin/trivy
# Install Docker Bench for security checks
git clone https://github.com/docker/docker-bench-security.git
cd docker-bench-security
# Install Anchore for policy scanning
pip3 install anchorecli
# Verify installations
trivy --version
๐ Step 3: Create Compliance Policies
Set up your compliance rules:
# Create compliance directory
mkdir -p /etc/container-compliance/policies
cd /etc/container-compliance
# Create base security policy
cat > policies/base-security.json << 'EOF'
{
"name": "base-security-policy",
"version": "1.0",
"rules": [
{
"id": "no-root-user",
"description": "Containers must not run as root",
"severity": "HIGH",
"check": "user != root"
},
{
"id": "no-privileged",
"description": "No privileged containers allowed",
"severity": "CRITICAL",
"check": "privileged == false"
},
{
"id": "readonly-rootfs",
"description": "Root filesystem should be read-only",
"severity": "MEDIUM",
"check": "readOnlyRootFilesystem == true"
},
{
"id": "no-new-privileges",
"description": "Prevent privilege escalation",
"severity": "HIGH",
"check": "noNewPrivileges == true"
}
]
}
EOF
# Create allowed base images list
cat > policies/allowed-images.txt << 'EOF'
alpine:latest
alpine:3.18
nginx:alpine
redis:alpine
postgres:alpine
EOF
๐ Step 4: Implement Scanning Script
Create automated compliance checking:
# Create compliance scanner
cat > /usr/local/bin/check-container-compliance.sh << 'EOF'
#!/bin/bash
# Container Compliance Checker
IMAGE="${1:-}"
REPORT_DIR="/var/log/compliance"
mkdir -p "$REPORT_DIR"
if [ -z "$IMAGE" ]; then
echo "Usage: $0 <image:tag>"
exit 1
fi
echo "๐ Checking compliance for: $IMAGE"
echo "=================================="
# 1. Vulnerability Scan
echo "๐ Running vulnerability scan..."
trivy image --severity HIGH,CRITICAL "$IMAGE" > "$REPORT_DIR/vuln-scan.txt"
VULN_COUNT=$(grep -c "Total:" "$REPORT_DIR/vuln-scan.txt" || echo "0")
# 2. Check Dockerfile best practices
echo "๐ Checking image configuration..."
docker inspect "$IMAGE" > "$REPORT_DIR/inspect.json"
# Check if running as root
USER=$(docker inspect "$IMAGE" | jq -r '.[0].Config.User')
if [ -z "$USER" ] || [ "$USER" = "root" ]; then
echo "โ FAIL: Container runs as root user"
else
echo "โ
PASS: Container runs as non-root user ($USER)"
fi
# Check for exposed ports
PORTS=$(docker inspect "$IMAGE" | jq -r '.[0].Config.ExposedPorts | keys[]' 2>/dev/null)
if [ -n "$PORTS" ]; then
echo "โ ๏ธ WARNING: Exposed ports: $PORTS"
fi
# 3. Check against allowed base images
echo "๐ Checking base image..."
BASE_IMAGE=$(docker inspect "$IMAGE" | jq -r '.[0].Config.Labels."org.opencontainers.image.base.name"' 2>/dev/null)
# 4. Security capabilities check
echo "๐ Checking security settings..."
# Check for dangerous capabilities
CAPS=$(docker inspect "$IMAGE" | jq -r '.[0].Config.Labels."org.label-schema.docker.caps"' 2>/dev/null)
# Generate report
cat > "$REPORT_DIR/compliance-report.txt" << REPORT
Container Compliance Report
==========================
Date: $(date)
Image: $IMAGE
User: $USER
Vulnerabilities: $VULN_COUNT
Base Image: ${BASE_IMAGE:-Unknown}
Compliance Status:
- Root User Check: $([ -z "$USER" ] || [ "$USER" = "root" ] && echo "FAIL" || echo "PASS")
- Vulnerability Check: $([ "$VULN_COUNT" -gt 0 ] && echo "FAIL" || echo "PASS")
- Exposed Ports: $([ -n "$PORTS" ] && echo "WARNING" || echo "PASS")
Details in: $REPORT_DIR/
REPORT
echo ""
echo "๐ Report saved to: $REPORT_DIR/compliance-report.txt"
EOF
chmod +x /usr/local/bin/check-container-compliance.sh
๐ Step 5: Runtime Compliance Monitoring
Monitor running containers:
# Create runtime monitor
cat > /usr/local/bin/monitor-containers.sh << 'EOF'
#!/bin/bash
# Runtime Container Monitor
echo "๐ Monitoring running containers..."
echo "==================================="
# Check all running containers
for CONTAINER in $(docker ps -q); do
NAME=$(docker inspect $CONTAINER | jq -r '.[0].Name' | sed 's/^\///')
echo ""
echo "Container: $NAME"
# Check if running as root
USER=$(docker inspect $CONTAINER | jq -r '.[0].Config.User')
if [ -z "$USER" ] || [ "$USER" = "root" ]; then
echo " โ Running as root"
else
echo " โ
Running as user: $USER"
fi
# Check privileged mode
PRIV=$(docker inspect $CONTAINER | jq -r '.[0].HostConfig.Privileged')
if [ "$PRIV" = "true" ]; then
echo " โ Running in privileged mode"
else
echo " โ
Not privileged"
fi
# Check capabilities
CAPS=$(docker inspect $CONTAINER | jq -r '.[0].HostConfig.CapAdd[]' 2>/dev/null)
if [ -n "$CAPS" ]; then
echo " โ ๏ธ Added capabilities: $CAPS"
fi
# Check read-only root
RO=$(docker inspect $CONTAINER | jq -r '.[0].HostConfig.ReadonlyRootfs')
if [ "$RO" = "true" ]; then
echo " โ
Read-only root filesystem"
else
echo " โ ๏ธ Writable root filesystem"
fi
done
EOF
chmod +x /usr/local/bin/monitor-containers.sh
๐ Step 6: CIS Docker Benchmark
Run security benchmark checks:
# Run Docker Bench Security
cd /root/docker-bench-security
./docker-bench-security.sh > /var/log/compliance/docker-bench.txt
# Create custom CIS checks
cat > /usr/local/bin/cis-docker-check.sh << 'EOF'
#!/bin/bash
# CIS Docker Benchmark Checks
echo "๐ Running CIS Docker Benchmark..."
echo "================================="
# 2.1 Ensure network traffic is restricted
IPTABLES=$(iptables -L -n | grep -c DOCKER-USER)
echo "2.1 Network restrictions: $([ $IPTABLES -gt 0 ] && echo "โ
PASS" || echo "โ FAIL")"
# 2.2 Ensure log level is set
LOG_LEVEL=$(docker info 2>/dev/null | grep -i "log level" | awk '{print $NF}')
echo "2.2 Log level configured: $([ -n "$LOG_LEVEL" ] && echo "โ
PASS" || echo "โ ๏ธ WARNING")"
# 2.3 Ensure Docker content trust
CONTENT_TRUST=${DOCKER_CONTENT_TRUST:-0}
echo "2.3 Content trust: $([ "$CONTENT_TRUST" = "1" ] && echo "โ
PASS" || echo "โ FAIL")"
# 2.4 Ensure auditd is installed
AUDITD=$(which auditd 2>/dev/null)
echo "2.4 Audit daemon: $([ -n "$AUDITD" ] && echo "โ
PASS" || echo "โ FAIL")"
# 2.5 Ensure containers are not run as root
ROOT_CONTAINERS=$(docker ps -q | xargs -I {} docker inspect {} | jq -r 'select(.[0].Config.User == "" or .[0].Config.User == "root") | .[0].Name' | wc -l)
echo "2.5 Non-root containers: $([ "$ROOT_CONTAINERS" -eq 0 ] && echo "โ
PASS" || echo "โ FAIL ($ROOT_CONTAINERS running as root)")"
EOF
chmod +x /usr/local/bin/cis-docker-check.sh
๐ Step 7: Automated Compliance Pipeline
Set up CI/CD compliance checks:
# Create pre-deployment check
cat > /usr/local/bin/pre-deploy-compliance.sh << 'EOF'
#!/bin/bash
# Pre-deployment Compliance Check
IMAGE="$1"
NAMESPACE="${2:-default}"
echo "๐ Pre-deployment compliance check"
echo "================================="
echo "Image: $IMAGE"
echo "Namespace: $NAMESPACE"
echo ""
# Run all checks
FAILED=0
# 1. Vulnerability scan
echo "1. Vulnerability Scan"
trivy image --exit-code 1 --severity CRITICAL "$IMAGE"
[ $? -ne 0 ] && FAILED=$((FAILED + 1))
# 2. Policy compliance
echo ""
echo "2. Policy Compliance"
/usr/local/bin/check-container-compliance.sh "$IMAGE"
# 3. Image signature verification
echo ""
echo "3. Image Signature"
if [ "$DOCKER_CONTENT_TRUST" = "1" ]; then
docker trust inspect "$IMAGE" > /dev/null 2>&1
[ $? -ne 0 ] && FAILED=$((FAILED + 1)) && echo "โ Image not signed"
else
echo "โ ๏ธ Content trust not enabled"
fi
# 4. Check against blocklist
echo ""
echo "4. Blocklist Check"
BLOCKED_IMAGES="ubuntu:latest debian:latest"
for BLOCKED in $BLOCKED_IMAGES; do
if [[ "$IMAGE" == *"$BLOCKED"* ]]; then
echo "โ Image is blocklisted: $BLOCKED"
FAILED=$((FAILED + 1))
fi
done
# Final verdict
echo ""
echo "================================="
if [ $FAILED -eq 0 ]; then
echo "โ
All compliance checks PASSED"
exit 0
else
echo "โ $FAILED compliance checks FAILED"
echo "Deployment blocked!"
exit 1
fi
EOF
chmod +x /usr/local/bin/pre-deploy-compliance.sh
๐ Step 8: Compliance Dashboard
Create a simple compliance dashboard:
# Create dashboard generator
cat > /usr/local/bin/compliance-dashboard.sh << 'EOF'
#!/bin/bash
# Generate Compliance Dashboard
DASHBOARD="/var/www/compliance/index.html"
mkdir -p /var/www/compliance
cat > "$DASHBOARD" << 'HTML'
<!DOCTYPE html>
<html>
<head>
<title>Container Compliance Dashboard</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
.pass { color: green; }
.fail { color: red; }
.warning { color: orange; }
table { border-collapse: collapse; width: 100%; }
th, td { border: 1px solid #ddd; padding: 8px; text-align: left; }
th { background-color: #f2f2f2; }
</style>
</head>
<body>
<h1>๐ Container Compliance Dashboard</h1>
<p>Last updated: <span id="timestamp"></span></p>
<h2>Running Containers</h2>
<div id="containers"></div>
<h2>Recent Scans</h2>
<div id="scans"></div>
<script>
document.getElementById('timestamp').textContent = new Date().toLocaleString();
// Add auto-refresh
setTimeout(() => location.reload(), 60000);
</script>
</body>
</html>
HTML
echo "Dashboard created at: $DASHBOARD"
EOF
chmod +x /usr/local/bin/compliance-dashboard.sh
# Add to cron for regular updates
echo "*/5 * * * * /usr/local/bin/monitor-containers.sh > /var/www/compliance/status.txt" | crontab -
๐ฎ Practice Exercise
Try these compliance tasks:
- Scan a container image
- Fix compliance issues
- Create custom policies
- Monitor compliance
# Practice with nginx
docker pull nginx:alpine
# Check compliance
/usr/local/bin/check-container-compliance.sh nginx:alpine
# Create compliant Dockerfile
cat > Dockerfile.compliant << 'EOF'
FROM alpine:3.18
RUN adduser -D -H appuser
USER appuser
WORKDIR /app
COPY --chown=appuser:appuser . .
EXPOSE 8080
CMD ["./app"]
EOF
# Build and scan
docker build -t myapp:compliant -f Dockerfile.compliant .
/usr/local/bin/check-container-compliance.sh myapp:compliant
๐จ Troubleshooting Common Issues
Scanner Not Working
Fix scanning issues:
# Update Trivy database
trivy image --download-db-only
# Check Docker socket
ls -la /var/run/docker.sock
# Test with simple scan
trivy image alpine:latest
# Check permissions
chmod 666 /var/run/docker.sock
False Positives
Handle incorrect findings:
# Create exceptions file
cat > /etc/container-compliance/exceptions.json << 'EOF'
{
"CVE-2023-1234": {
"reason": "False positive - not applicable",
"approved_by": "security-team",
"date": "2025-06-13"
}
}
EOF
# Update scanner to use exceptions
trivy image --ignorefile /etc/container-compliance/exceptions.json nginx:alpine
Policy Conflicts
Resolve policy issues:
# Debug policy evaluation
docker inspect nginx:alpine | jq '.[] | {User: .Config.User, Env: .Config.Env}'
# Test specific policies
/usr/local/bin/check-container-compliance.sh nginx:alpine | grep -E "PASS|FAIL"
# Adjust policies as needed
nano /etc/container-compliance/policies/base-security.json
๐ก Pro Tips
Tip 1: Shift-Left Security
Scan early in development:
# Add to CI pipeline
cat > .gitlab-ci.yml << 'EOF'
stages:
- build
- scan
- deploy
scan:
stage: scan
script:
- trivy image --exit-code 1 --severity HIGH,CRITICAL $CI_IMAGE_TAG
- /usr/local/bin/pre-deploy-compliance.sh $CI_IMAGE_TAG
EOF
Tip 2: Custom Policies
Create organization-specific rules:
# Industry-specific policy
cat > policies/healthcare-compliance.json << 'EOF'
{
"name": "HIPAA-compliance",
"rules": [
{
"id": "encryption-at-rest",
"check": "volume.encrypted == true"
},
{
"id": "audit-logging",
"check": "logging.enabled == true"
}
]
}
EOF
Tip 3: Compliance as Code
Version control your policies:
cd /etc/container-compliance
git init
git add .
git commit -m "Initial compliance policies"
โ Best Practices Summary
-
Scan everything
- Base images
- Built images
- Running containers
-
Automate checks
- Pre-deployment
- Runtime monitoring
- Regular audits
-
Fix issues early
- Secure base images
- Non-root users
- Minimal privileges
-
Document everything
- Policy exceptions
- Approval process
- Audit trails
๐ What You Learned
Excellent work! You can now:
- โ Set up compliance scanning
- โ Create security policies
- โ Monitor container compliance
- โ Automate security checks
- โ Generate compliance reports
Your containers are now secure and compliant!
๐ฏ Whatโs Next?
Now that you understand compliance, explore:
- Advanced policy engines
- SIEM integration
- Kubernetes compliance
- Runtime protection
Keep your containers secure and compliant! ๐