TT Lab
はじめる
学ぶ 学習パス コース

CKS — Kubernetesセキュリティスペシャリスト

監査ポリシーを設計する

TT Labで続きを見る

目標

audit.k8s.io/v1の監査ポリシーファイルを、ルールを1つずつ積み上げて作りながら、ルールの順序とレベルの選択が、何を残し、何を捨てるのかを自分で確認します。

なぜ重要なのか

侵害対応の最初の問いは、いつも「いつ、誰が、何をしたのか」であり、Kubernetesでそれに答えられる唯一の資料が、APIサーバーの監査ログです。すべてを記録するとコストが爆発し、いい加減に記録すると、肝心なときに何も残っていません。そのため、監査ポリシーは、「何を記録するか」ではなく「何を捨てるか」を決める文書です。

最もよくある2つの間違いを、このラボで自分で体験します。1つ目は、ルールが上から評価されて最初に一致した1つだけが適用されるため、除外ルール(level: None)が下にあると、何の効果もないことです。2つ目は、SecretにRequestResponseを設定すると、監査ログファイルの中にSecretの値がそのまま入ることです。監査ログを収集するシステムは、たいていアプリケーションよりアクセス権限が広いため、守ろうとしたものを広めてしまう結果になります。

この環境では、監査ログを実際に有効にすることはできません(kwokのコントロールプレーンには、ポリシーファイルをもう一度マウントできません)。採点はポリシーファイルの内容と順序だけを見ます。CKS試験で採点されるのも、結局このファイルです。Falcoのルールとcrictlによるランタイムの調査は、このモジュールの理論とクイズで扱います。

ステップ

  1. /root/cks-audit-runtime/audit-policy.yamlを作成してください。apiVersion: audit.k8s.io/v1、kind: Policyで、rulesの最後のルールは、条件なしでlevel: Metadataとする包括ルールにします。
  2. 同じファイルの最上位にomitStagesを置き、RequestReceivedを入れてください。
  3. rulesに、SecretとConfigMapをlevel: Metadataで記録するルールを追加してください。コアグループのsecretsとconfigmapsを対象にします。ファイル内のどのルールも、secretsに対してRequestやRequestResponseを指定してはいけません。
  4. rulesの一番上に、kube-systemネームスペースのsecretsのgetリクエストをlevel: Noneで除外するルールを入れてください。このルールの位置は、ステップ3で作成したルールより必ず前でなければなりません。
  5. rulesに、RBACリソース(rbac.authorization.k8s.ioグループのroles、rolebindings、clusterroles、clusterrolebindings)に対するescalate、bind、impersonateの動詞をlevel: RequestResponseで記録するルールを追加してください。
  6. rulesに、コアグループのpodsのcreate、update、patch、deleteをlevel: Requestで記録するルールを追加してください。
  7. /root/cks-audit-runtime/apiserver-audit-flags.txtに、APIサーバーに付けるフラグを1行に1つずつ書いてください。--audit-policy-file=/etc/kubernetes/audit-policy.yaml、--audit-log-path=/var/log/kubernetes/audit.log、--audit-log-maxage=30、--audit-log-maxbackup=10、--audit-log-maxsize=100の5つです。

参考

監査ポリシーの骨組みと包括ルール

/root/cks-audit-runtime/audit-policy.yamlを作成してください。apiVersion: audit.k8s.io/v1、kind: Policyで、rulesの最後のルールは、条件なしでlevel: Metadataとする包括ルールにします。

ポリシーはaudit.k8s.io/v1のPolicyリソースです。どれにも一致しなかったリクエストを受け止める包括ルールが、一番下になければなりません。

ノイズになる段階を取り除く

同じファイルの最上位にomitStagesを置き、RequestReceivedを入れてください。

1つのリクエストは、複数の段階でイベントを作ります。リクエストを受け取った時点のイベントは、ほとんど役に立ちません。最上位のフィールドとして指定すると、全体に適用されます。

Secretはメタデータまで

rulesに、SecretとConfigMapをlevel: Metadataで記録するルールを追加してください。コアグループのsecretsとconfigmapsを対象にします。ファイル内のどのルールも、secretsに対してRequestやRequestResponseを指定してはいけません。

SecretにRequest以上のレベルを設定すると、監査ログファイルの中にSecretの値がそのまま入ります。どのルールも、secretsに対してRequest以上を指定してはいけません。

kube-systemのノイズを除外する

rulesの一番上に、kube-systemネームスペースのsecretsのgetリクエストをlevel: Noneで除外するルールを入れてください。このルールの位置は、ステップ3で作成したルールより必ず前でなければなりません。

ルールは上から評価され、最初に一致した1つだけが適用されます。除外ルールが下にあると、上のルールが先に捕まえてしまいます。

権限昇格の試みはすべて記録する

rulesに、RBACリソース(rbac.authorization.k8s.ioグループのroles、rolebindings、clusterroles、clusterrolebindings)に対するescalate、bind、impersonateの動詞をlevel: RequestResponseで記録するルールを追加してください。

RBACリソースは、コアグループではなくrbac.authorization.k8s.ioグループです。verbsに、危険な動詞を3つともすべて書いてください。

Podの変更はリクエスト本文まで

rulesに、コアグループのpodsのcreate、update、patch、deleteをlevel: Requestで記録するルールを追加してください。

参照は除いて、変更する動詞だけを選びます。リクエスト本文を残せば、侵害後にどのマニフェストがデプロイされたかを再構成できます。

総合: 監査ログバックエンドのフラグを文書化する

/root/cks-audit-runtime/apiserver-audit-flags.txtに、APIサーバーに付けるフラグを1行に1つずつ書いてください。--audit-policy-file=/etc/kubernetes/audit-policy.yaml、--audit-log-path=/var/log/kubernetes/audit.log、--audit-log-maxage=30、--audit-log-maxbackup=10、--audit-log-maxsize=100の5つです。

ポリシーファイルの場所、ログの出力先、そしてローテーションのポリシーの3つをすべて書く必要があります。ローテーションの設定がないとディスクが埋まり、ディスクが埋まるとAPIサーバーが止まります。