コンテンツにスキップ

Kubernetes 監査ログ収集

Kubernetes の監査(Audit)は、セキュリティ関連の時系列操作記録を提供します。これには、時刻、送信元、操作結果、操作を実行したユーザー、対象リソース、リクエスト/レスポンスの詳細などが含まれます。

設定

前提条件

  • K8S 環境をインストール済み
  • DataKit をインストール済み

監査ログポリシーを有効化する

❗すでに有効な場合は、ここは読み飛ばしてください

Kubernetes 1.24 を例に、監査ログポリシーを有効化します

  • マスターノードにログインする

cd /etc/kubernetes

  • audit-policy.yml を追加する
audit-policy.yml
# Copyright © 2022 sealos.
#
# Apache License, Version 2.0(「License」)に基づいてライセンスされています。
# このファイルは License に従わない限り使用できません。
# License のコピーは次の URL から入手できます。
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# applicable law または書面での合意により必要とされない限り、
# software は、明示的または黙示的を問わず、いかなる保証もなく
# 「現状有姿」で配布されます。
# License に基づく特定の権限と制限については、License を参照してください。

apiVersion: audit.k8s.io/v1 # 必須です。
kind: Policy
# RequestReceived ステージでのすべてのリクエストに対して監査イベントを生成しない。
omitStages:
- "RequestReceived"
rules:
# 以下のリクエストは、手動で高頻度かつ低リスクと判定されたため、
# 破棄します。
- level: None
    users: [ "system:kube-proxy" ]
    verbs: [ "watch" ]
    resources:
    - group: "" # core
        resources: [ "endpoints", "services" ]
- level: None
    users: [ "system:unsecured" ]
    namespaces: [ "kube-system" ]
    verbs: [ "get" ]
    resources:
    - group: "" # core
        resources: [ "configmaps" ]
- level: None
    users: [ "kubelet" ] # legacy kubelet identity
    verbs: [ "get" ]
    resources:
    - group: "" # core
        resources: [ "nodes" ]
- level: None
    userGroups: [ "system:nodes" ]
    verbs: [ "get" ]
    resources:
    - group: "" # core
        resources: [ "nodes" ]
- level: None
    users:
    - system:kube-controller-manager
    - system:kube-scheduler
    - system:serviceaccount:kube-system:endpoint-controller
    verbs: [ "get", "update" ]
    namespaces: [ "kube-system" ]
    resources:
    - group: "" # core
        resources: [ "endpoints" ]
- level: None
    users: [ "system:apiserver" ]
    verbs: [ "get" ]
    resources:
    - group: "" # core
        resources: [ "namespaces" ]
# これらの読み取り専用 URL はログに残さない。
- level: None
    nonResourceURLs:
    - /healthz*
    - /version
    - /swagger*
# events リクエストはログに残さない。
- level: None
    resources:
    - group: "" # core
        resources: [ "events" ]
# Secrets、ConfigMaps、TokenReviews には機微情報とバイナリデータが含まれる可能性があるため、
# Metadata レベルのみで記録する。
- level: Metadata
    resources:
    - group: "" # core
        resources: [ "secrets", "configmaps" ]
    - group: authentication.k8s.io
        resources: [ "tokenreviews" ]
# GET 応答は大きくなることがあるため、スキップする。
- level: Request
    verbs: [ "get", "list", "watch" ]
    resources:
    - group: "" # core
    - group: "admissionregistration.k8s.io"
    - group: "apps"
    - group: "authentication.k8s.io"
    - group: "authorization.k8s.io"
    - group: "autoscaling"
    - group: "batch"
    - group: "certificates.k8s.io"
    - group: "extensions"
    - group: "networking.k8s.io"
    - group: "policy"
    - group: "rbac.authorization.k8s.io"
    - group: "settings.k8s.io"
    - group: "storage.k8s.io"
# 既知の API に対するデフォルトレベル
- level: RequestResponse
    resources:
    - group: "" # core
    - group: "admissionregistration.k8s.io"
    - group: "apps"
    - group: "authentication.k8s.io"
    - group: "authorization.k8s.io"
    - group: "autoscaling"
    - group: "batch"
    - group: "certificates.k8s.io"
    - group: "extensions"
    - group: "networking.k8s.io"
    - group: "policy"
    - group: "rbac.authorization.k8s.io"
    - group: "settings.k8s.io"
    - group: "storage.k8s.io"
    - group: "autoscaling.alibabacloud.com"
# その他すべてのリクエストのデフォルトレベル。
- level: Metadata

💡対応するポリシー情報は、実際の要件に応じて調整できます。

API Server で監査ログを有効化する

❗すでに有効な場合は、ここは読み飛ばしてください

ディレクトリ /etc/kubernetes/manifests に入り、まず kube-apiserver.yaml をバックアップしてください。バックアップしたファイルは /etc/kubernetes/manifests/ の下に置かないでください。ファイル内容を調整します。

  • spec.containers.command に次のコマンドを追加します。
  - command:
    - kube-apiserver
    - --advertise-address=10.0.16.204
    - --allow-privileged=true
    - --audit-log-format=json
    - --audit-log-maxage=7
    - --audit-log-maxbackup=10
    - --audit-log-maxsize=100
    - --audit-log-path=/var/log/kubernetes/audit.log
    - --audit-policy-file=/etc/kubernetes/audit-policy.yml
  • spec.containers.volumeMounts に次を追加します。
    - mountPath: /etc/kubernetes
      name: audit
    - mountPath: /var/log/kubernetes
      name: audit-log
  • spec.volumes に次を追加します。
  - hostPath:
      path: /etc/kubernetes
      type: DirectoryOrCreate
    name: audit
  - hostPath:
      path: /var/log/kubernetes
      type: DirectoryOrCreate
    name: audit-log
  • 反映する

API Server が変更されると自動的に再起動されるので、数分待てば大丈夫です。

  • 確認

次のコマンドを実行し、audit.log ファイルが生成されているか確認してください。生成されていれば、反映済みです。

ls /var/log/kubernetes

K8S 監査ログを収集する

K8S 監査ログは対応する master ノードの /var/log/kubernetes ディレクトリに保存されます。ここでは annotation 方式で収集します。

  • pod を作成する: k8s-audit-log.yaml
apiVersion: v1
kind: Pod
metadata:
  name: kube-audit-log
  annotations:
        datakit/logs: |
          [
            {
              "disable": false,
              "type": "file",
              "path":"/var/log/kubernetes/audit.log",
              "source":  "k8s-audit",
              "tags" : {
                "atype": "kube-audit-log"
              }
            }
          ]

spec:
  containers:
  - name: kube-audit-log
    image: busybox
#    command: ["sleep", "1"]
    args:
    - /bin/sh
    - -c
    - >
      i=0;
      while true;
      do
        i=$((i+1));
        sleep 10;
      done
    volumeMounts:
    - mountPath: /var/log/kubernetes
      name: datakit-vol-opt
  volumes:
  - name: datakit-vol-opt
    hostPath: 
      path: /var/log/kubernetes
  nodeSelector:
     kubernetes.io/hostname: k8s-master
  tolerations:
  - key: "node-role.kubernetes.io/master"
    operator: "Exists"
    effect: "NoSchedule"
  - key: "node-role.kubernetes.io/control-plane"
    operator: "Exists"
    effect: "NoSchedule"

❗現在の pod は master ノードでのみ実行できます。

  • 実行
kubectl apply -f k8s-audit-log.yaml 
  • 確認

数分後に Guance 上で対応するログを確認できます。json 形式のため、Guance では @+json フィールド名で検索できます。たとえば @verb:update⁠ のように指定します。

監査ログのフィールド抽出

監査ログを収集した後、Guance の pipeline 機能を使って監査ログの主要フィールドを抽出し、さらに詳細なデータ分析を行えます。

  • Guance の ログ - pipeline - 新規作成
  • 対応するログソース k8s-audit を選択する
  • Pipeline 名称: kubelet-audit
  • 解析ルールを定義する
abc = load_json(_)

add_key(kind, abc["kind"])
add_key(level, abc["level"])
add_key(stage, abc["stage"])
add_key(verb, abc["verb"])
add_key(auditID, abc["auditID"])
add_key(username, abc["user"]["username"])
add_key(responseCode, abc["responseStatus"]["code"])
if abc["responseStatus"]["code"]==200 {
  add_key(status, "OK")
}else{
  add_key(status, "FAIL")
}
add_key(sourceIP_0,abc["sourceIPs"][0])

add_key(namespace,abc["objectRef"]["namespace"])
add_key(node,abc["objectRef"]["name"])
  • スクリプトの取得テストをクリックする
  • 保存する

フィードバック

このページは役に立ちましたか?