Skip to content
Published on

CKS (Certified Kubernetes Security Specialist) 完全模擬試験

Authors

1. CKS 試験概要

CKS (Certified Kubernetes Security Specialist) は、CNCF と Linux Foundation が提供する上級 Kubernetes セキュリティ資格です。

項目内容
試験時間120分
問題形式15〜20問のパフォーマンスベース実技
合格基準67%以上
前提条件有効な CKA 資格
試験環境リモート監視、ブラウザベースのターミナル
有効期限2年

ドメイン別割合

ドメイン割合
Cluster Setup10%
Cluster Hardening15%
System Hardening15%
Minimizing Microservice Vulnerabilities20%
Supply Chain Security20%
Monitoring, Logging and Runtime Security20%

2. Kubernetes セキュリティの核心概念まとめ

2.1 RBAC (Role-Based Access Control)

RBAC は Kubernetes API アクセスを制御する中核的な仕組みです。Role/ClusterRole は権限を定義し、RoleBinding/ClusterRoleBinding はその権限を主体(ユーザー、グループ、ServiceAccount)にバインドします。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: pod-reader
rules:
  - apiGroups: ['']
    resources: ['pods']
    verbs: ['get', 'watch', 'list']

2.2 Pod Security Standards (PSS)

プロファイル説明
Privileged制限なし、すべての権限を許可
Baseline最小限の制限、既知の権限昇格を防止
Restricted強力なセキュリティポリシー、ベストプラクティスを強制

2.3 NetworkPolicy

NetworkPolicy は Pod 間のトラフィックを L3/L4 レベルで制御します。デフォルトではすべてのトラフィックが許可され、NetworkPolicy を適用すると明示的に許可されたトラフィックのみが流れます。

2.4 Falco ランタイムセキュリティ

Falco はカーネルのシステムコールを監視してランタイムの脅威を検出します。ルールベースで不審なアクティビティを検知しアラートを送信します。

2.5 Supply Chain Security

  • イメージスキャン: Trivy、Snyk で CVE 脆弱性を検出
  • イメージ署名: Cosign でイメージへの署名と検証
  • SBOM: ソフトウェア部品表 (Software Bill of Materials)
  • Admission Controllers: ImagePolicyWebhook でイメージポリシーを強制

3. 概念理解問題 (Q1〜Q55)

Cluster Setup (Q1〜Q10)

Q1. kube-bench はどの標準に基づいて Kubernetes クラスターを検査しますか?

A) NIST SP 800-190 B) CIS Kubernetes Benchmark C) PCI DSS D) ISO 27001

正解: B

解説: kube-bench は CIS (Center for Internet Security) Kubernetes Benchmark に基づいてクラスターコンポーネントのセキュリティ設定を自動検査します。マスターノード、ワーカーノード、etcd、API サーバーなどを検査します。

Q2. etcd データを保存時 (at rest) に暗号化するための正しい設定方法は?

A) /etc/kubernetes/manifests/kube-apiserver.yaml--etcd-encryption-key フラグ B) /etc/kubernetes/encryption-config.yaml を作成し kube-apiserver の --encryption-provider-config で指定 C) etcd の --cipher-suites フラグ D) kubelet の --encrypt-data フラグ

正解: B

解説: etcd の保存時暗号化は EncryptionConfiguration リソースを YAML ファイルで作成し、kube-apiserver の --encryption-provider-config フラグでそのファイルを指定することで有効化します。Secrets や ConfigMaps などのリソースタイプに対して暗号化プロバイダー (aescbc, aesgcm, secretbox など) を設定します。

Q3. Kubernetes Ingress に TLS を設定する際、証明書と秘密鍵はどこに保存すべきですか?

A) ConfigMap B) Secret (type: kubernetes.io/tls) C) PersistentVolume D) ServiceAccount トークン

正解: B

解説: TLS 証明書と秘密鍵は kubernetes.io/tls タイプの Secret に保存します。tls.crt フィールドに証明書、tls.key フィールドに秘密鍵を base64 エンコードして格納し、Ingress リソースの spec.tls セクションでこの Secret を参照します。

Q4. クラウド環境で Pod が IMDS (Instance Metadata Service) に直接アクセスするのを防ぐ最適な方法は?

A) NetworkPolicy で 169.254.169.254 へのアクセスをブロック B) Pod に hostNetwork: true を設定 C) ServiceAccount の自動マウントを無効化 D) PSP で hostPID を禁止

正解: A

解説: AWS IMDSv1 は認証なしで 169.254.169.254 にアクセスして IAM 認証情報を盗むことができます。NetworkPolicy でその IP アドレスへの egress をブロックするか、IMDSv2 にアップグレードしてホップ制限を 1 に設定すると、コンテナからの直接アクセスを防止できます。

Q5. 特定の namespace の Pod からのアクセスのみ許可する NetworkPolicy セレクターは?

A) podSelector B) namespaceSelector C) ipBlock D) serviceSelector

正解: B

解説: namespaceSelector は namespace のラベルでマッチングし、そのラベルを持つ namespace の Pod からのトラフィックのみを許可します。podSelector と組み合わせると特定の namespace 内の特定 Pod のみを許可するきめ細かいポリシーを作成できます。

Q6. kube-bench の結果で [FAIL] 項目を修正する際に最初にすべきことは?

A) クラスターをすぐに再起動 B) その項目の remediation セクションを確認 C) 新しいクラスターを作成 D) etcd バックアップを削除

正解: B

解説: kube-bench の各 [FAIL] 項目には remediation (修正方法) セクションが含まれており、具体的な修正コマンドや設定変更方法が記載されています。まずこのセクションを確認し、慎重に適用する必要があります。

Q7. Kubernetes API サーバーへの匿名 (anonymous) 認証を無効化するための正しい設定は?

A) --anonymous-auth=false B) --disable-anonymous=true C) --allow-anonymous=false D) --auth-anonymous=disabled

正解: A

解説: kube-apiserver の --anonymous-auth=false フラグで匿名認証を無効化できます。これを設定すると、認証されていないリクエストが system:anonymous ユーザーとして処理されずに拒否されます。

Q8. etcd クラスターのピア通信を TLS で保護するために必要なフラグの組み合わせは?

A) --peer-cert-file--peer-key-file--peer-trusted-ca-file B) --tls-cert-file--tls-key-file C) --client-cert-auth--trusted-ca-file D) --peer-auth=tls

正解: A

解説: etcd ピア通信の TLS には --peer-cert-file (ピア証明書)、--peer-key-file (ピア秘密鍵)、--peer-trusted-ca-file (ピア CA 証明書) の 3 つのフラグを設定します。--peer-client-cert-auth=true も追加するとピアクライアント認証も強制できます。

Q9. Kubernetes 監査ログで RequestResponse レベルを設定すると何の情報が含まれますか?

A) イベントメタデータのみ B) リクエストメタデータとリクエストボディ C) メタデータ、リクエストボディ、レスポンスボディの全て D) レスポンスボディのみ

正解: C

解説: 監査ログのレベルは None、Metadata、Request、RequestResponse の 4 段階です。RequestResponse は最も詳細なレベルで、イベントメタデータ、リクエストボディ (request body)、レスポンスボディ (response body) の全てを記録します。ただしデータ量が多くストレージコストが高くなります。

Q10. CIS Benchmark が推奨する kube-apiserver の admission controller 設定は?

A) AlwaysAllow B) NodeRestriction、PodSecurityAdmission を含む C) AlwaysDeny D) LimitRanger のみ有効化

正解: B

解説: CIS Benchmark は NodeRestriction (ノードが自分のリソースのみ変更可能)、PodSecurityAdmission (PSS ポリシーを適用)、ResourceQuota、LimitRanger などのセキュリティ強化 admission controller を有効にすることを推奨しています。

Cluster Hardening (Q11〜Q22)

Q11. ServiceAccount のトークンが自動的に Pod にマウントされないようにするには?

A) ServiceAccount に automountServiceAccountToken: false を設定 B) Pod spec に serviceAccountName: none を設定 C) RBAC で serviceaccount リソースを削除 D) Secret を削除

正解: A

解説: ServiceAccount リソースまたは Pod spec に automountServiceAccountToken: false を設定することで ServiceAccount トークンの自動マウントを防げます。Pod レベルの設定が ServiceAccount レベルの設定を上書きします。

Q12. 最小権限の原則に従って RBAC を設定する際の正しいアプローチは?

A) cluster-admin ClusterRole を全 ServiceAccount にバインド B) 必要なリソースと動詞 (verbs) のみを含むカスタム Role を作成 C) RBAC を無効化して ABAC を使用 D) 全リソースにワイルドカード (*) を使用

正解: B

解説: 最小権限の原則は必要な作業に最小限の権限のみ付与することです。特定の namespace の特定リソースに対する特定の動詞のみを許可するカスタム Role を作成し、必要な主体にのみ RoleBinding を通じて付与します。

Q13. kubelet 認証を強化するために設定すべき kubelet フラグは?

A) --authentication-token-webhook=true--authorization-mode=Webhook B) --anonymous-auth=true C) --read-only-port=10255 D) --allow-all-requests=true

正解: A

解説: kubelet のセキュリティ強化のために --anonymous-auth=false で匿名アクセスをブロックし、--authentication-token-webhook=true でトークンウェブフック認証を有効化し、--authorization-mode=Webhook で API サーバーを通じた認可を設定します。

Q14. Kubernetes のバージョンアップグレードの頻度がセキュリティ上重要な理由は?

A) 新機能の追加のため B) CVE 脆弱性パッチとセキュリティフィックスの適用 C) パフォーマンス向上のため D) kubectl バージョン互換性のため

正解: B

解説: Kubernetes は約 4 ヶ月ごとにマイナーバージョンをリリースし、各バージョンは約 14 ヶ月間サポートされます。アップグレードしないと CVE 脆弱性がパッチされず、セキュリティリスクが高まります。CKS では最新のサポート対象バージョンを維持することを推奨しています。

Q15. 次の ClusterRoleBinding が危険な理由は?
subjects:
  - kind: Group
    name: system:authenticated
roleRef:
  kind: ClusterRole
  name: cluster-admin

A) subjects フィールドが間違っている B) 認証された全ユーザーに cluster-admin 権限が付与される C) ClusterRoleBinding に名前がない D) apiGroup が欠如している

正解: B

解説: system:authenticated グループは認証された全ユーザーを含みます。このグループに cluster-admin をバインドすると、クラスターにアクセス可能な全ユーザーが最高権限を持つことになります。同様に system:unauthenticated に権限を付与することも非常に危険です。

Q16. Audit Policy で特定リソースの変更 (create/update/delete) のみを記録し、get/list を除外するには?

A) rules の verbs フィールドに目的の動詞のみを指定 B) resourceNames フィールドを使用 C) namespace フィールドでフィルタリング D) level を None に設定

正解: A

解説: Audit Policy の rules で verbs フィールドを使用して特定の HTTP 動詞についてのみログを記録できます。例えば verbs: ["create", "update", "delete", "patch"] と設定すると変更操作のみが監査ログに記録されます。

Q17. kubelet の読み取り専用ポート (デフォルト 10255) を無効化するには?

A) --read-only-port=0 B) --disable-readonly=true C) --secure-port=0 D) --port=0

正解: A

解説: --read-only-port=0 と設定することで kubelet の読み取り専用 HTTP ポート (デフォルト 10255) が無効化されます。このポートは認証なしで Pod 情報とメトリクスを公開するため、無効化することがセキュリティ上推奨されます。

Q18. ServiceAccount に最小権限を適用するベストプラクティスとして正しいものは?

A) すべての Pod が default ServiceAccount を使用 B) アプリケーションごとに専用 ServiceAccount を作成し、必要最小限の権限のみを付与 C) cluster-admin を全 ServiceAccount に付与 D) RBAC の代わりにファイルベースのアクセス制御を使用

正解: B

解説: 各ワークロードに専用の ServiceAccount を作成し、そのアプリケーションが実際に必要なリソースと動詞のみを許可する Role を作成してバインドすることがベストプラクティスです。default ServiceAccount を共有すると不必要な権限が付与される可能性があります。

Q19. kube-apiserver の --insecure-port フラグのセキュリティ上正しい設定は?

A) 8080 に設定 B) 0 に設定して無効化 C) 443 に変更 D) TLS 証明書を追加

正解: B

解説: --insecure-port=0 と設定すると TLS なし・認証なしの HTTP ポートが無効化されます。このフラグは Kubernetes 1.20 から deprecated となりデフォルト値が 0 になりましたが、明示的に 0 と設定することが CIS Benchmark の推奨事項です。

Q20. Node Authorization モードの役割は?

A) 全ユーザーにノードアクセスを許可 B) kubelet が自身で実行している Pod に関連するリソースのみにアクセスするよう制限 C) ノード間のネットワーク通信を暗号化 D) ノードの OS レベルのアクセス制御

正解: B

解説: Node Authorization モードは kubelet が API サーバーにアクセスする際に、自分のノードで実行中の Pod に必要なリソース (Secrets、ConfigMaps、PersistentVolumes など) のみへのアクセスを制限します。--authorization-mode=Node,RBAC と併用することが推奨されます。

Q21. CertificateSigningRequest (CSR) を通じたユーザー証明書発行の正しい順序は?

A) CSR 作成 → 承認 → CSR オブジェクト作成 → 証明書抽出 B) 秘密鍵生成 → CSR ファイル作成 → CSR オブジェクト作成 → 承認 → 証明書抽出 C) CA で直接署名 → kubeconfig 設定 D) ServiceAccount トークンを使用

正解: B

解説: 正しい順序は 1) openssl で秘密鍵を生成、2) CSR ファイルを作成、3) base64 エンコードして CertificateSigningRequest オブジェクトを作成、4) kubectl certificate approve で承認、5) kubectl get csr -o jsonpath='{.status.certificate}' で証明書を抽出、です。

Q22. kubectl auth can-i コマンドはどんな用途で使いますか?

A) クラスター証明書の更新 B) 特定のユーザー/ServiceAccount が特定の操作を実行できるか確認 C) RBAC ルールの適用 D) 監査ログの確認

正解: B

解説: kubectl auth can-i get pods --namespace default のように使用して、現在のユーザーが特定の操作を実行できるか確認します。--as フラグで別のユーザーに成り代わって確認することもできます。RBAC 設定の検証に非常に役立ちます。

System Hardening (Q23〜Q32)

Q23. AppArmor プロファイルを Pod に適用するための annotation 形式は?

A) security.alpha.kubernetes.io/apparmor: runtime/default B) container.apparmor.security.beta.kubernetes.io/CONTAINER_NAME: localhost/PROFILE_NAME C) apparmor.kubernetes.io/profile: enforced D) securityContext.appArmorProfile: localhost/custom

正解: B

解説: Kubernetes 1.30 以前では container.apparmor.security.beta.kubernetes.io/コンテナ名: localhost/プロファイル名 という annotation で AppArmor を適用しました。1.30 以降は securityContext.appArmorProfile フィールドを使用します。プロファイルはノードに事前にロードされている必要があります。

Q24. Seccomp プロファイルの RuntimeDefault を Pod に適用する正しい方法は?

A) Pod annotation でのみ設定 B) securityContext.seccompProfile.type: RuntimeDefault C) 別途 CRD の作成が必要 D) Node レベルでのみ設定可能

正解: B

解説: Kubernetes 1.19 以降、securityContext.seccompProfile フィールドで Seccomp を設定できます。type: RuntimeDefault はコンテナランタイムのデフォルト Seccomp プロファイルを使用し、type: Localhost でカスタムプロファイルを指定することもできます。

Q25. コンテナ内で実行されるプロセスの OS レベルのセキュリティを強化するツールは?

A) NetworkPolicy B) RBAC C) AppArmor、Seccomp D) PodDisruptionBudget

正解: C

解説: AppArmor は MAC (Mandatory Access Control) でプロセスがアクセスできるファイル、ネットワーク、機能を制限します。Seccomp はプロセスが呼び出せるシステムコールを制限します。どちらもコンテナ内プロセスの OS レベルの動作を制限します。

Q26. ノードで不要なサービスとポートを確認するために適切なコマンドは?

A) kubectl describe node B) ss -tlnp または netstat -tlnp C) docker ps D) journalctl -u kubelet

正解: B

解説: ss -tlnp (ソケット統計) または netstat -tlnp コマンドでノードでリッスン中の TCP ポートと対応するプロセスを確認できます。不必要なサービスがポートを開いている場合は無効化または削除すべきです。

Q27. Linux capability を削除してコンテナの権限を制限する securityContext 設定は?

A) securityContext.privileged: false B) securityContext.capabilities.drop: ["ALL"] C) securityContext.runAsRoot: false D) securityContext.allowPrivilegeEscalation: false

正解: B

解説: securityContext.capabilities.drop: ["ALL"] で全ての Linux capability を削除し、capabilities.add で必要な capability のみを選択的に追加するのがベストプラクティスです。allowPrivilegeEscalation: false と組み合わせるとより強化されます。

Q28. gVisor (runsc) を使用する RuntimeClass を Pod に適用する方法は?

A) spec.runtimeClassName: gvisor B) spec.securityContext.runtime: gvisor C) annotation で設定 D) Node ラベルで自動選択

正解: A

解説: まず RuntimeClass オブジェクトを作成 (handler: runsc) し、Pod spec の runtimeClassName フィールドでその RuntimeClass を指定します。gVisor はユーザー空間カーネルを実装してコンテナをサンドボックス化するため、ホストカーネルから分離されます。

Q29. AWS で Pod に IAM 権限を付与する推奨方法 (IRSA) は?

A) ノードの IAM ロールに全権限を付与 B) Access Key / Secret Key を Secret に保存 C) OIDC Provider と ServiceAccount の annotation で IAM Role を連携 D) EC2 インスタンスプロファイルのみ使用

正解: C

解説: IRSA (IAM Roles for Service Accounts) は EKS の OIDC Provider を使用して Kubernetes の ServiceAccount と IAM Role を連携します。ServiceAccount に eks.amazonaws.com/role-arn annotation を追加すると、その SA を使用する Pod にのみ特定の IAM 権限が付与されます。

Q30. コンテナのファイルシステムを読み取り専用に設定する securityContext フィールドは?

A) securityContext.immutable: true B) securityContext.readOnlyRootFilesystem: true C) securityContext.noWrite: true D) volumeMounts.readOnly: true

正解: B

解説: securityContext.readOnlyRootFilesystem: true を設定するとコンテナのルートファイルシステムが読み取り専用になります。攻撃者がコンテナ内に悪意あるファイルを作成したりバイナリを改ざんしたりすることを防ぎます。書き込みが必要なパスは emptyDir ボリュームとしてマウントします。

Q31. コンテナが root で実行されないよう強制する設定は?

A) securityContext.runAsUser: 0 B) securityContext.runAsNonRoot: true C) securityContext.privileged: false D) RBAC で制御

正解: B

解説: securityContext.runAsNonRoot: true を設定すると、コンテナが root (UID 0) で実行しようとしたとき Kubernetes がそれをブロックします。runAsUser: 1000 のように特定の UID を指定する方法も有効です。

Q32. Kata Containers の特徴として正しいものは?

A) 通常のコンテナと同様にカーネルを共有する分離 B) 各コンテナ/Pod が軽量 VM と独立したカーネル上で実行 C) ネットワーク分離のみを提供 D) Seccomp プロファイルベースの分離

正解: B

解説: Kata Containers は各コンテナ (または Pod) を軽量 VM 上で実行します。各ワークロードが独立したカーネルを持つため、カーネルの脆弱性を利用したコンテナ脱出が非常に困難です。gVisor とは異なり、実際の Linux カーネルを使用します。

Minimizing Microservice Vulnerabilities (Q33〜Q42)

Q33. Pod Security Admission (PSA) の enforce モードと warn モードの違いは?

A) 違いはない B) enforce はポリシー違反 Pod を拒否、warn は警告のみ表示して許可 C) warn の方が厳格 D) enforce は既存 Pod にも遡及して適用

正解: B

解説: PSA の 3 つのモードのうち enforce はポリシーに違反する Pod の作成を拒否します。warn は違反時に警告メッセージを返しますが Pod は作成されます。audit は監査ログに記録しますが Pod は許可されます。

Q34. OPA Gatekeeper と Kyverno の共通点は?

A) 同じポリシー言語を使用 B) Kubernetes admission webhook として動作してポリシーを強制 C) ランタイム監視ツール D) ネットワークポリシーの管理

正解: B

解説: OPA Gatekeeper と Kyverno はどちらも Kubernetes ValidatingAdmissionWebhook として動作し、リソースの作成/変更時にポリシーを検査して違反を拒否します。Gatekeeper は Rego 言語を、Kyverno は YAML ベースのポリシーを使用するという違いがあります。

Q35. サービスメッシュ (Istio) で mTLS (mutual TLS) を有効にするメリットは?

A) パフォーマンスの向上 B) サービス間通信の双方向認証と暗号化 C) 外部トラフィックのブロック D) データベースの暗号化

正解: B

解説: mTLS はクライアントとサーバーの両方が証明書でお互いを認証します。Istio で PeerAuthentication リソースに STRICT mTLS を設定すると、サービス間の全通信が暗号化され、認証されたサービスのみが通信でき、ラテラルムーブメント攻撃を防止します。

Q36. Kubernetes Secrets をより安全に管理する方法として正しくないものは?

A) etcd の保存時暗号化を有効化 B) Vault や Sealed Secrets を使用 C) Secrets を Git リポジトリに平文で保存 D) RBAC で Secrets へのアクセスを制限

正解: C

解説: Secrets を Git に平文で保存することは非常に危険です。正しい方法は etcd 暗号化、Bitnami Sealed Secrets (暗号化された SealedSecret を Git に保存)、HashiCorp Vault (動的シークレット管理)、AWS Secrets Manager との連携などです。

Q37. Restricted Pod Security Standard に違反する設定は?

A) runAsNonRoot: true B) seccompProfile.type: RuntimeDefault C) privileged: true D) capabilities.drop: ["ALL"]

正解: C

解説: Restricted PSS は最も厳格なプロファイルで privileged: true、hostNetwork、hostPID、hostIPC の使用禁止、特定 capability の追加禁止、runAsNonRoot の必須などを要求します。privileged: true は Privileged PSS でのみ許可されます。

Q38. PodSecurityPolicy (PSP) が deprecated された理由とその代替は?

A) パフォーマンス問題のため、RuntimeClass で代替 B) 複雑さと権限昇格リスクのため、Pod Security Admission で代替 C) 機能不足のため、OPA で代替 D) etcd 互換性の問題

正解: B

解説: PSP は Kubernetes 1.21 で deprecated、1.25 で削除されました。PSP を使用するにはサービスに ClusterRole を通じた PSP use 権限が必要で、その過程で権限昇格が発生する可能性があり、設定も複雑でした。代替は Pod Security Admission (PSA) で、OPA Gatekeeper や Kyverno も使用されます。

Q39. コンテナサンドボックス技術でないものは?

A) gVisor B) Kata Containers C) Firecracker D) Calico

正解: D

解説: gVisor、Kata Containers、Firecracker はコンテナ分離を強化するサンドボックス技術です。Calico は CNI ネットワークプラグインでネットワークポリシーを実装するツールであり、サンドボックス技術ではありません。

Q40. Istio の AuthorizationPolicy の目的は?

A) 証明書の自動更新 B) サービス間のアクセス制御 (誰が誰にリクエストできるかを定義) C) トラフィックのロードバランシング D) コンテナイメージのスキャン

正解: B

解説: Istio の AuthorizationPolicy はサービスメッシュ内で L7 レベルのアクセス制御を実装します。特定のサービス、パス、メソッドに対してどのサービス/ユーザーがアクセスできるかを定義します。mTLS と組み合わせるとゼロトラストネットワーキングを実現できます。

Q41. Secret を環境変数として使用する際のセキュリティリスクは?

A) パフォーマンス低下 B) プロセス環境に公開され /proc/PID/environ で読み取られるか、ログに出力されるリスク C) サイズ制限 D) タイプ制限

正解: B

解説: 環境変数はプロセスの /proc/PID/environ から読み取ることができ、アプリケーションが誤って環境変数をログに出力する可能性があります。ボリュームマウント方式の方が安全で、特に Vault Agent Injector や CSI Secret Store 方式が推奨されます。

Q42. ゼロトラストセキュリティモデルを Kubernetes で実装する方法は?

A) ファイアウォールのみ使用 B) mTLS + RBAC + NetworkPolicy + PSA の組み合わせ C) VPN のみ使用 D) 物理的なネットワーク分離

正解: B

解説: ゼロトラストは「信頼しない、常に検証する」という原則です。Kubernetes では mTLS (サービス間認証)、RBAC (最小権限)、NetworkPolicy (ネットワークマイクロセグメンテーション)、PSA (ワークロードセキュリティ標準) を組み合わせて実装します。

Supply Chain Security (Q43〜Q52)

Q43. Trivy でコンテナイメージをスキャンするコマンドは?

A) trivy scan IMAGE_NAME B) trivy image IMAGE_NAME C) trivy check IMAGE_NAME D) trivy docker IMAGE_NAME

正解: B

解説: trivy image nginx:latest のように trivy image サブコマンドを使用します。CVE データベースをベースにイメージの OS パッケージや言語別依存関係の脆弱性をスキャンします。--severity HIGH,CRITICAL で深刻度のフィルタリングも可能です。

Q44. ImagePolicyWebhook admission controller の役割は?

A) イメージを自動的に最新バージョンに更新 B) 外部ウェブフックサービスにイメージの許可可否を問い合わせ C) イメージの脆弱性を自動修正 D) イメージサイズの制限

正解: B

解説: ImagePolicyWebhook は Pod 作成時に外部ウェブフックサービスにイメージの使用許可可否を問い合わせます。ウェブフックサービスはイメージスキャン結果、署名検証、レジストリポリシーなどに基づいて許可/拒否を応答します。

Q45. Cosign でコンテナイメージに署名するコマンドは?

A) cosign sign --key cosign.key IMAGE_DIGEST B) cosign create-signature IMAGE C) docker sign IMAGE D) kubectl sign image IMAGE

正解: A

解説: cosign sign --key cosign.key IMAGE@sha256:DIGEST でイメージに署名します。署名は OCI レジストリに別のタグとして保存されます。cosign verify --key cosign.pub IMAGE で検証し、Kyverno ポリシーで署名済みイメージのみを許可するよう強制できます。

Q46. SBOM (Software Bill of Materials) とは何ですか?

A) ソフトウェアライセンスの一覧 B) ソフトウェアを構成する全コンポーネント、ライブラリ、依存関係の一覧 C) ソフトウェアのコスト明細 D) ソフトウェアの配布計画書

正解: B

解説: SBOM はソフトウェアに含まれる全てのオープンソースおよび独自コンポーネント、バージョン、ライセンス、脆弱性情報を含む一覧です。CycloneDX、SPDX フォーマットが標準として使用されます。サプライチェーン攻撃の防止と脆弱性追跡に不可欠です。

Q47. Distroless イメージを使用するセキュリティ上のメリットは?

A) イメージサイズが小さくなりビルド速度が向上 B) シェル、パッケージマネージャーなど不要なツールを削除し攻撃面を最小化 C) 無料で使用可能 D) CI/CD パイプラインとの統合が容易

正解: B

解説: Distroless イメージはアプリケーション実行に必要なランタイムのみを含み、シェル (/bin/sh)、パッケージマネージャー、不要なユーティリティがありません。攻撃者がコンテナに侵入しても利用できるツールがなく、被害を最小化できます。

Q48. ValidatingWebhookConfiguration を使用して特定のラベルがない Pod をブロックするには?

A) RBAC ルールを追加 B) webhook サービスが admission review リクエストを検査して拒否レスポンスを返す C) NetworkPolicy を設定 D) Pod 削除コントローラーをデプロイ

正解: B

解説: ValidatingWebhookConfiguration はリソースの作成/変更時に外部 webhook サービスに AdmissionReview リクエストを送信します。webhook サービスはリクエストを検査し allowed: false とメッセージを返すと Kubernetes API サーバーがリソースの作成を拒否します。

Q49. コンテナイメージに latest タグを使わない理由は?

A) latest タグが deprecated になった B) 再現性の欠如 — どのイメージバージョンが実行中か不明 C) レジストリの容量を無駄遣い D) ビルド速度の低下

正解: B

解説: latest タグは変更可能 (mutable) で同じタグで異なるイメージがプッシュされる可能性があります。これによりデプロイの再現性がなく、セキュリティ脆弱性があるイメージが latest としてデプロイされる可能性があります。常に SHA256 ダイジェストや固定バージョンタグを使用すべきです。

Q50. Kyverno ポリシーで latest タグの使用を禁止するポリシータイプは?

A) MutatePolicy B) ClusterPolicy の validate ルール C) GeneratePolicy D) SyncPolicy

正解: B

解説: Kyverno の ClusterPolicyvalidate ルールでイメージタグが latest の場合を拒否できます。deny 条件でイメージタグを検査し、違反時に message とともに拒否します。mutate ルールでイメージを自動変換することもできます。

Q51. ソフトウェアサプライチェーン攻撃の例でないものは?

A) SolarWinds ハッキング B) 悪意ある npm パッケージの配布 C) DDoS 攻撃 D) 依存関係混同攻撃 (Dependency Confusion)

正解: C

解説: サプライチェーン攻撃はソフトウェアの開発/配布パイプラインの脆弱性を悪用します。SolarWinds ビルドサーバーの侵害、悪意ある npm/PyPI パッケージ、Dependency Confusion (プライベートパッケージ名でパブリックパッケージを配布) が代表例です。DDoS は可用性攻撃であり、サプライチェーン攻撃ではありません。

Q52. プライベートコンテナレジストリからイメージを pull する際に認証する Kubernetes リソースは?

A) ServiceAccount B) imagePullSecret C) ConfigMap D) PersistentVolumeClaim

正解: B

解説: プライベートレジストリ認証のために docker-registry タイプの Secret を作成し、Pod spec の imagePullSecrets で参照するか、ServiceAccount の imagePullSecrets に追加します。これにより、その SA を使用する全ての Pod が自動的に認証されます。

Monitoring, Logging and Runtime Security (Q53〜Q55)

Q53. コンテナ内でシェルが実行された際にアラートを生成する Falco 条件は?

A) evt.type=connect and fd.type=ipv4 B) evt.type=execve and container.id!=host and proc.name in (sh, bash, zsh) C) evt.type=open and fd.name contains /etc/passwd D) evt.type=write and fd.name startswith /tmp

正解: B

解説: Falco では execve イベントタイプが新しいプロセスの実行を意味します。container.id!=host はコンテナ内部を、proc.name in (sh, bash, zsh) はシェルプロセスをフィルタリングします。組み込みルール「Terminal shell in container」がこのパターンを使用しています。

Q54. Kubernetes Audit Policy で kube-system namespace の Secrets への get リクエストを記録しないようにするには?

A) audit policy から該当するルールを削除 B) 他のルールより先に level: None のルールを記述 C) kube-system namespace を削除 D) Secrets タイプを変更

正解: B

解説: Audit Policy はルールを順番に評価して最初にマッチしたルールを適用します。level: None で特定の条件をスキップするには、そのルールを他のルールより前 (上部) に記述する必要があります。例えば kube-system の secrets の get リクエストを除外する場合、level: Noneresources: secretsnamespaces: kube-systemverbs: get のルールをファイルの先頭に記述します。

Q55. 侵害された Pod を発見した際の正しい対応順序は?

A) すぐに削除して再デプロイ B) 証拠収集 (ログ、フォレンジック) → Pod の隔離 (NetworkPolicy) → 侵害範囲の把握 → 修正と再デプロイ C) ノードの再起動 D) クラスター全体の再デプロイ

正解: B

解説: インシデント対応の正しい順序は 1) 証拠の保全 (ログ収集、メモリダンプ)、2) 追加被害防止のために NetworkPolicy で対象 Pod のネットワークを隔離、3) 侵害経路と範囲の把握、4) 脆弱性を修正して新しいイメージをビルドしデプロイ、です。すぐに削除するとフォレンジック証拠を失います。


4. 実技シナリオ (P1〜P10)

P1. NetworkPolicy による Pod の隔離設定

# 特定 namespace の Pod のみ DB へのアクセスを許可する NetworkPolicy
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-allow-app-only
  namespace: production
spec:
  podSelector:
    matchLabels:
      app: database
  policyTypes:
  - Ingress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: production
      podSelector:
        matchLabels:
          app: backend
    ports:
    - protocol: TCP
      port: 5432
EOF

P2. ServiceAccount のセキュリティ強化

# 1. 専用 ServiceAccount を作成 (automount 無効化)
kubectl create serviceaccount app-sa -n default

kubectl patch serviceaccount app-sa -n default \
  -p '{"automountServiceAccountToken": false}'

# 2. 必要な権限のみを付与する Role を作成
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: app-role
  namespace: default
rules:
- apiGroups: [""]
  resources: ["configmaps"]
  verbs: ["get", "list"]
EOF

# 3. RoleBinding
kubectl create rolebinding app-binding \
  --role=app-role \
  --serviceaccount=default:app-sa \
  -n default

# 4. 権限確認
kubectl auth can-i get configmaps \
  --as=system:serviceaccount:default:app-sa \
  -n default

P3. etcd 暗号化の設定

# 1. 暗号化キーの生成
head -c 32 /dev/urandom | base64

# 2. EncryptionConfiguration の作成
cat <<EOF > /etc/kubernetes/encryption-config.yaml
apiVersion: apiserver.config.k8s.io/v1
kind: EncryptionConfiguration
resources:
- resources:
  - secrets
  providers:
  - aescbc:
      keys:
      - name: key1
        secret: <BASE64_32BYTE_KEY>
  - identity: {}
EOF

# 3. kube-apiserver manifest の修正
# --encryption-provider-config=/etc/kubernetes/encryption-config.yaml を追加

# 4. 既存 Secrets の再暗号化
kubectl get secrets --all-namespaces -o json | kubectl replace -f -

# 5. etcd で直接確認 (暗号化されて読めないはず)
ETCDCTL_API=3 etcdctl \
  --endpoints=https://127.0.0.1:2379 \
  --cacert=/etc/kubernetes/pki/etcd/ca.crt \
  --cert=/etc/kubernetes/pki/etcd/server.crt \
  --key=/etc/kubernetes/pki/etcd/server.key \
  get /registry/secrets/default/my-secret

P4. AppArmor プロファイルの適用

# 1. ノードで AppArmor の状態を確認
ssh worker-node-1 "aa-status"

# 2. カスタムプロファイルを作成 (ノード上で)
cat <<EOF > /etc/apparmor.d/k8s-custom-profile
#include <tunables/global>

profile k8s-custom-profile flags=(attach_disconnected) {
  #include <abstractions/base>
  file,
  deny /etc/shadow r,
  deny /proc/** w,
}
EOF

# 3. プロファイルをロード
apparmor_parser -r /etc/apparmor.d/k8s-custom-profile

# 4. Pod に AppArmor を適用 (Kubernetes 1.30 以前)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: secured-pod
  annotations:
    container.apparmor.security.beta.kubernetes.io/app: localhost/k8s-custom-profile
spec:
  containers:
  - name: app
    image: nginx:alpine
EOF

P5. Falco ルールのカスタマイズ

# /etc/falco/rules.d/custom-rules.yaml
- rule: Detect Shell in Container
  desc: コンテナ内でシェルが起動された場合にアラート
  condition: >
    spawned_process and
    container and
    proc.name in (shell_binaries)
  output: >
    Shell spawned in container
    (user=%user.name container=%container.name
    image=%container.image.repository proc=%proc.name
    parent=%proc.pname cmdline=%proc.cmdline)
  priority: WARNING
  tags: [container, shell, cks]

- rule: Sensitive File Access
  desc: 機密ファイルへのアクセスを検出
  condition: >
    open_read and
    (fd.name in (/etc/shadow, /etc/sudoers) or
     fd.name startswith /root/.ssh)
  output: >
    Sensitive file accessed
    (user=%user.name file=%fd.name
    container=%container.name proc=%proc.name)
  priority: CRITICAL
  tags: [filesystem, sensitive, cks]
# Falco 再起動後にルールを確認
systemctl restart falco
falco --list | grep "Detect Shell"

P6. Pod Security Admission の設定

# namespace に PSA ラベルを設定
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/warn-version=latest \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/audit-version=latest

# Restricted PSS に準拠した Pod の例
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: restricted-pod
  namespace: production
spec:
  securityContext:
    runAsNonRoot: true
    runAsUser: 1000
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: app
    image: nginx:alpine
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop: ["ALL"]
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: var-cache
      mountPath: /var/cache/nginx
    - name: var-run
      mountPath: /var/run
  volumes:
  - name: tmp
    emptyDir: {}
  - name: var-cache
    emptyDir: {}
  - name: var-run
    emptyDir: {}
EOF

P7. Trivy を使ったイメージスキャン

# HIGH、CRITICAL のみスキャン
trivy image --severity HIGH,CRITICAL nginx:latest

# JSON 形式で出力
trivy image -f json -o scan-result.json nginx:latest

# ファイルシステムのスキャン
trivy fs --security-checks vuln,secret /path/to/project

# Kubernetes クラスター全体のスキャン
trivy k8s --report summary cluster

# CI/CD パイプラインで CRITICAL 発見時に失敗
trivy image --exit-code 1 --severity CRITICAL myapp:latest

P8. Audit Policy の設定

# /etc/kubernetes/audit-policy.yaml
apiVersion: audit.k8s.io/v1
kind: Policy
rules:
  # kube-system の Secrets への get リクエストは記録しない
  - level: None
    resources:
      - group: ''
        resources: ['secrets']
    namespaces: ['kube-system']
    verbs: ['get']

  # Secrets への全アクセスを詳細記録
  - level: RequestResponse
    resources:
      - group: ''
        resources: ['secrets']

  # Pod の変更を記録
  - level: Request
    resources:
      - group: ''
        resources: ['pods']
    verbs: ['create', 'update', 'patch', 'delete']

  # その他の全リクエストはメタデータのみ記録
  - level: Metadata
    omitStages:
      - RequestReceived
# kube-apiserver に適用するフラグ:
# --audit-log-path=/var/log/kubernetes/audit.log
# --audit-policy-file=/etc/kubernetes/audit-policy.yaml
# --audit-log-maxage=30
# --audit-log-maxbackup=10
# --audit-log-maxsize=100

P9. gVisor RuntimeClass の設定

# 1. containerd 設定で gVisor を確認 (/etc/containerd/config.toml)
# [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
#   runtime_type = "io.containerd.runsc.v1"

# 2. RuntimeClass の作成
cat <<EOF | kubectl apply -f -
apiVersion: node.k8s.io/v1
kind: RuntimeClass
metadata:
  name: gvisor
handler: runsc
EOF

# 3. gVisor を使用する Pod のデプロイ
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: sandboxed-pod
spec:
  runtimeClassName: gvisor
  containers:
  - name: app
    image: nginx:alpine
EOF

# 4. サンドボックスの確認 (gVisor カーネルバージョンが表示)
kubectl exec sandboxed-pod -- uname -r

P10. Cosign を使ったイメージ署名と検証

# 1. キーペアの生成
cosign generate-key-pair

# 2. イメージのビルドと push
docker build -t registry.example.com/myapp:v1.0 .
docker push registry.example.com/myapp:v1.0

# 3. イメージへの署名
cosign sign --key cosign.key registry.example.com/myapp:v1.0

# 4. 署名の検証
cosign verify --key cosign.pub registry.example.com/myapp:v1.0

# 5. 署名済みイメージのみを許可する Kyverno ポリシー
cat <<EOF | kubectl apply -f -
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: verify-image-signature
spec:
  validationFailureAction: Enforce
  rules:
  - name: verify-cosign
    match:
      any:
      - resources:
          kinds: ["Pod"]
    verifyImages:
    - imageReferences: ["registry.example.com/*"]
      attestors:
      - entries:
        - keys:
            publicKeys: |-
              -----BEGIN PUBLIC KEY-----
              <COSIGN_PUBLIC_KEY>
              -----END PUBLIC KEY-----
EOF

5. 試験のヒント

  • 試験環境: ブラウザターミナルで kubectlcrictlkubeadmopensslfalcotrivycosign などが使用可能
  • コンテキスト切り替え: 問題ごとに kubectl config use-context でクラスターを切り替えることが必須
  • ブックマーク: killer.sh、Kubernetes 公式ドキュメントなど許可されたリソースを積極活用
  • 優先順位: 配点の高い問題から解き、難しい問題は後回し
  • 検証: 設定変更後は必ず kubectl getkubectl describe で確認