コンテナセキュリティ実践ガイド:Docker・Kubernetesを安全に運用する方法

クラウド・インフラセキュリティ

※本記事にはアフィリエイトリンクが含まれます。詳しくはプライバシーポリシー・広告掲載についてをご覧ください。

「DockerコンテナやKubernetesを本番環境で使っているが、セキュリティ対策が不十分かもしれない」と感じたことはありませんか?コンテナ技術は開発効率を大幅に向上させる一方、適切なセキュリティ設定を怠ると深刻な侵害につながります。本記事では、コンテナ環境の脅威モデルから始まり、Dockerfile・Kubernetes・イメージスキャン・ランタイム保護まで、実践的なセキュリティ対策を体系的に解説します。DevSecOpsを実践したいエンジニアや、コンテナ環境のセキュリティ強化を担当するセキュリティ担当者に向けた内容です。

コンテナ環境の脅威モデル

コンテナセキュリティを考えるうえで、まず攻撃者がどのような経路で侵入・被害を拡大させるかを理解することが重要です。

主要な攻撃ベクター

  • 脆弱なベースイメージ: パッチ未適用のOSライブラリを含むイメージを使用することで、既知CVEを悪用される
  • コンテナエスケープ: Dockerデーモンの設定ミスや特権コンテナ(--privileged)により、ホストOSへの侵入が可能になる
  • サプライチェーン攻撃: 悪意のあるサードパーティイメージやパッケージの混入
  • シークレット漏洩: Dockerfileや環境変数にハードコードされたAPIキー・パスワード
  • ネットワーク横移動: コンテナ間通信の無制限許可による侵害の拡散
  • 過剰な権限: 不要なLinux Capabilitiesやroot実行による特権昇格

攻撃の典型的な流れ

攻撃者は通常、①脆弱なアプリケーション経由でコンテナ内に初期侵入し、②コンテナ内での権限昇格を試み、③コンテナエスケープでホストを掌握し、④クラスタ全体への横移動を行います。各段階でのセキュリティ対策が求められます。

Dockerfileセキュリティベストプラクティス

rootlessコンテナの実装

デフォルトではDockerコンテナはrootユーザとして実行されます。これは、コンテナエスケープが発生した際にホストOSをroot権限で掌握されるリスクを意味します。必ず非rootユーザを指定しましょう。

# NG: rootで実行(デフォルト)
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y myapp

# OK: 非rootユーザを作成して実行
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y myapp \
    && useradd -r -u 1001 -g root appuser
USER appuser
ENTRYPOINT ["myapp"]

マルチステージビルドによる攻撃面の削減

マルチステージビルドを使用することで、ビルドツール(gcc、makeなど)を最終イメージから除外し、攻撃面を大幅に削減できます。

# ビルドステージ(ビルドツールを含む)
FROM golang:1.21 AS builder
WORKDIR /app
COPY . .
RUN CGO_ENABLED=0 go build -o server .

# 実行ステージ(最小限のイメージ)
FROM gcr.io/distroless/static:nonroot
COPY --from=builder /app/server /server
USER nonroot:nonroot
ENTRYPOINT ["/server"]

distrolessイメージはシェルすら含まないため、攻撃者がコンテナ内に侵入しても有効なコマンドを実行できません。

読み取り専用ファイルシステム

コンテナのファイルシステムを読み取り専用にすることで、マルウェアの書き込みや設定ファイルの改ざんを防止できます。

# docker run時
docker run --read-only --tmpfs /tmp myapp

# docker-compose.yml
services:
  app:
    image: myapp
    read_only: true
    tmpfs:
      - /tmp
      - /var/run

シークレット管理の徹底

Dockerfileに認証情報をハードコードしてはいけません。ビルド時に使用するシークレットは--secretフラグで渡し、実行時はDocker SecretsやKubernetes Secretsを活用します。

# NG: Dockerfileに直書き
ENV DB_PASSWORD=mysecretpassword

# OK: ビルド時シークレット(Dockerfileに残らない)
# syntax=docker/dockerfile:1
RUN --mount=type=secret,id=db_password \
    DB_PASSWORD=$(cat /run/secrets/db_password) && mysetup

Kubernetesセキュリティ設定

NetworkPolicyによる通信制御

KubernetesはデフォルトでPod間の全通信を許可しています。NetworkPolicyを設定し、必要な通信のみを明示的に許可する「ゼロトラスト」アプローチを採用しましょう。

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-ingress
  namespace: production
spec:
  podSelector: {}
  policyTypes:
  - Ingress
  - Egress
---
# フロントエンドからバックエンドへの通信のみ許可
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-frontend-to-backend
spec:
  podSelector:
    matchLabels:
      app: backend
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: frontend
    ports:
    - protocol: TCP
      port: 8080

RBACによる最小権限の原則

Role-Based Access Control (RBAC) を適切に設定し、ServiceAccountに必要最小限の権限のみを付与します。cluster-admin権限の濫用は深刻なリスクです。

# 特定のnamespaceでのみPod読み取りを許可するRole
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: production
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods
  namespace: production
subjects:
- kind: ServiceAccount
  name: monitoring-sa
  namespace: production
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

Pod Security Standards

Kubernetes 1.25以降、Pod Security Admission (PSA) が標準化されています。restrictedプロファイルを適用することで、特権コンテナ・ホストNamespace使用・特権昇格を一括で防止できます。

# namespaceにrestricted profileを適用
apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    pod-security.kubernetes.io/enforce: restricted
    pod-security.kubernetes.io/enforce-version: latest
    pod-security.kubernetes.io/warn: restricted

SecurityContextの設定

apiVersion: v1
kind: Pod
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1001
    fsGroup: 2000
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL

コンテナイメージスキャン:TrivyとGrype

Trivyによる脆弱性スキャン

TrivyはAqua Securityが開発したオープンソースの脆弱性スキャナーです。OSパッケージ・言語パッケージ・設定ファイル・シークレットを包括的にスキャンできます。

# イメージスキャン
trivy image nginx:latest

# 重大度HIGHとCRITICALのみ表示
trivy image --severity HIGH,CRITICAL myapp:latest

# CI/CD組み込み(終了コードで合否判定)
trivy image --exit-code 1 --severity CRITICAL myapp:latest

# Dockerfile/設定ファイルスキャン(IaC)
trivy config ./k8s/

# シークレットスキャン
trivy fs --scanners secret .

Grypeによる補完スキャン

GrypeはAnchoreが提供するイメージスキャナーで、SBOMファイルからの脆弱性評価が得意です。Trivyと組み合わせて使用することで検出漏れを最小化できます。

# イメージスキャン
grype myapp:latest

# SBOMから脆弱性評価
syft myapp:latest -o cyclonedx-json > sbom.json
grype sbom:sbom.json

CI/CDパイプラインへの統合

スキャンはビルド時だけでなく、定期的にも実行することが重要です。依存ライブラリの新たなCVEは日々公開されます。

# GitHub Actions例
- name: Scan image with Trivy
  uses: aquasecurity/trivy-action@master
  with:
    image-ref: 'myapp:${{ github.sha }}'
    format: 'sarif'
    output: 'trivy-results.sarif'
    severity: 'CRITICAL,HIGH'
    exit-code: '1'

ランタイム保護:FalcoとSeccomp

Falcoによる異常検知

FalcoはCNCFのランタイムセキュリティツールで、Linuxカーネルのシステムコールを監視し、不審な挙動をリアルタイムで検知します。

# Helmでインストール
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm install falco falcosecurity/falco \
  --namespace falco --create-namespace \
  --set falco.jsonOutput=true \
  --set falco.logLevel=info

# カスタムルール例(コンテナ内でのシェル実行を検知)
- rule: Shell spawned in container
  desc: A shell was spawned in a container
  condition: >
    spawned_process and container
    and shell_procs
    and not user_known_shell_spawn_activities
  output: >
    Shell spawned in container
    (user=%user.name container=%container.name
    image=%container.image.repository shell=%proc.name)
  priority: WARNING

Seccompプロファイルによるシステムコール制限

seccomp(Secure Computing Mode)は、コンテナが使用できるシステムコールをホワイトリスト方式で制限します。不要なシステムコールをブロックすることで、エクスプロイトの影響範囲を大幅に縮小できます。

# カスタムseccompプロファイル例(必要最小限のsyscallのみ許可)
{
  "defaultAction": "SCMP_ACT_ERRNO",
  "syscalls": [
    {
      "names": ["read", "write", "open", "close", "stat",
                "fstat", "mmap", "mprotect", "munmap",
                "brk", "rt_sigaction", "rt_sigprocmask",
                "ioctl", "access", "execve", "exit",
                "wait4", "kill", "uname", "fcntl",
                "gettimeofday", "getpid", "clone",
                "socket", "connect", "accept", "sendto",
                "recvfrom", "shutdown", "bind", "listen",
                "getsockname", "getpeername", "setsockopt",
                "getsockopt", "exit_group", "epoll_wait",
                "epoll_ctl", "tgkill", "openat", "getdents64",
                "set_robust_list", "futex", "nanosleep"],
      "action": "SCMP_ACT_ALLOW"
    }
  ]
}

コンテナセキュリティ実践チェックリスト

Dockerfileチェック項目

  • ☑ 非rootユーザ(USER命令)を指定している
  • ☑ マルチステージビルドでビルドツールを除外している
  • ☑ distroless/alpineなど最小ベースイメージを使用している
  • --no-cacheでパッケージキャッシュを含めない
  • ☑ シークレットをDockerfileにハードコードしていない
  • .dockerignoreで不要ファイルを除外している
  • ☑ ベースイメージのダイジェスト(SHA256)をピン留めしている

Kubernetesチェック項目

  • ☑ NetworkPolicyでPod間通信を制限している
  • ☑ RBACで最小権限ServiceAccountを設定している
  • ☑ Pod Security StandardsのrestrictedプロファイルをNamespaceに適用している
  • allowPrivilegeEscalation: falseを設定している
  • readOnlyRootFilesystem: trueを設定している
  • ☑ 不要なCapabilitiesをすべてdropしている
  • ☑ Secretsを環境変数ではなくボリュームマウントで渡している
  • ☑ EtcdのSecret暗号化(Encryption at Rest)を有効化している

継続的セキュリティチェック項目

  • ☑ CI/CDパイプラインにTrivyスキャンを組み込んでいる
  • ☑ コンテナレジストリで定期スキャンを設定している
  • ☑ Falcoでランタイム異常を監視している
  • ☑ Kubernetes APIサーバの監査ログを有効化している
  • ☑ コンテナイメージの署名(cosign/Notary)を実施している

おすすめセキュリティ対策ツール

本記事で紹介した対策を実施するうえで役立つ製品をご紹介します。

🛡️ まず今日から始めるなら:エンドポイント保護ソフトの導入
コンテナ環境のセキュリティ強化と並行して、開発端末・踏み台サーバへのエンドポイント保護も欠かせません。信頼性の高いセキュリティソフトの導入を強くお勧めします。

※ 上記はアフィリエイトリンクです。料金・機能は各公式サイトで必ずご確認ください。

📋 無料配布:AIセキュリティ対策チェックリスト

中小企業・個人向け。今すぐできる30項目のセキュリティ確認リストを無料配布中。

無料でチェックリストを受け取る →

まとめ:コンテナセキュリティは多層防御で

  • Dockerfileでは非root・マルチステージ・read-onlyを基本とする
  • KubernetesはNetworkPolicy・RBAC・Pod Security Standardsで最小権限を徹底する
  • TrivyやGrypeでCI/CDにスキャンを組み込み、既知CVEを継続的に排除する
  • FalcoとSeccompでランタイムの異常行動を検知・ブロックする
  • セキュリティは一度設定して終わりではなく、継続的な監視と改善が必要

コンテナ技術の普及に伴い、攻撃者も専門的な手法を用いるようになっています。本記事のチェックリストを参考に、自社のコンテナ環境のセキュリティ体制を見直してみてください。

参考資料情報セキュリティ10大脅威 2026(IPA) / 内閣サイバーセキュリティセンター(NISC)

コメント

タイトルとURLをコピーしました