24
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Falcoを利用したPod内実行コマンドのログ取得

Last updated at Posted at 2020-06-03

はじめに

Kubernetesの監査ログといえばKubernetes Audit Loggingを利用した、Kubernetes API に対してのリクエストログの事を指します。
しかし、監査ログとして「いつ」「だれが」「何をしたか」を確認するためにはpod内で実行されたコマンドもログとして取得する必要があると感じています。

そこで、今回は kubectl exec 等でpod内で実行されたコマンドをログ取得する方法としてFalcoを検証してみました。

Falcoとは?

Falcoの公式ページにて下記の紹介があります。

Falcoは、アプリケーションの異常なアクティビティを検出するように設計されたビヘイビアアクティビティモニタです。もともとSysdigによって構築されたパワフルなシステムコールキャプチャテクノロジーを使用します。Falcoでは、1組の[ルール]を使用して、コンテナ、アプリケーション、ホスト、およびネットワークアクティビティを1か所で、1つのデータソースから継続的に監視および検出できます。

詳細な説明は公式ページを見てもらうのが確実です。
今回は「kubectl execにてpod内にて実行されたコマンドをログとして出力する事ができるツール」として利用します。

検証環境

  • EKS
  • Kubernetes v1.16

今回は下記の様な環境を作ってpod内にて実行されたコマンドをlogとして取得できるかを検証します。

falco_qiita_image.png

Falcoのデプロイ

FalcoのInstall方法は公式ページのドキュメントに日本語で記載されています。
今回は DaemonSet マニフェスト の箇所を参考にデプロイをしました。

※注意:公式ページの紹介しているリポジトリと実際のリポジトリが異なります。2020年05月31日現在
デプロイに関するファイルが別リポジトリに移動されています。正しいリポジトリはこちら

また、公式マニュアルではconfigmapの作成を kubectl create にて行っていますが、CI/CDを考慮してコード管理ができるようにします。
マニフェストファイルでは複数の外部ファイルを参照してconfigmapを作成する事ができないのでkustomizeのconfigMapGeneratorを使って実現しました。

kustomization.yaml
resources:
  - rbac.yaml
  - daemonset.yaml

configMapGenerator:
- name: falco-config
  files:
  - falco-config/falco.yaml
  - falco-config/falco_rules.yaml
  - falco-config/falco_rules.local.yaml

ドキュメント通りに進めてkustomization.yamlを設置すると下記のようなディレクトリ構成になります。

.
├── daemonset.yaml
├── falco-config
│   ├── falco.yaml
│   ├── falco_rules.local.yaml
│   ├── falco_rules.yaml
│   └── k8s_audit_rules.yaml
├── kustomization.yaml
└── rbac.yaml

上記ディレクトリにてapplyする事でKubernetes上にDaemonSetとしてFalcoをDeployする事ができます。

$ kubectl get pod 
NAMESPACE           NAME                                      READY   STATUS    RESTARTS   AGE
default             falco-daemonset-z9xh6                     1/1     Running   0          37s
default             falco-daemonset-t4dr9                     1/1     Running   0          38s

Falcoのルール作成

Falcoではlogの出力条件を『ルール』として定義します。
ルールの定義箇所はデフォルトのルールファイルとローカルルールファイルがそれぞれあります。

  • falco_rules.yaml (デフォルトのルールファイル)
    • 最初に呼び出されるファイル
    • 事前定義された基礎的なルールが含まれている
    • このルールファイルは変更されず、新しいソフトウェアバージョンごとに置き換えられることが意図されている
  • falco_rules.local.yaml(ローカルルールファイル)
    • falco_rules.yamlの後に呼び出されるファイル
    • falco_rules.yaml に対する追加、オーバーライド、変更等を定義する
    • このルールファイルはソフトウェアバージョンごとに置き換わる事は無い

falco_rules.yaml はfalcoのバージョンが変わった際に置換する可能性があるのでカスタムルールを作成する際は falco_rules.local.yaml に記載しましょう。

falcoのカスタムルール作成は公式マニュアルが例を記載してあるので大変参考になります。
あらかじめ定義されているマクロ各種フィールドを組み合わせて condition として定義する事でログの出力条件とする事ができます。
フィールドを組み合わせて任意のマクロを作成する事も可能です。

今回はpod内のshellで実行した全てのログを取得したいので新規プロセスを検知するマクロを使用しました。

利用するマクロ
- macro: spawned_process
  condition: evt.type = execve and evt.dir=<

上記マクロをconditionに追加した下記ルールを falco_rules.local.yaml に追記します。

- rule: Unexpected activity
  desc: Detected Unexpected activity
  condition: spawned_process
  output: >
    Unexpected process spawned in container
    (command=%proc.cmdline pid=%proc.pid user=%user.name %container.info image=%container.image)
  priority: INFO

falco_rules.local.yaml の編集が完了したところで再度falcoのDaemonSetをapplyしてください。

注意点
falco_rules.yamlの中にはKubernetes APIのlog取得に関するルールも記述されています。
EKS等のマネージドなKubernetes環境を利用している場合、Kubernetes APIのlogがクラスターのオプションとして取得できる事が多いのでどちらを利用するかは運用次第かと思います。
Falco以外でKubernetes APIのlogを取得する際は下記部分をコメントアウトすると良さそうです。
2020/06/14 更新
falco_rules.yaml の内容を変更したい場合は falco_rules.local.yaml にて上書きするべきでした。
falco_rules.yaml は 『このルールファイルは変更されず、新しいソフトウェアバージョンごとに置き換えられることが意図されている』 為です。

下記ruleを falco_rules.local.yaml に追記する事でAPIのlog取得ルールをdisableに上書きする事ができました。

- rule: Contact K8S API Server From Container
  desc: Detect attempts to contact the K8S API Server from a container
  condition: evt.type=connect and evt.dir=< and (fd.typechar=4 or fd.typechar=6) and container and not k8s_containers and k8s_api_server
  output: Unexpected connection to K8s API Server from container (command=%proc.cmdline %container.info image=%container.image.repository:%container.image.tag connection=%fd.name)
  priority: NOTICE
  tags: [network, k8s, container, mitre_discovery]
  enabled: false

Falcoで取得したlogの確認

実際にpod内のshellでコマンドを実行してlogを取得できているか確認してみます。

falcoのpod内でコマンドを実行
$ kubectl exec -it falco-daemonset-7sxx6 -- bash 
root@falco-daemonset-7sxx6:/#
root@falco-daemonset-7sxx6:/# whoami
root
root@falco-daemonset-7sxx6:/# ping 8.8.8.8

falcoのlogにて上記コマンド実行のlogが残っているか確認します。
podのlogとして記録されるのでで下記コマンドにてlogを確認する事ができます。

$ kubectl logs falco-daemonset-7sxx6
falcoの出力log
"09:00:59.029886506: Notice Unexpected process spawned in container (command=whoami pid=28214 user=root k8s.ns=defalut k8s.pod=falco-daemonset-7sxx6 container=afa3528dd4a0 image=falcosecurity/falco@sha256:70e3e3c46a37a98642f9cd8490235c414ee1c7d670cde65345fa20187971c0a0)\n"
"09:01:11.611216799: Notice Unexpected process spawned in container (command=ping 8.8.8.8 pid=28486 user=root k8s.ns=defalut k8s.pod=falco-daemonset-7sxx6 container=afa3528dd4a0 image=falcosecurity/falco@sha256:70e3e3c46a37a98642f9cd8490235c414ee1c7d670cde65345fa20187971c0a0)\n"

コマンドの実行日時やどのpodで実行されたかもlogにあるので監査ログとして利用できそうです。

念の為、同じNodeにのっている別のpodでもコマンドを実行してみました。

同じNode上のexample-podにてコマンドを実行
$ kubectl exec -it example-pod -- bash 
root@example-pod:/#
root@example-pod:/# cat /etc/hostname
example-pod
root@example-pod:/#

falcoのlogにて上記コマンド実行のlogが残っているか確認します。

falcoの出力log
"09:21:30.694701115: Notice Unexpected process spawned in container (command=cat /etc/hostname pid=24018 user=root k8s.ns=defalut k8s.pod=example-pod container=d5158de43f2d image=hogehoge@sha256:34cf6e68a67f1dc80958824af97e16c1fd78e21d1e8313f56f62628816cc85c9)\n",

別のpodでもlogが取得できているので問題なさそうです。

総評

情報収集コマンドも含めて全てfalcoのpodにlogとして出力されていました。
取得内容は実行されたpod名、実行コマンド、日時と揃っているので監査logとして利用する事ができそうです。
kubectl exec実行ユーザーについてはKubernetes API側のlogにて出てるはずなのでログを比較する事で、「いつ」「だれが」「何をしたか」を調査する事はできると思います。

podのlogとして出力されるのでEKSであればCloudWatchlogsを使って取得してS3に保存するといった運用が可能な点も使いやすいと感じました。

気になった点としてexeternal-secretsやexternal-dns等カスタムコントローラを利用している際に該当のpodからKubernetes APIへの通信が不正通信扱いになり、大量のlogが流れていました。
これらの利用する際は該当のlogを除外するruleを定義する等の対応が必要になりそうです。

ruleがとても柔軟に定義できるため、今回の用途以外でもFalcoを活用できる場面は多々あるかと思います。
皆様も是非色々とお試しください。

24
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?