はじめに
FalcoはOSSとして開発されているランタイムセキュリティツールで、LinuxのシステムコールやKubernetesのAudit Logなどをソースとして、ルールを比較し、異常な動作や潜在的なセキュリティ脅威をリアルタイムで検知し、アラートを発することができます。
https://falco.org/
本記事では、kindで作成したKubernetesクラスタでFalcoを動作させて、その挙動を確認します。
環境情報
| Component | Version |
|---|---|
| PC | M1 MacBook Pro |
| OS | macOS 26.2 |
| Docker Desktop | 4.56.0 |
| kind | 0.31.0 |
| helm | v4.0.5 |
| falco | 0.42.1 |
手順
Kubernetesクラスタを作成する
kindコマンドでfalco-sandboxというKubernetesクラスタを立ち上げます。
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
name: falco-sandbox
nodes:
- role: control-plane
- role: worker
上記のyamlファイルを元にKubernetesクラスタを作成します。
kind create cluster --config kind-sandbox.yaml
Falcoのインストール
helm経由でインストールするため、レポジトリを追加します。
helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update
modern_ebpfモードでインストールします。
❯ helm install falco falcosecurity/falco \
--namespace falco --create-namespace\
--set driver.kind=modern_ebpf \
--set tty=true
正常にPodが立ち上がるか確認します。
k -n falco get po
デフォルトルールでの検知テスト
nginxのPodを立てて、execでシェルに入ります。
k run nginx --image=nginx
k exec -it nginx -- sh
別のターミナルで、Falcoのログを確認します。
k -n falco logs -l app.kubernetes.io/name=falco -f
正常に実行できていれば、以下のようにシェルが生成されたことが通知されます。
(snip)
Notice A shell was spawned in a container with an attached terminal
(snip)
Falcoの設定ファイル
Falcoの主な設定ファイルは以下の3つがあります。
| Component | Version |
|---|---|
| /etc/falco/falco.yaml | Falco本体の設定 |
| /etc/falco/falco_rules.yaml | デフォルトのルールセット |
| /etc/falco/falco_rules.local.yaml | ユーザー定義 |
例えば、先ほど確認したデフォルトルールにあったシェルの実行検知は /etc/falco/falco_rules.yaml に以下のように設定があります。
k -n falco exec -it falco-g454b -c falco -- less /etc/falco/falco_rules.yaml
(snip)
- rule: Terminal shell in container
desc: >
A shell was used as the entrypoint/exec point into a container with an attached terminal. Pare
nt process may have
legitimately already exited and be null (read container_entrypoint macro). Common when using "
kubectl exec" in Kubernetes.
Correlate with k8saudit exec logs if possible to find user or serviceaccount token used (fuzzy
correlation by namespace and pod name).
Rather than considering it a standalone rule, it may be best used as generic auditing rule whi
le examining other triggered
rules in this container/tty.
condition: >
spawned_process
and container
and shell_procs
and proc.tty != 0
and container_entrypoint
and not user_expected_terminal_shell_in_container_conditions
output: A shell was spawned in a container with an attached terminal | evt_type=%evt.type user=%
user.name user_uid=%user.uid user_loginuid=%user.loginuid process=%proc.name proc_exepath=%proc.ex
epath parent=%proc.pname command=%proc.cmdline terminal=%proc.tty exe_flags=%evt.arg.flags
priority: NOTICE
tags: [maturity_stable, container, shell, mitre_execution, T1059]
(snip)
特定のファイルへのアクセスを検知する
/tmp/secrets にアクセスしたことを検知してみます。
以下の custom-rules.yaml を作成します。
customRules:
rules-custom.yaml: |-
- rule: Detect Access to Secret File
desc: Alert when /tmp/secret is touched
condition: >
fd.name = "/tmp/secret" and evt.dir = <
output: "Security alert! Access to secret file detected (user=%user.name command=%proc.cmdline)"
priority: WARNING
helm upgradeを実行し、 custom-rules.yaml を適用します。
helm upgrade falco falcosecurity/falco \
--namespace falco \
--set driver.kind=modern_ebpf \
--set tty=true \
-f custom-rules.yaml
customRulesに設定を追加すると、 /etc/falco/rules.d 配下に設定ファイルが追加されます。
k -n falco exec -it falco-kzj7m -c falco -- ls /etc/falco/rules.d
rules-custom.yaml
k -n falco exec -it falco-kzj7m -c falco -- cat /etc/falco/rules.d/rules-custom.yaml
- rule: Detect Access to Secret File
desc: Alert when /tmp/secret is touched
condition: >
fd.name = "/tmp/secret" and evt.dir = <
output: "Security alert! Access to secret file detected (user=%user.name command=%proc.cmdline)"
priority: WARNING
nginx Podの /tmp/secret にアクセスしてみます。
k exec -it nginx -- touch /tmp/secret
以下のメッセージがログに出力されていたら、正しく動作しています。
k -n falco logs -l app.kubernetes.io/name=falco -f
(snip)
Warning Security alert! Access to secret file detected
(snip)
既存ルールの無効化
デフォルトルールを上書きし、nginxコンテナはシェル実行の検知を除外する設定を追加してみます。
custom-rules.yaml を以下のように更新してみます。
customRules:
rules-custom.yaml: |-
- rule: Detect Access to Secret File
desc: Alert when /tmp/secret is touched
condition: >
fd.name = "/tmp/secret" and evt.dir = <
output: "Security alert! Access to secret file detected (user=%user.name command=%proc.cmdline)"
priority: WARNING
- rule: Terminal shell in container
desc: >
A shell was used as the entrypoint/exec point into a container with an attached terminal. Parent process may have
legitimately already exited and be null (read container_entrypoint macro). Common when using kubectl exec" in Kubernetes.
Correlate with k8saudit exec logs if possible to find user or serviceaccount token used (fuzzycorrelation by namespace and pod name).
Rather than considering it a standalone rule, it may be best used as generic auditing rule while examining other triggered
rules in this container/tty.
condition: >
and not container.image endswith nginx
override:
condition: append
desc: replace
helm upgradeを実行し、 custom-rules.yaml を適用します。
helm upgrade falco falcosecurity/falco \
--namespace falco \
--set driver.kind=modern_ebpf \
--set tty=true \
-f custom-rules.yaml
nginxのPodでシェルを実行しますが、先ほどのようなシェルが実行された旨のログは出力されていません。
k exec -it nginx -- sh
最後に
kindで作成したKubernetesクラスタでFalcoの挙動を確認してみました。