AgentSkillsCN

security-docker

审查Docker与容器的安全审计模式。无论是镜像分层中的密钥管理、端口暴露,还是非root用户权限,此功能都能帮你全面审视Docker安全。当Dockerfile或docker-compose.yml文件存在时,此功能更应主动运用。 示例: - 用户输入:“审计这个Dockerfile” → 检查ENV/ARG中的密钥,以及非root USER的使用 - 用户输入:“审查docker-compose的端口” → 查找意外暴露的数据库端口 - 用户输入:“检查镜像历史中的密钥” → 审查各层与构建产物 - 用户输入:“优化Docker安全” → 实施多阶段构建,选用最小化的基础镜像 - 用户输入:“审计容器权限” → 检查是否设置了privileged: true,或挂载了docker.sock

SKILL.md
--- frontmatter
name: security-docker
description: |-
  Review Docker and container security audit patterns. Use for auditing secrets in layers, port exposure, and non-root users. Use proactively when Dockerfile or docker-compose.yml is present.
  Examples:
  - user: "Audit this Dockerfile" → check for secrets in ENV/ARG and non-root USER
  - user: "Review docker-compose ports" → find accidentally exposed databases
  - user: "Check for secrets in image history" → audit layers and build artifacts
  - user: "Optimize Docker security" → implement multi-stage builds and minimal base images
  - user: "Audit container privileges" → check for privileged: true or docker.sock mounts
<overview>

Security audit patterns for Docker and container deployments covering secrets in images, port exposure, user privileges, and compose security.

</overview> <vulnerabilities>

Secrets in Images (Critical)

Secrets in Build Args/ENV

dockerfile
# CRITICAL: Secret in ENV (visible in image history) - MUST NOT do this
ENV API_KEY=sk_live_abc123
ENV DATABASE_URL=postgres://user:password@host/db

# CRITICAL: Secret in ARG (visible in image history) - MUST NOT do this
ARG AWS_SECRET_ACCESS_KEY
RUN aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY

# MUST use runtime secrets
# Pass via docker run -e or docker-compose environment/env_file

# SHOULD use Docker secrets (Swarm) or orchestrator-specific secrets
# Use /run/secrets/* instead of ENV/ARG when available

Secrets Baked into Layers

dockerfile
# CRITICAL: Even if deleted, secret is in layer history - MUST NOT do this
COPY .env /app/.env
RUN source /app/.env && do_something
RUN rm /app/.env  # Still in previous layer!

# CRITICAL: Copying all files includes secrets - MUST NOT do this
COPY . /app/  # Copies .env, .git, etc.

# MUST use .dockerignore
# In .dockerignore:
# .env*
# .git
# *.pem
# *.key

# MAY use explicit COPY
COPY package*.json /app/
COPY src/ /app/src/

Checking Image History

bash
# SHOULD audit existing images for secrets
docker history --no-trunc <image>
docker inspect <image> | jq '.[0].Config.Env'

Port Exposure

docker-compose.yml

yaml
# CRITICAL: Database exposed to host network - MUST NOT do this
services:
  db:
    image: postgres
    ports:
      - "5432:5432"  # Accessible from outside!

# CRITICAL: Redis without password - MUST NOT do this
  redis:
    image: redis
    ports:
      - "6379:6379"  # And no AUTH!

# SHOULD use internal only (accessible to other containers)
services:
  db:
    image: postgres
    expose:
      - "5432"  # Only internal
    # No 'ports' = not exposed to host

# If must expose, MUST bind to localhost
  db:
    ports:
      - "127.0.0.1:5432:5432"  # Only localhost

Default Credentials

yaml
# No password or default password - MUST NOT do this
services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: postgres  # Default!

  redis:
    image: redis
    # No password at all

# MUST use strong passwords from secrets
services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD_FILE: /run/secrets/db_password
    secrets:
      - db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt  # MUST NOT be in git!

Non-Root User

dockerfile
# Running as root (default) - SHOULD NOT do this
FROM node:18
COPY . /app
CMD ["node", "server.js"]  # Runs as root

# SHOULD create and use non-root user
FROM node:18
WORKDIR /app
COPY --chown=node:node . .
USER node
CMD ["node", "server.js"]

# MAY use numeric UID (more portable)
FROM node:18
RUN useradd -r -u 1001 appuser
WORKDIR /app
COPY --chown=1001:1001 . .
USER 1001
CMD ["node", "server.js"]

Multi-Stage Builds

dockerfile
# Build tools and secrets in final image - SHOULD NOT do this
FROM node:18
COPY . .
RUN npm install
RUN npm run build
CMD ["node", "dist/server.js"]
# Final image has: source, node_modules (dev deps), build tools

# SHOULD use multi-stage: only production artifacts
FROM node:18 AS builder
WORKDIR /app
COPY package*.json .
RUN npm ci
COPY . .
RUN npm run build

FROM node:18-slim AS production
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
USER node
CMD ["node", "dist/server.js"]
# Final image: minimal, no source, no build tools

Docker Compose Security

Privileged Mode

yaml
# CRITICAL: Full host access - MUST NOT do this
services:
  app:
    privileged: true  # Container can do anything on host!

# HIGH: Dangerous capabilities - SHOULD NOT do this without justification
services:
  app:
    cap_add:
      - SYS_ADMIN
      - NET_ADMIN

Volume Mounts

yaml
# CRITICAL: Docker socket access = root on host - MUST NOT do this unless required
services:
  app:
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

# HIGH: Sensitive host paths - MUST NOT do this
services:
  app:
    volumes:
      - /etc:/etc
      - /root:/root

Network Mode

yaml
# HIGH: Host network mode - SHOULD NOT do this without justification
services:
  app:
    network_mode: host  # Bypasses Docker network isolation

Image Security

Base Image

dockerfile
# Outdated or unverified - MUST NOT do this
FROM node:14  # EOL version
FROM random-user/node-app  # Unverified

# MUST use official, recent, minimal
FROM node:20-slim
FROM node:20-alpine

Image Scanning

bash
# SHOULD scan for vulnerabilities
docker scout cves <image>
trivy image <image>
grype <image>
</vulnerabilities> <commands>

Quick Audit Commands

bash
# Find secrets in Dockerfile
rg "(ENV|ARG).*(KEY|SECRET|PASSWORD|TOKEN)" Dockerfile*

# Find exposed ports in compose
rg "ports:" docker-compose*.yml -A 3

# Check for privileged/capabilities
rg "(privileged|cap_add|network_mode)" docker-compose*.yml

# Check for docker.sock mount
rg "docker.sock" docker-compose*.yml

# Check for USER instruction
grep "^USER" Dockerfile

# Check .dockerignore exists and has secrets
cat .dockerignore | grep -E "(env|key|secret|pem)"
</commands> <checklist>

Hardening Checklist

  • MUST NOT have secrets in ENV/ARG instructions
  • MUST NOT have secrets COPY'd into image
  • .dockerignore MUST exclude .env, .git, *.pem, *.key
  • Database/Redis ports MUST NOT be exposed to host (or only 127.0.0.1)
  • MUST have strong passwords for all services (not defaults)
  • USER instruction SHOULD set non-root user
  • SHOULD use multi-stage build for production images
  • MUST NOT have privileged: true
  • MUST NOT have docker.sock mount (unless required)
  • Base images MUST be official and recent
  • Images SHOULD be scanned for vulnerabilities
</checklist>