mcpField
S
security-docker

security-docker

github.com/igorwarzochaセキュリティ122117 回インストール38 週間前に更新
リポジトリ

security-docker について

Docker とコンテナ環境のセキュリティ監査向けスキルです。Dockerfile や Compose 設定を確認する開発者を対象に、イメージ内のシークレット、ポート、権限、マウント、ネットワーク、脆弱性スキャンを扱い、監査コマンドと強化チェックリストを示します。

主な機能

  1. 01イメージビルド時のシークレット確認
  2. 02公開ポートとデフォルト認証情報の点検
  3. 03非 root ユーザーと特権設定の確認
  4. 04マウントとネットワーク分離リスクの評価
  5. 05イメージ脆弱性スキャン用コマンド
  6. 06セキュリティ強化チェックリスト

活用シーン

  1. 01リリース前の Docker イメージビルド設定の確認
  2. 02Compose サービスのデータベースポート公開の点検
  3. 03コンテナ権限や機密マウントのリスク調査
  4. 04イメージのスキャンと強化項目の確認

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/igorwarzocha/opencode-workflows --skill security-docker

インストール後、Claude Code で/security-dockerを入力して読み込まれたか確認します。

同梱ファイルscripts/scan.sh

詳細

Docker とコンテナのデプロイにおける、イメージ内のシークレット、ポートの公開、ユーザー権限、Compose のセキュリティに関するセキュリティ監査パターンです。

イメージ内のシークレット(重大)

ビルド引数/ENV 内のシークレット
# ❌ CRITICAL: Secret in ENV (visible in image history)
ENV API_KEY=sk_live_abc123
ENV DATABASE_URL=postgres://user:password@host/db

# ❌ CRITICAL: Secret in ARG (visible in image history)
ARG AWS_SECRET_ACCESS_KEY
RUN aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY

# ✓ Use runtime secrets
# Pass via docker run -e or docker-compose environment/env_file

# ✓ Docker secrets (Swarm) or orchestrator-specific secrets
# Use /run/secrets/* instead of ENV/ARG when available
レイヤーに埋め込まれたシークレット
# ❌ CRITICAL: Even if deleted, secret is in layer history
COPY .env /app/.env
RUN source /app/.env && do_something
RUN rm /app/.env  # Still in previous layer!

# ❌ CRITICAL: Copying all files includes secrets
COPY . /app/  # Copies .env, .git, etc.

# ✓ Use .dockerignore
# In .dockerignore:
# .env*
# .git
# *.pem
# *.key

# ✓ Or explicit COPY
COPY package*.json /app/
COPY src/ /app/src/
イメージの履歴を確認する
# Audit existing images for secrets
docker history --no-trunc <image>
docker inspect <image> | jq '.[0].Config.Env'

ポートの公開

docker-compose.yml
# ❌ CRITICAL: Database exposed to host network
services:
  db:
    image: postgres
    ports:
      - "5432:5432"  # Accessible from outside!

# ❌ CRITICAL: Redis without password
  redis:
    image: redis
    ports:
      - "6379:6379"  # And no AUTH!

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

# ✓ If must expose, bind to localhost
  db:
    ports:
      - "127.0.0.1:5432:5432"  # Only localhost
デフォルトの認証情報
# ❌ No password or default password
services:
  db:
    image: postgres
    environment:
      POSTGRES_PASSWORD: postgres  # Default!

  redis:
    image: redis
    # No password at all

# ✓ 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!

root 以外のユーザー

# ❌ Running as root (default)
FROM node:18
COPY . /app
CMD ["node", "server.js"]  # Runs as root

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

# ✓ Using 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"]

マルチステージビルド

# ❌ Build tools and secrets in final image
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

# ✓ 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 のセキュリティ

特権モード
# ❌ CRITICAL: Full host access
services:
  app:
    privileged: true  # Container can do anything on host!

# ❌ HIGH: Dangerous capabilities
services:
  app:
    cap_add:
      - SYS_ADMIN
      - NET_ADMIN
ボリュームのマウント
# ❌ CRITICAL: Docker socket access = root on host
services:
  app:
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock

# ❌ HIGH: Sensitive host paths
services:
  app:
    volumes:
      - /etc:/etc
      - /root:/root
ネットワークモード
# ❌ HIGH: Host network mode
services:
  app:
    network_mode: host  # Bypasses Docker network isolation

イメージのセキュリティ

ベースイメージ
# ❌ Outdated or unverified
FROM node:14  # EOL version
FROM random-user/node-app  # Unverified

# ✓ Official, recent, minimal
FROM node:20-slim
FROM node:20-alpine
イメージのスキャン
# Scan for vulnerabilities
docker scout cves <image>
trivy image <image>
grype <image>

クイック監査コマンド

# 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)"

セキュリティ強化チェックリスト

  • ENV/ARG 命令にシークレットが含まれていない
  • COPY でイメージにシークレットを追加していない
  • .dockerignore で .env、.git、.pem、.key を除外している
  • データベース/Redis のポートをホストに公開していない(または 127.0.0.1 のみに公開している)
  • すべてのサービスに強力なパスワードを設定している(デフォルトのままにしていない)
  • USER 命令で root 以外のユーザーを設定している
  • 本番用イメージにマルチステージビルドを使用している
  • privileged: true を設定していない
  • docker.sock をマウントしていない(必要な場合を除く)
  • ベースイメージが公式かつ最新である
  • イメージの脆弱性をスキャンしている

コメント