コンテナセキュリティ: なぜそれが基本なのか
I 容器 彼らはソフトウェアの提供方法に革命をもたらしましたが、 また、新たな攻撃対象領域も導入されました。 Docker イメージにはコードだけではありません アプリケーションだけでなく、ベースのオペレーティング システム、システム ライブラリ、および依存関係も含みます。 ランタイム。各コンポーネントには、アプリケーションに継承される脆弱性が含まれる可能性があります。
コンテナーのセキュリティは、イメージの構築 (ビルド時) から、 レジストリでの配布 (ディストリビューション) から本番環境での実行 (ランタイム) まで。 この記事では、各段階を保護するためのツールと実践方法について説明します。
何を学ぶか
- Trivy と Grype でのコンテナー イメージのスキャンの仕組み
- マルチステージビルドとディストリビューションレスで安全なイメージを構築
- Cosign を使用したイメージの署名と検証
- Falco とネットワーク ポリシーによるランタイム保護
- Kubernetes のセキュリティ コンテキストとポッド セキュリティ標準
- 安全な Dockerfile のベスト プラクティス
Trivy: 包括的な脆弱性スキャナー
トリビー Aqua Security と分析可能な最も人気のあるコンテナ スキャナーによる Docker イメージ、ファイルシステム、Git リポジトリ、および IaC 構成。速く、正確で、簡単です CI/CD パイプラインに統合します。
Dockerイメージスキャン
# Installare Trivy
curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh
# Scan di un'immagine Docker
trivy image node:18-alpine
# Scan con filtro severita
trivy image --severity CRITICAL,HIGH node:18-alpine
# Output in formato SARIF per GitHub
trivy image --format sarif --output trivy-results.sarif myapp:latest
# Scan del filesystem locale
trivy fs --security-checks vuln,config .
# Scan con exit code per CI (fallisce se trova CRITICAL)
trivy image --exit-code 1 --severity CRITICAL myapp:latest
GitHub Actions での Trivy の統合
# .github/workflows/container-security.yml
name: Container Security Scan
on:
push:
branches: [main]
pull_request:
jobs:
trivy-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t myapp:${{ github.sha }} .
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
image-ref: "myapp:${{ github.sha }}"
format: "sarif"
output: "trivy-results.sarif"
severity: "CRITICAL,HIGH"
exit-code: "1"
- name: Upload SARIF to GitHub Security
if: always()
uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: "trivy-results.sarif"
Grype: 画像スキャンの軽量代替ツール
グライプ Anchore による、Trivy に代わる軽量で特化した代替品 コンテナイメージの脆弱性スキャンについて。特に高速で統合されています まあそれで シフト (同じチームから) SBOM 世代向け。
# Installare Grype
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh
# Scan di un'immagine
grype myapp:latest
# Scan con filtro e output JSON
grype myapp:latest --only-fixed --output json > grype-results.json
# Scan con fail-on severity
grype myapp:latest --fail-on critical
# Generare SBOM con Syft e analizzare con Grype
syft myapp:latest -o cyclonedx-json > sbom.json
grype sbom:sbom.json
安全な Docker イメージの構築
コンテナのセキュリティは次から始まります Dockerfile。よく構築されたイメージ 攻撃対象領域と脆弱性の数が大幅に減少します。
マルチステージビルド
マルチステージ ビルド パターンにより、ビルド環境が最終イメージから分離されます。 実稼働イメージからビルド ツール、ソース、開発依存関係を削除します。
# Stage 1: Build
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
RUN npm run build
# Stage 2: Production (immagine minimale)
FROM gcr.io/distroless/nodejs20-debian12
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
EXPOSE 3000
USER nonroot
CMD ["dist/server.js"]
ディストロレスイメージ
Le ジストレスの画像 Google からのアプリケーションとそのアプリケーションのみが含まれています シェル、パッケージ マネージャー、その他のシステム ツールを使用しない実行時の依存関係。これにより、 攻撃対象領域を最小限に抑えます。
サイズと脆弱性の比較
| ベースイメージ | サイズ | 典型的な CVE |
|---|---|---|
| ノード:20 | ~1.1GB | 200-400 |
| ノード:20-スリム | ~250MB | 50-100 |
| ノード:20-アルパイン | ~180MB | 10-30 |
| distroless/nodejs20 | ~130MB | 0-5 |
Dockerfile セキュリティのベスト プラクティス
安全な Dockerfile は、攻撃対象領域を減らす特定のルールに従います。
# 1. Usare versioni specifiche, mai :latest
FROM node:20.11.0-alpine3.19
# 2. Creare un utente non-root
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
# 3. Impostare WORKDIR
WORKDIR /app
# 4. Copiare prima i file di dipendenze (cache layer)
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# 5. Copiare il codice applicativo
COPY --chown=appuser:appgroup . .
# 6. Non esporre porte privilegiate
EXPOSE 8080
# 7. Usare l'utente non-root
USER appuser
# 8. Usare HEALTHCHECK
HEALTHCHECK --interval=30s --timeout=3s \
CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
# 9. Usare exec form per CMD
CMD ["node", "dist/server.js"]
余署名を使用した画像署名
連署 (Sigstore プロジェクトの一部) を使用すると、画像にデジタル署名できます。 コンテナーを作成し、ビルド以降にイメージが変更されていないことを確認します。これは サプライチェーンのセキュリティの基本です。
# Installare Cosign
brew install cosign # macOS
# oppure
go install github.com/sigstore/cosign/v2/cmd/cosign@latest
# Generare una coppia di chiavi
cosign generate-key-pair
# Firmare un'immagine
cosign sign --key cosign.key myregistry.com/myapp:v1.0.0
# Verificare la firma
cosign verify --key cosign.pub myregistry.com/myapp:v1.0.0
# Firmare con keyless (Sigstore/Fulcio)
cosign sign myregistry.com/myapp:v1.0.0
Falco によるランタイム保護
ファルコン Sysdig とランタイム セキュリティのためのリファレンス オープン ソース ツールの コンテナの。カーネルのシステムコールをリアルタイムで監視し、検出されるとアラートを生成します 異常または疑わしい動作。
ファルコが検出したもの
- シェルはコンテナ内にスポーンします
- 機密ファイルへのアクセス (/etc/shadow、/etc/passwd)
- 予期しないネットワーク接続
- システムファイルの編集
- 権限昇格
- クリプトマイニング活動
Kubernetes ポッドのセキュリティ
Kubernetes 環境では、コンテナのセキュリティはポッド構成にまで拡張されます。 ザ ポッドのセキュリティ標準 3 つのセキュリティ レベルを定義します。
# Pod con security context restrittivo
apiVersion: v1
kind: Pod
metadata:
name: secure-app
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
fsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: app
image: myapp:v1.0.0
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
resources:
limits:
memory: "256Mi"
cpu: "500m"
requests:
memory: "128Mi"
cpu: "250m"
ネットワークポリシー
Le ネットワークポリシー Kubernetes ではポッド間のネットワーク トラフィックを制限します。 ネットワーク レベルでの最小特権の原則の実装:
# Deny all ingress by default
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
---
# Allow only specific traffic
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-frontend-to-api
namespace: production
spec:
podSelector:
matchLabels:
app: api
policyTypes:
- Ingress
ingress:
- from:
- podSelector:
matchLabels:
app: frontend
ports:
- protocol: TCP
port: 8080
コンテナセキュリティのベストプラクティス
- ビルドごとにスキャンする: Trivy/Grype を各イメージの CI パイプラインに統合します
- 最小限の画像: Alpine または distroless をベースとして使用し、完全なイメージを避けます
- 非ルート: コンテナは常に非 root ユーザーとして実行します。
- 読み取り専用ファイルシステム: ルート ファイルシステムを読み取り専用でマウントします。
- 最新のタグはありません: SHA256 ダイジェストでは常に特定のタグを使用します
- プライベートレジストリ: 統合されたスキャンでプライベート レジストリを使用する
- サイン画像: デプロイ前に各イメージに Cosign で署名します。
- ランタイム監視: 本番監視のために Falco を導入する
結論
コンテナのセキュリティは DevSecOps の重要な側面であり、常に注意が必要です ライフサイクルの段階。最小限で安全な画像の構築からスキャンまで 自動化され、ランタイム監視に至るまで、各層が以下に対する保護を追加します。 脅迫。
次の記事では、詳しく見ていきます サプライチェーンのセキュリティ、SBOMの分析 (ソフトウェア部品表)、アーティファクト署名用の Sigstore、および SLSA フレームワーク ソフトウェア サプライ チェーンの完全性を確保するため。







