Kubernetesの監査ログとFalcoを使い始める

By 清水 孝郎 - FEBRUARY 9, 2021

SHARE:

本文の内容は、2021年2月9日にPawan Shankarが投稿したブログ(https://sysdig.com/blog/kubernetes-audit-log-falco/)を元に日本語に翻訳・再構成した内容となっております。

Kubernetesの採用が拡大し続ける中、Kubernetesの監査ログは、Kubernetesのセキュリティ戦略に組み込むための重要な情報源となっています。これにより、セキュリティチームとDevOpsチームは、クラスター内で発生しているすべてのイベントを完全に可視化することができます。

Kubernetes監査ログ機能はKubernetes 1.11で導入されました。監査ログは、新しいデプロイメントの作成、ネームスペースの削除、ノードポートサービスの開始などのイベントをキャプチャーするため、Kubernetesクラスターのセキュリティを確保する上で重要な機能です。

この記事では、Kubernetesの監査ログとは何か、どのような情報を提供するのか、そしてクラスター内の不審なアクティビティを検出するためにFalco (オープンソースのランタイムセキュリティツール)と統合する方法を学びます。

Kubernetesの監査ログのメリット

Kubernetes の監査ログを統合することで、次のような質問に答えることができます。
  • 何が起こったのか?どの新しいポッドが作成されたのか?
  • 誰がやったのか?ユーザー、ユーザーグループ、またはサービスアカウント
  • それはいつ発生したのか?イベントのタイムスタンプ
  • どこで発生したか?ポッドが作成されたネームスペース
Kubernetesクラスターでは、監査を実行するのはkube-apiserverです。例えば、リクエストがネームスペースを作成すると、それはkube-apiserverに送られます。

攻撃者や不注意な管理者がクラスターをいじった場合、その行為は監査ログに登録されます。セキュリティツールはこのログのイベントを解析して、不審な活動を警告することができます。
falcoでkubernetesの監査ログを処理する図
各リクエストは、関連するステージで記録することができます。定義されたステージは以下の通りです。
  • RequestReceived: リクエストが処理されずに監査ハンドラによって受信されるとすぐにイベントが生成されます。
  • ResponseStarted: レスポンスヘッダーが送信されると、イベントが生成されます。レスポンスヘッダが送信された後、レスポンスボディが送信される前に発生します。このステージは、長時間実行されるリクエスト (watch など) に対してのみ生成されます。
  • ResponseComplete: レスポンスボディが送信されたときにイベントが生成されます。
  • Panic: パニックが発生したときにイベントが発生します。
では、実際に見てみましょう。Kubernetes監査ポリシーを導入し、Kubernetes監査を有効にする方法を紹介します。

Kubernetesの監査ポリシー:一例

Kubernetesクラスターはアクティビティでいっぱいなので、そのすべてを記録するのは現実的でも現実的でもありません。監査ポリシーを使えば、イベントをフィルタリングして、必要なものだけを記録することができます。

セキュリティを考慮して、ポッド、kube-proxy、シークレット、設定、その他の重要なコンポーネントに関連するリクエストをフィルタリングするポリシーを作成します。


このようなポリシーは以下のようになります:
apiVersion: audit.k8s.io/v1 # This is required.
kind: Policy
# Don't generate audit events for all requests in RequestReceived stage.
omitStages:
  - "RequestReceived"
rules:
  # Log pod changes at RequestResponse level
  - level: RequestResponse
    resources:
    - group: ""
      # Resource "pods" doesn't match requests to any subresource of pods,
      # which is consistent with the RBAC policy.
      resources: ["pods"]
  # Only check access to resource "pods"
  - level: Metadata
    resources:
    - group: ""
      resources: ["pods/log", "pods/status"]
  # Don't log watch requests by the "system:kube-proxy" on endpoints or services
  - level: None
    users: ["system:kube-proxy"]
    verbs: ["watch"]
    resources:
    - group: "" # core API group
      resources: ["endpoints", "services"]
  # Don't log authenticated requests to certain non-resource URL paths.
  - level: None
    userGroups: ["system:authenticated"]
    nonResourceURLs:
    - "/api*" # Wildcard matching.
    - "/version"
  # Log the request body of configmap changes in kube-system.
  - level: Request
    resources:
    - group: "" # core API group
      resources: ["configmaps"]
    # This rule only applies to resources in the "kube-system" namespace.
    # The empty string "" can be used to select non-namespaced resources.
    namespaces: ["kube-system"]
  # Log configmap and secret changes in all other namespaces at the Metadata level.
  - level: Metadata
    resources:
    - group: "" # core API group
      resources: ["secrets", "configmaps"]
  # A catch-all rule to log all other requests at the Metadata level.
  - level: Metadata
    # Long-running requests like watches that fall under this rule will not
    # generate an audit event in RequestReceived.
    omitStages:
      - "RequestReceived"
Kubernetesの監査を有効にするだけでなく、これらのルールを適用する方法の1つとして、kube-apiserverの起動時に–audit-policy-fileフラグを定義した監査ポリシーファイルと一緒に渡すという方法があります。

ご覧のように、1つのKubernetes監査ポリシーで複数の監査ルールを設定することができます。


各監査ルールを定義するフィールドは以下の通りです:
  • lebel: イベントの冗長性を定義する監査レベル。
  • resources: 監査対象のオブジェクト (例: “ConfigMaps” など)。
  • nonResourcesURL: リソースに関連付けられていない、リソースに関連付けられていない URL (Uniform Resource Locator) パス。
  • namespace: 監査対象のネームスペース内の特定のオブジェクト。
  • verb: 監査のための特定の操作 (作成、更新、削除)。
  • users: ルールが適用される認証済みのユーザー。
  • userGroups: ルールが適用される認証済みユーザー グループ。
  • omitStages: 指定されたステージでのイベント生成をスキップします。
監査レベルは、イベントをどの程度記録するかを定義します。4つの監査レベルがあります。

  • None: このルールに一致するイベントをログに記録しません。
  • Metadata: リクエストのメタデータ(リクエストするユーザー、タイムスタンプ、リソース、verbなど)を記録しますが、リクエストやレスポンスのボディは記録しません。
  • Request: イベントのメタデータとリクエストボディは記録しますが、レスポンスボディは記録しません。これはリソース以外のリクエストには適用されません。
  • RequestResponse: イベントのメタデータ、リクエスト、レスポンスボディを記録します。これはリソース以外のリクエストには適用されません。
イベントが処理され、監査ポリシールールと比較されると、最初に一致したルールがイベントの監査レベルを設定することに注意してください。これは、最も制限の多いものに応じてルールが適用される Kubernetes や RBAC ポリシーとは異なります。

イベントを受信する監査バックエンドとしてのFalcoの設定

フォレンジック調査が行われるのを待っているだけのログでは、時間通りに脅威に対応することはできません。

ホスト侵入検知(HIDS)のようなセキュリティツールと統合することで、監査ログの可能性をすべて解き放つことができます。

2つの方法のいずれかでイベントを送信することで、Kubernetesの監査ログをセキュリティツールと統合することができます。

  • ログのバックエンド: ファイルシステムにイベントを書き込む。セキュリティツールが同じマシンにインストールされていれば、ファイルを解析することができます。jq のような json パーサーを使って手動でファイルを処理し、クエリーを構築することもできます。
  • Webhook バックエンド: イベントを外部の HTTP API に送信します。そうすれば、セキュリティツールはファイルシステムへのアクセスを必要としません。
以下の例では、Webhookバックエンドを使用してFalcoにイベントを送信します。

オープンソースのクラウドネイティブランタイムセキュリティプロジェクトであるFalcoは、デファクトのKubernetes脅威検知エンジンです。Falcoは2016年にSysdigによって作成され、CNCFにインキュベーションレベルのプロジェクトとして初めて参加したランタイムセキュリティプロジェクトです。Falcoは、予期せぬアプリケーションの動作を検出し、ランタイムで脅威をアラートします。Linuxのシステムコールを介してSysdigのオープンソースライブラリをタップすることで、ハイパフォーマンスな本番環境で動作させることができます。

Falcoは、Webhookバックエンドとして、Kubernetes API監査イベントをインジェストし、我々のオーケストレーション活動のランタイム検出とアラートを提供します。Falcoには、最も一般的な脅威の検出を開始するのに役立つ、すぐに使えるルールの包括的なセットが同梱されています。これらのルールを簡単にカスタマイズしたり、独自のルールを作成して、組織のニーズに合わせてFalcoを適応させることができます。

falcoでkubernetesの監査ログを処理する図。

apiVersion: v1
    kind: Config
    clusters:
    - name: falco
     cluster:
       server: http://$FALCO_SERVICE_CLUSTERIP:8765/k8s_audit
    contexts:
    - context:
       cluster: falco
       user: ""
     name: default-context
    current-context: default-context
    preferences: {}
    users: []

server フィールドの URL エンドポイントは、監査イベントが送信されるリモートエンドポイントです。

webhook バックエンドを有効にするには、webhook 設定ファイルで –audit-webhook-config-file フラグを設定する必要があります。

Kubernetesのバージョン1.13から1.18では、AuditSinkオブジェクトを介して動的にwebhookバックエンドを設定することもできます。この機能は 1.19 から削除されていることに注意してください。

End-to-Endの例

監査ポリシーを定義し、WebhookバックエンドがKubernetesの監査ログをFalcoに送信するように設定されたので、それに命を吹き込んでみましょう!

以下の例のようなconfigmapをKubernetes APIにpostします:
apiVersion: v1
data:
 ui.properties: |
   color.good=purple
   color.bad=yellow
   allow.textmode=true
 access.properties: |
   aws_access_key_id = MY-ID
   aws_secret_access_key = MY-KEY
kind: ConfigMap
metadata:
 name: my-config
 namespace: default
 実行させます;
> kubectl create -f badconfigmap.yaml
これは次のようなout-of-the-boxのルールをトリガーします (GitHub でルールの全リストを確認することができます)。
- rule: Create/Modify Configmap With Private Credentials
  desc: >
     Detect creating/modifying a configmap containing a private credential (aws key, password, etc.)
  condition: kevt and configmap and kmodify and contains_private_credentials
  exceptions:
    - name: configmaps
      fields: [ka.target.namespace, ka.req.configmap.name]
  output: K8s configmap with private credential (user=%ka.user.name verb=%ka.verb configmap=%ka.req.configmap.name config=%ka.req.configmap.obj)
  priority: WARNING
  source: k8s_audit
  tags: [k8s]

今、Falcoのログを見てみると(ポッド名が変わっています)。
> kubectl tail -f falco-b4ck9
以下のようなアラート/検出が表示されるはずです:
Warning Kubernetes configmap with private credential (user=minikube-user verb=create configmap=my-config config={"access.properties":"aws_access_key_id=MY-ID aws_secret_access_key=MY-KEY","ui.properties":"color.good=purple color.bad=yellow allow.textmode=true"})

まとめ

Kubernetesのセキュリティ戦略を強化するためには、Kubernetesの監査ログイベントのような疑わしいイベントや誤った設定を可視化できるようなものを取り入れて、新しい機能や改善点に気を配ることが重要です。

これらのログで収集された情報は、クラスター内で何が起こっているのかを把握するのに非常に役立ちますし、コンプライアンスの目的で必要とされることもあります。

ルールを慎重にチューニングし、必要に応じてあまり冗長ではないモードを使用することで、SaaSの集中型ログソリューションを使用する際のコスト削減にも役立ちます。

しかし、ここで本当に違いが出るのは、脅威検知エンジンとしてFalcoを使用していることです。WebhookのバックエンドにFalcoを選択することは、Kubernetesセキュリティのベストプラクティスを実施し、誤用を検出し、クラスターが実行されていると思われるものと実際に実行されているものとの間のギャップを埋めるための第一歩となります。

Falcoについてもっと詳しく知りたい方はこちらをご覧ください。
Sysdig Secureでは、他のオープンソースプロジェクトとともにFalcoでアウトオブボックスのルールを拡張し、Kubernetesセキュリティの作業と管理をさらに簡単にしています。30日間の無料トライアルに登録して、ご自身の目で確かめてみてください。