- Authors
- Name
##入り
セキュリティスキャナがCVEリストを注ぐと、どこから手を触れるべきかが止まります。重要なのは、すべての脆弱性を直ちに修正するのではなく、リスクに基づいて優先順位を付け、体系的に措置し、再発を防止するプロセスを備えることだ。
この記事では、OSパッケージの脆弱性パッチ、コンテナイメージセキュリティ、ランタイムハードニングを網羅する本番プレイブックを紹介します。
1. 脆弱性対応プロセスの概要```
┌─────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ 발견 │ → │ 분류 │ → │ 조치 │ → │ 검증 │ → │ 보고 │ │ Scanning │ │ Triage │ │ Remediate│ │ Verify │ │ Report │ └─────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘
|重大度CVSSスコア|アクション期限例
| ------------ | --------- | ------------------------ | -------------------- |
| **Critical** | 9.0〜10.0 | 24〜72時間| RCE、認証バイパス
| **High** | 7.0〜8.9 | 7日|権限上昇、情報漏洩
| **Medium** | 4.0〜6.9 | 30日| XSS、サービス拒否
| **Low** | 0.1〜3.9 | 90日または次の定期パッチ|情報露出(限定)|
> **核心原則**: CVSSスコアだけで判断せず、**Exploit可否(EPSS)**、**インターネット露出可否**、**影響を受ける資産の重要度**を総合判断する。
---
## 2. OSパッケージの脆弱性の管理
### 2.1 脆弱性のスキャン```bash
# RHEL / Rocky - 보안 업데이트 확인
dnf updateinfo list security
dnf updateinfo list --sec-severity=Critical
dnf updateinfo info RHSA-2026:1234
# Ubuntu - 보안 업데이트 확인
apt update
apt list --upgradable 2>/dev/null | grep -i security
# 설치된 패키지의 CVE 확인 (Trivy)
trivy rootfs --severity CRITICAL,HIGH /
# OpenSCAP 스캔 (컴플라이언스)
oscap xccdf eval \
--profile xccdf_org.ssgproject.content_profile_cis \
--results results.xml \
--report report.html \
/usr/share/xml/scap/ssg/content/ssg-rhel9-ds.xml
```### 2.2 パッチ適用手順```bash
#!/usr/bin/env bash
# patch-os.sh - OS 보안 패치 적용 스크립트
set -euo pipefail
LOG_FILE="/var/log/security-patch-$(date +%Y%m%d).log"
SNAPSHOT_NAME="pre-patch-$(date +%Y%m%d-%H%M%S)"
log() { printf '[%s] %s\n' "$(date +%T)" "$1" | tee -a "$LOG_FILE"; }
# 1단계: 스냅샷/백업
log "=== 패치 시작 ==="
log "스냅샷 생성: $SNAPSHOT_NAME"
# LVM 스냅샷 (해당 시)
# lvcreate -L 10G -s -n "$SNAPSHOT_NAME" /dev/vg0/root
# 2단계: 현재 상태 기록
rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /tmp/packages-before.txt
# 3단계: 보안 업데이트만 적용
log "보안 업데이트 적용 중..."
if command -v dnf &>/dev/null; then
dnf update --security -y 2>&1 | tee -a "$LOG_FILE"
elif command -v apt-get &>/dev/null; then
apt-get update
apt-get upgrade -y -o Dpkg::Options::="--force-confold" 2>&1 | tee -a "$LOG_FILE"
fi
# 4단계: 변경된 패키지 목록
rpm -qa --qf '%{NAME}-%{VERSION}-%{RELEASE}.%{ARCH}\n' | sort > /tmp/packages-after.txt
diff /tmp/packages-before.txt /tmp/packages-after.txt > /tmp/packages-diff.txt || true
log "변경된 패키지:"
cat /tmp/packages-diff.txt | tee -a "$LOG_FILE"
# 5단계: 서비스 재시작 필요 여부 확인
if command -v needs-restarting &>/dev/null; then
log "재시작 필요 서비스:"
needs-restarting -s 2>&1 | tee -a "$LOG_FILE"
if needs-restarting -r 2>&1 | grep -q "Reboot is required"; then
log "WARNING: 커널 업데이트로 리부팅 필요"
fi
fi
log "=== 패치 완료 ==="
```### 2.3 自動セキュリティアップデートの設定
#### RHEL / Rocky```bash
# dnf-automatic 설치·설정
dnf install -y dnf-automatic
# /etc/dnf/automatic.conf
# [commands]
# apply_updates = yes
# upgrade_type = security # 보안 업데이트만
systemctl enable --now dnf-automatic-install.timer
```#### Ubuntu```bash
# unattended-upgrades 설정
apt install -y unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
# /etc/apt/apt.conf.d/50unattended-upgrades
# Unattended-Upgrade::Allowed-Origins {
# "${distro_id}:${distro_codename}-security";
# };
# Unattended-Upgrade::Automatic-Reboot "false";
# Unattended-Upgrade::Mail "admin@example.com";
```### 2.4 パッチ管理チェックリスト
- [ ] セキュリティアップデート通知チャンネルの購読(RHSA、USN、CVEメーリングリスト)
- []週間脆弱性スキャンの自動化
- [ ] ステージング → 本番パッチパイプライン構築
- [ ]パッチ適用前のスナップショット/バックアップ必須
- [ ] パッチ後サービス ヘルスチェック自動化
- [ ] カーネル更新時の再起動スケジュールの確立
- [ ] パッチ履歴・監査ログ保存(最低1年)
---
## 3.コンテナイメージのセキュリティ
### 3.1 イメージスキャンツールの比較
|ツール|ライセンス|特徴| CI / CD統合|
| -------------------- | ---------------- | ------------------------------- | ------------------------- |
| **Trivy** | OSS(Apache-2.0)| OS +言語パッケージ+ IaC + Secret | GitHub Actions、GitLab CI |
| **Grype** | OSS(Apache-2.0)| SBOMベースのスキャン| CLI中心|
| **Snyk Container** |商用(無料プラン)|開発者にやさしいフィックスPRほとんどCI |
| **Prisma Cloud** |商業フルCNAPP |エンタープライズCI |
| **AWS ECR Scanning** | AWSを含めるInspectorベース| AWSネイティブ|
### 3.2 Trivy本番を使う```bash
# 이미지 스캔 (Critical + High만)
trivy image --severity CRITICAL,HIGH myapp:latest
# SBOM 생성
trivy image --format spdx-json -o sbom.json myapp:latest
# 취약점이 있으면 빌드 실패 (CI용)
trivy image --exit-code 1 --severity CRITICAL myapp:latest
# .trivyignore - 허용된 취약점 (예외 처리)
# CVE-2024-XXXX # 해당 코드 경로 미사용, 2026-04-01까지 예외
```### 3.3 安全なDockerfileの作成```dockerfile
# 1. 최소 베이스 이미지 사용
FROM cgr.dev/chainguard/python:latest-dev AS builder
# 또는 distroless, Alpine, UBI-micro
# 2. 빌드 의존성과 런타임 분리 (멀티스테이지)
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir --prefix=/install -r requirements.txt
COPY . .
FROM cgr.dev/chainguard/python:latest
WORKDIR /app
COPY --from=builder /install /usr/local
COPY --from=builder /app .
# 3. non-root 사용자 (Chainguard은 기본 non-root)
# 일반 이미지의 경우:
# RUN addgroup -S app && adduser -S app -G app
# USER app
# 4. 불필요한 패키지 제거, 캐시 정리
# (멀티스테이지로 해결)
# 5. 건강 검사
HEALTHCHECK --interval=30s --timeout=5s --retries=3 \
CMD ["python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8000/health')"]
ENTRYPOINT ["python", "-m", "uvicorn", "main:app", "--host", "0.0.0.0"]
```### 3.4 ベース画像選択ガイド
|画像タイプ|サイズ|脆弱性の数パッケージマネージャーシェル推奨用途|
| -------------- | ----- | --------- | ------------- | ----------- | --------------- |
|`ubuntu:24.04`| ~78MB |中apt | bash |汎用|
|`alpine:3.20`| ~7MB |低い| apk | ash |軽量サービス|
|`distroless`| 〜20MB |非常に低い|なしなしプロダクションランタイム|
|`chainguard`| 〜15MB |ほぼ0 | apk(devのみ)|なし(devのみ)|セキュリティ重視
|`ubi-micro`| ~35MB |低い|なしなしRHEL互換が必要
|`scratch`| 0MB | 0 |なしなしGoバイナリ|
### 3.5 CI/CDパイプライン統合```yaml
# GitHub Actions 예시
name: Container Security
on:
push:
branches: [main]
pull_request:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build image
run: docker build -t myapp:${{ github.sha }} .
- name: Trivy vulnerability scan
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
severity: CRITICAL,HIGH
exit-code: 1
format: sarif
output: trivy-results.sarif
- name: Upload scan results
uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: trivy-results.sarif
- name: Generate SBOM
uses: aquasecurity/trivy-action@master
with:
image-ref: myapp:${{ github.sha }}
format: spdx-json
output: sbom.spdx.json
- name: Upload SBOM
uses: actions/upload-artifact@v4
with:
name: sbom
path: sbom.spdx.json
```---
## 4. ランタイムハードニング
### 4.1 コンテナランタイムセキュリティ
#### Docker ハードニング```bash
# /etc/docker/daemon.json
{
"userns-remap": "default",
"no-new-privileges": true,
"log-driver": "json-file",
"log-opts": {
"max-size": "10m",
"max-file": "3"
},
"storage-driver": "overlay2",
"live-restore": true,
"icc": false,
"default-ulimits": {
"nofile": { "Name": "nofile", "Hard": 65535, "Soft": 65535 }
}
}
```####コンテナ実行時のセキュリティオプション```bash
docker run -d \
--name myapp \
--read-only \
--tmpfs /tmp:rw,noexec,nosuid,size=100m \
--cap-drop ALL \
--cap-add NET_BIND_SERVICE \
--security-opt no-new-privileges:true \
--security-opt seccomp=default.json \
--pids-limit 100 \
--memory 512m \
--cpus 1.0 \
--user 1000:1000 \
myapp:latest
```#### Kubernetes Pod Security```yaml
# Pod Security Standards - Restricted 프로파일
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:latest
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ['ALL']
resources:
limits:
memory: 512Mi
cpu: '1'
requests:
memory: 256Mi
cpu: '0.5'
volumeMounts:
- name: tmp
mountPath: /tmp
volumes:
- name: tmp
emptyDir:
sizeLimit: 100Mi
```### 4.2 Kubernetesクラスタハードニングチェックリスト
|エリア|アイテム|コマンド/設定|
| ------------ | ---------------------------- | -------------------------------------------- |
| **認証** |匿名アクセスをブロック|`--anonymous-auth=false`|
| **認可** | RBACを有効にする`--authorization-mode=RBAC`|
| **API** | NodeRestrictionアドミッション|`--enable-admission-plugins=NodeRestriction`|
| **Etcd** |暗号化設定|`--encryption-provider-config`|
| **ネットワーク** | NetworkPolicy適用| Calico / Ciliumネットワークポリシー|
| ** Pod** | PSA(Pod Security Admission)|名前空間に`enforce: restricted`|
| **シークレット** |外部シークレットマネージャVault、AWS Secrets Manager |
| **ありがとう** | Auditロギング|`--audit-log-path`、`--audit-policy-file`|
| **画像** |署名検証| Cosign + Admission Webhook |
| **ランタイム** | Seccomp / AppArmorプロファイル| Pod securityContext |
### 4.3 ネットワークポリシーの例```yaml
# 기본 거부 정책 (deny-all)
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: default-deny-all
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress
---
# 앱 특정 허용 정책
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-app-traffic
namespace: production
spec:
podSelector:
matchLabels:
app: myapp
policyTypes:
- Ingress
- Egress
ingress:
- from:
- podSelector:
matchLabels:
app: nginx-ingress
ports:
- port: 8080
protocol: TCP
egress:
- to:
- podSelector:
matchLabels:
app: postgres
ports:
- port: 5432
protocol: TCP
- to: # DNS 허용
- namespaceSelector: {}
podSelector:
matchLabels:
k8s-app: kube-dns
ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
```---
## 5. 脆弱性対応シナリオ別プレイブック
### シナリオ 1: Critical CVE 緊急パッチ```
1. [즉시] CVE 공지 확인 → 영향받는 패키지·버전 식별
2. [1시간] 자산 인벤토리에서 영향 범위 파악
3. [2시간] 패치 가용 여부 확인
├── 패치 있음 → 스테이징 적용 → 테스트 → 프로덕션 롤링
└── 패치 없음 → Workaround 적용 (WAF 룰, 설정 변경, 서비스 격리)
4. [24시간] 프로덕션 패치 완료
5. [48시간] 스캔으로 조치 검증 → 보고서 작성
```### シナリオ 2: コンテナイメージの脆弱性```
1. 이미지 스캔 결과 확인 (Trivy/Snyk)
2. 취약점 분류:
├── OS 패키지 → 베이스 이미지 업데이트
├── 언어 라이브러리 → dependency 업데이트
└── 설정 문제 → Dockerfile 수정
3. 이미지 재빌드 + 스캔 재실행
4. 스테이징 배포 → E2E 테스트
5. 프로덕션 롤링 업데이트
6. 이전 이미지 태그 비활성화
```### シナリオ 3: ランタイム侵害検知対応```
1. [즉시] 알림 확인 (Falco, 감사 로그)
2. [즉시] 해당 Pod/컨테이너 격리 (NetworkPolicy deny-all)
3. [1시간] 포렌식 데이터 수집:
- 컨테이너 프로세스 목록, 네트워크 연결
- 감사 로그, 런타임 이벤트 로그
- 이미지 레이어 분석
4. [4시간] 침입 경로 파악 → 취약점 조치
5. [24시간] 클린 이미지로 재배포
6. [1주] 사후 분석 보고서 + 재발 방지 대책
```---
## 6.セキュリティスキャン自動化アーキテクチャ```
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 코드 푸시 │ → │ CI 파이프라인 │ → │ 이미지 빌드 │
└─────────────┘ └──────┬──────┘ └──────┬──────┘
│ │
┌──────▼──────┐ ┌──────▼──────┐
│ SAST 스캔 │ │ 이미지 스캔 │
│ (Semgrep) │ │ (Trivy) │
└──────┬──────┘ └──────┬──────┘
│ │
┌──────▼───────────────────▼──────┐
│ 결과 집계 + 판정 │
│ (Critical → 빌드 실패) │
│ (High → 경고 + Jira 생성) │
└──────────────┬──────────────────┘
│
┌──────────────▼──────────────────┐
│ 레지스트리 푸시 (통과 시에만) │
└──────────────┬──────────────────┘
│
┌──────────────▼──────────────────┐
│ 정기 스캔 (주간, 레지스트리 전체) │
└─────────────────────────────────┘
```---
## 7. コンプライアンスマッピング
|フレームワーク|関連要件|このプレイブックの対応|
| ----------------- | ---------------------------------- | ------------------ |
| **CIS Benchmark** | OS・Docker・K8sベンチマーク|セクション2、4
| **NIST 800-53** | SI-2(Flaw Remediation)|セクション2(パッチ管理)|
| **PCI DSS 4.0** | 6.3(脆弱性の特定・対処)|全体のプロセス
| **SOC 2** | CC7.1(モニタリング)、CC8.1(変更管理)|セクション5、6
| **ISMS-P** | 2.10(システム・サービスセキュリティ管理)全体
---
##8.ツールチェーン推奨
### 必須ツール
|用途| OSS |商業
| --------------- | ----------------------- | -------------------- |
|画像スキャン| Trivy、Grype | Snyk、Prisma Cloud |
| OSコンプライアンス| OpenSCAP、Lynis | Qualys、テナブル|
|ランタイムセキュリティ| Falco | Sysdig Secure |
| SBOMの作成| Syft、Trivy | Anchore |
|シークレットスキャン| Gitleaks、TruffleHog | GitGuardian |
| SAST | Semgrep、CodeQL | SonarQube、Checkmarx |
|画像署名| Cosign(Sigstore)| Docker Content Trust |
|ポリシーエンジン| OPA / Gatekeeper、Kyverno | Styra DAS |
###最小構成の推奨```
코드 단계: Gitleaks (시크릿) + Semgrep (SAST)
빌드 단계: Trivy (이미지 스캔) + Syft (SBOM)
배포 단계: Cosign (이미지 서명) + Kyverno (정책)
런타임: Falco (이상 탐지) + 감사 로그
```---
## 9. レポートテンプレート
###脆弱性対策レポート```markdown
# 보안 취약점 조치 보고서
## 개요
- 보고일: YYYY-MM-DD
- 작성자: 보안 운영팀
- 대상 기간: YYYY-MM-DD ~ YYYY-MM-DD
## 요약
| 심각도 | 발견 | 조치 완료 | 예외 처리 | 미조치 |
| -------- | ---- | --------- | --------- | ------ |
| Critical | 3 | 3 | 0 | 0 |
| High | 12 | 10 | 2 | 0 |
| Medium | 45 | 30 | 5 | 10 |
## Critical 취약점 상세
### CVE-YYYY-XXXXX
- 영향: [설명]
- 영향 자산: [서버/이미지 목록]
- 조치: [패치 버전/설정 변경]
- 조치일: YYYY-MM-DD
- 검증: [스캔 결과 첨부]
## 예외 처리 목록
| CVE | 사유 | 보완 조치 | 만료일 |
| -------------- | --------------------- | ----------- | ---------- |
| CVE-YYYY-XXXXX | 해당 코드 경로 미사용 | WAF 룰 추가 | YYYY-MM-DD |
## 개선 권고사항
1. [구체적 개선 사항]
2. [구체적 개선 사항]
```---
## 10.本番確認チェックリスト
### OSセキュリティ
- []不要なサービスを無効にする(`systemctl list-unit-files --state=enabled`)
- [ ] SSHキーベースの認証のみを許可、rootログインをブロック
- [ ] 自動セキュリティ更新設定
- []ファイアウォールのデフォルト拒否ポリシー
- []監査ログ(auditd)を有効にする
- [ ] AIDE/OSSECファイルの整合性の監視
###コンテナセキュリティ
- [ ] 最小ベースイメージの使用 (distroless/chainguard)
- [ ]マルチステージビルドでビルドツールを削除する
- [ ] non-root ユーザーとして実行
- [ ] 読み取り専用ファイルシステム
- [ ]リソース制限(CPU、メモリ、PID)
- [ ] イメージ署名 + 検証
### Kubernetesセキュリティ
- [ ] PSA (Pod Security Admission) restricted モード
- [ ] NetworkPolicy デフォルト deny-all
- [ ] RBAC最小権限原則
- [ ] Etcd暗号化
- [ ]監査ロギングの有効化
- [ ]シークレット外部管理(Vaultなど)
---
##仕上げ
セキュリティは一度の措置ではなく、「持続的なプロセス」です。このプレイブックの核心を3行にまとめる。
1. **自動化**: スキャン・パッチ・検証をCI/CDに内蔵し、手動抜けを防止する。
2. **階層防御**: OS・イメージ・ランタイム・ネットワークを全て扱う深層防御戦略を樹立する。
3. **対応システム**:発見→分類→処置→検証→報告のサイクルを繰り返し、SLAを守る。
完全なセキュリティは不可能ですが、体系的な運用で**リスクを管理可能なレベルに下げることができる**。