TL;DR
Master Docker security scanning with this comprehensive guide covering vulnerability scanning, compliance checks, and best practices for securing containerized applications
Docker Security Scanning: A Complete Guide to Container Security
Container security scanning is crucial for identifying vulnerabilities and ensuring compliance in containerized applications. This guide explores tools and best practices for implementing comprehensive security scanning in your Docker environment.
$1
`` graph TB
subgraph "Scanning Layers"
A["Base Image"]
B["Dependencies"]
C["Application Code"]
D["Configuration"]
end
subgraph "Security Tools"
E["Trivy"]
F["Snyk"]
G["Clair"]
H["Docker Scout"]
end
subgraph "Integration"
I["CI/CD Pipeline"]
J["Registry Scanning"]
K["Runtime Scanning"]
end
A --> E
B --> F
C --> G
D --> H
E --> I
F --> J
G --> K
H --> I
classDef security fill:#1a73e8,stroke:#fff,color:#fff
class A,B,C,D,E,F,G,H,I,J,K security
mermaid
`
$1
| Tool | Features | Best For |
|---|---|---|
| Trivy | Comprehensive scanning | General use |
| Snyk | Deep dependency analysis | Application security |
| Clair | Container scanning | Enterprise |
$1
$1
` name: Security Scan on:
push:
branches: [ main ]
pull_request:
branches: [ main ] jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: 'docker.io/my-organization/my-app:${{ github.sha }}'
format: 'table'
exit-code: '1'
ignore-unfixed: true
vuln-type: 'os,library'
severity: 'CRITICAL,HIGH'
yaml
`.github/workflows/security-scan.yml
$1
` // snyk.config.js
module.exports = {
docker: {
baseImage: 'node:16-alpine',
dockerfilePath: './Dockerfile',
excludeBaseImageVulns: false,
severityThreshold: 'high',
ignorePatterns: [
'SNYK-DEBIAN-OPENSSL-*',
'SNYK-ALPINE-OPENSSL-*'
]
},
failOnIssues: true,
org: 'my-org-name'
};
typescript
`
$1
$1
` scan:
# Vulnerability scanning
vulnerability:
type:
- os
- library
ignore-unfixed: true
severity:
- CRITICAL
- HIGH
# Misconfiguration scanning
config:
include:
- kubernetes
- dockerfile
severity:
- CRITICAL
- HIGH
- MEDIUM
# Secret scanning
secret:
enable: true
yaml
`trivy.yaml
$1
| Policy | Description | Action |
|---|---|---|
| Critical CVEs | Block critical vulnerabilities | Fail build |
| Base Images | Use approved base images | Warn |
| Secrets | Detect hardcoded secrets | Fail build |
$1
$1
` name: Container Security on:
push:
branches: [ main ]
pull_request:
branches: [ main ] jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Scan with Trivy
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload scan results
uses: github/codeql-action/upload-sarif@v1
with:
sarif_file: 'trivy-results.sarif'
- name: Scan with Snyk
uses: snyk/actions/docker@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
image: myapp:${{ github.sha }}
args: --severity-threshold=high
yaml
`.github/workflows/container-security.yml
$1
` // Jenkinsfile
pipeline {
agent any
environment {
DOCKER_IMAGE = 'myapp:${BUILD_NUMBER}'
}
stages {
stage('Build') {
steps {
sh 'docker build -t ${DOCKER_IMAGE} .'
}
}
stage('Security Scan') {
parallel {
stage('Trivy') {
steps {
sh '''
trivy image \
--exit-code 1 \
--severity HIGH,CRITICAL \
--no-progress \
${DOCKER_IMAGE}
'''
}
}
stage('Snyk') {
steps {
snykSecurity(
snykInstallation: 'snyk',
snykTokenId: 'snyk-api-token',
targetFile: 'Dockerfile',
dockerImage: "${DOCKER_IMAGE}",
severity: 'high',
failOnIssues: true
)
}
}
}
}
}
}
groovy
`
$1
$1
` desc: Alert on shell execution in container
condition: >
container.id != host and
proc.name = bash
output: Shell executed in container (user=%user.name container=%container.name)
priority: WARNING desc: Package management execution in container
condition: >
container.id != host and
(proc.name = apt or proc.name = apk or proc.name = yum)
output: Package management command executed in container (user=%user.name command=%proc.cmdline)
priority: WARNING
yaml
`falco-rules.yaml
$1
| Metric | Description | Alert Threshold |
|---|---|---|
| File Changes | Unexpected modifications | Any change |
| Network Activity | Unusual connections | > 100/min |
| Process Execution | New processes | Any shell |
$1
$1
` #!/bin/bash docker run --rm -v /var:/var \
-v /usr/bin/docker:/usr/bin/docker \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc:/etc --label docker_bench_security \
docker/docker-bench-security docker run --rm \
-v $(pwd)/results:/results \
docker/docker-bench-security -l /results/bench.log
bash
`Run Docker Bench Security
Parse results
$1
| Check | Requirement | Validation |
|---|---|---|
| Root Access | No root containers | User directive |
| Image Signing | Signed images only | DCT verification |
| Network Access | Restricted ports | Port mapping |
$1
$1
1. Base Image Selection
` # Use specific version tags
FROM alpine:3.17.0
# Add security packages
RUN apk add --no-cache \
ca-certificates \
tzdata \
&& update-ca-certificates
# Create non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
dockerfile
`
2. Dependency Management
` {
"name": "secure-app",
"version": "1.0.0",
"dependencies": {
"express": "4.18.2"
},
"scripts": {
"security-audit": "npm audit",
"update-deps": "npm update"
}
}
json
``
$1
$1
| Issue | Cause | Solution |
|---|---|---|
| False Positives | Outdated DB | Update scanner |
| Scan Failures | Resource limits | Increase memory |
| Missing Results | Configuration | Check settings |
$1
1. [Docker Security Documentation](https://docs.docker.com/engine/security/)
2. [Trivy Documentation](https://aquasecurity.github.io/trivy/)
3. [Snyk Container Security](https://snyk.io/product/container-vulnerability-management/)
4. [CIS Docker Benchmark](https://www.cisecurity.org/benchmark/docker)
5. [Container Security Best Practices](https://sysdig.com/blog/container-security-best-practices/)
6. [NIST Container Security Guide](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-190.pdf)
$1
Why This Matters
Understanding the business and technical context helps you make informed decisions rather than blindly following patterns.
Trade-offs to Consider
Every architectural decision involves trade-offs. Consider your specific requirements, team expertise, and scale when evaluating options.
When NOT to Use This
Knowing when a solution doesn't apply is as valuable as knowing when it does. Consider alternatives for your specific situation.
Decision Framework
Use this framework to evaluate whether this approach is right for your use case based on your specific constraints and requirements.