Why Container Image Security Matters
As container-based infrastructure has become the norm, image security is a core challenge for modern DevSecOps. According to the 2024 Sysdig report, 87% of production containers contain High or more severe vulnerabilities, many of which can be fixed with a simple base-image update.
The attack surface falls into three main areas:
- At build time: Vulnerable base images, unnecessary packages, hardcoded secrets
- In the registry: Unsigned images, inadequate access control
- At runtime: Excessive privileges, sensitive mounts, abnormal process execution
Hardening the Build Stage
1. Use Minimal Base Images
# 나쁜 예 — 불필요한 패키지 포함
FROM ubuntu:22.04
# 좋은 예 — distroless로 최소화
FROM gcr.io/distroless/nodejs20-debian12
# 또는 Alpine 기반
FROM node:20-alpine3.19Alpine cuts the attack surface dramatically at around 5MB, and distroless does not even include a shell, which minimizes what an attacker can do if they compromise the container.
2. Multi-Stage Builds
# 빌드 스테이지
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# 프로덕션 스테이지 — 빌드 도구 제외
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER nonroot
EXPOSE 3000
CMD ["dist/server.js"]3. Never Run as Root
# 전용 비권한 사용자 생성
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuserIn Kubernetes, you can enforce this with PodSecurityContext:
securityContext:
runAsNonRoot: true
runAsUser: 1000
readOnlyRootFilesystem: true
allowPrivilegeEscalation: falseVulnerability Scanning: Practical Trivy Usage
Trivy is currently the most widely used open-source container scanner.
Basic Scanning
# 이미지 스캔
trivy image nginx:1.25
# 심각도 필터링 (HIGH, CRITICAL만)
trivy image --severity HIGH,CRITICAL nginx:1.25
# JSON 출력 (CI 파이프라인용)
trivy image --format json --output results.json myapp:latest
# 특정 CVE 무시 (false positive 처리)
trivy image --ignorefile .trivyignore myapp:latestCI/CD Integration (GitHub Actions)
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: ${{ env.IMAGE_TAG }}
format: sarif
output: trivy-results.sarif
severity: CRITICAL,HIGH
exit-code: 1 # 취약점 발견 시 빌드 실패
- name: Upload Trivy scan results
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: trivy-results.sarifGenerating an SBOM
An SBOM (Software Bill of Materials) inventories every component included in the image:
# CycloneDX 형식으로 SBOM 생성
trivy image --format cyclonedx --output sbom.json myapp:latest
# SPDX 형식
trivy image --format spdx-json --output sbom.spdx.json myapp:latestImage Signing: Cosign + Sigstore
# Cosign 설치 및 키 생성
cosign generate-key-pair
# 이미지 서명
cosign sign --key cosign.key registry.example.com/myapp:latest
# 서명 검증
cosign verify --key cosign.pub registry.example.com/myapp:latest
# keyless 서명 (OIDC 기반, GitHub Actions)
cosign sign --yes registry.example.com/myapp:${{ github.sha }}To allow only signed images in Kubernetes, use a Kyverno or OPA Gatekeeper policy:
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: verify-image-signature
spec:
validationFailureAction: Enforce
rules:
- name: check-image
match:
any:
- resources:
kinds: [Pod]
verifyImages:
- imageReferences: ["registry.example.com/*"]
attestors:
- count: 1
entries:
- keys:
publicKeys: |-
-----BEGIN PUBLIC KEY-----
...Runtime Security: Falco
Falco detects anomalous behavior in the container runtime in real time.
# falco-rules.yaml — 주요 탐지 규칙 예시
- rule: Terminal shell in container
desc: 컨테이너 내 셸 실행 탐지
condition: >
spawned_process and container and
proc.name in (shell_binaries)
output: >
Shell spawned in container (user=%user.name container=%container.name
image=%container.image.repository)
priority: WARNING
- rule: Write below etc
desc: /etc 디렉토리 쓰기 시도
condition: >
open_write and container and fd.directory=/etc
output: File opened for writing below /etc (user=%user.name file=%fd.name)
priority: ERRORRegistry Security Checklist
| Item | Recommended setting |
|---|---|
| Access control | RBAC + least privilege |
| Image scanning | Enable automatic scanning on push |
| Signing policy | Allow pull of signed images only |
| Vulnerable images | Auto-quarantine on CRITICAL findings |
| Audit logging | Record all pull/push events |
| Retention policy | Automatically delete old images |
Hardening Roadmap
- Apply immediately (1 week): Integrate Trivy into the CI pipeline; fail builds on CRITICAL vulnerabilities
- Short term (1 month): Multi-stage builds + migrate to distroless/Alpine; enforce non-root users
- Medium term (3 months): Introduce Cosign image signing; apply Kyverno signature-verification policies
- Long term (6 months): Falco runtime detection; complete automated SBOM generation and vulnerability tracking
Image security is not a one-time setup. New CVEs are published every day, so the key is building automation that periodically rescans deployed images and keeps base images up to date.
Vulnerability Scan Results Decision Table
When Trivy dumps hundreds of findings, trying to fix everything and ending up fixing nothing is the worst outcome.
| Situation | Assessment | Action |
|---|---|---|
| Critical + a fix is available | Respond immediately | Bump the base image/package version → rebuild and redeploy |
| Critical but no patch released | Assess exposure | Check whether the library is actually on the execution path — if unused, register an exception (expiration date required); if in use, document mitigations (e.g., network isolation) |
| Most vulnerabilities originate from the base image | Improve the structure | Replacing with a minimal image (distroless/Alpine) is more effective than patching individually |
| The same CVE reappears every week | Process problem | No periodic base-image rebuild pipeline (weekly) — automate it |
| Judged a false positive | Record the rationale | Register it in .trivyignore with comments for reason, reviewer, and expiration date |
Operations Checklist
- Document CI gate criteria — e.g., Critical = block, High = warn then remediate within 7 days
- Expiration dates on the exception (ignore) list — no permanent exceptions
- Verify that runtime image tags match scanned image tags (scanning
latestis meaningless) - Enforce signature verification at admission control — otherwise signing is meaningless
Frequently Asked Questions (FAQ)
Q. How do you verify container image security? A. (1) Vulnerability scanning — inspect OS and library CVEs with Trivy or Grype. (2) Image signature verification — sign and verify with Cosign to prevent tampering. (3) SBOM generation — inventory components. (4) Minimize the base image (distroless/slim) to shrink the attack surface. The key is gating scans in the CI pipeline so that a failed scan blocks deployment.
Q. When should you scan images? A. At all three stages: at build time (CI), after registry registration, and at runtime (periodic rescan). CVEs continue to be disclosed after deployment, so images that are already running must be revalidated periodically.
Nodelog는 모든 콘텐츠의 내용과 출처를 공개 전에 검토합니다. 환경(OS·버전)에 따라 결과가 달라질 수 있는 기술 정보는 공식 문서와 함께 확인하며, 검토 기준과 정정 원칙은 편집 정책에서 안내합니다. 오류를 발견하시면 이메일로 제보해 주세요 — 확인 후 신속히 정정합니다.
Comments
Be the first to comment.