はじめに
前回の記事では、Falcoの概要とその仕組みについて紹介しました。
今回は、Falco Ruleについて詳しく解説します。
Falco Ruleとは
Falco Ruleは、システムコールやKubernetesのイベントなど、システム上のさまざまなアクティビティを監視し、特定の条件に一致した場合にアラートを生成するためのポリシーです。
Falco Ruleの利用方法
Falco Ruleは、Falco Controller(Daemon)によって読み込まれ、Rule Engineによって評価されます。
Kubernetes環境でFalcoを利用する場合、事前にFalco Rulesを作成し、設定ファイルに追加する必要があります。
Custom Ruleの追加やDefault Ruleの上書きは、すべてFalcoの設定ファイルを通じて行います。
Falco Ruleの上書きの適用はFileの読み込み順番で決まります。
一般的な順番は以下です。
rules_files:
- /etc/falco/falco_rules.yaml
- /etc/falco/falco_rules.local.yaml
- /etc/falco/faclo_plugin_***.yaml
- /etc/falco/rules.d
そのうち、/etc/falco以下のyamlが先に読み込まれます。
Helmなどを利用している場合、Custom Fileは/etc/falco/rules.d/以下に自動的に追加されるので、Plugin/Default Ruleに対する修正として最後に適用されます。
また、小規模な利用は、/etc/falco/rules.dではなく、falco_rules.local.yamlの修正が推奨されています。
詳細な設定方法(Helmなど)については、次回の記事で解説します。
Falco Ruleの構成
Falco Ruleの本体は、以下の基礎フィールドで構成されています。
- rule: Falco Ruleの名前、識別子
- condition: アラートを生成する条件
- output: アラート発生時の出力メッセージ
- priority: アラートの重要度
また、オプションフィールドとして、以下のものも設定可能です
- tags: Ruleのカテゴリや特性を示すタグ
- desc: Ruleの説明
- enabled: Rule自体の有効化か無効化
- exceptions: 特定の条件下でアラートを生成しないための例外設定
Falco Rule File(Set)の構成
Falco Rule Fileは、以下の3つの要素で構成されます。
-
Rule: Falco Rule本体
-
Macro: Rule内で再利用可能な条件の断片
共通の条件として複数のRuleで利用することが可能です
例えば、以下のK8s Deployment Created
というRuleでは、kactivity
などのMacroを複数利用しています。別のRuleでもkactivity
が多用されています- macro: kcreate condition: ka.verb=create - macro: kactivity condition: (kevt and consider_activity_events) - macro: response_successful condition: (ka.response.code startswith 2) - macro: deployment condition: ka.target.resource=deployments - rule: K8s Deployment Created desc: Detect any attempt to create a deployment condition: (kactivity and kcreate and deployment and response_successful) # ...
-
List: 特定の値の集合(RuleやMacro内で参照可能)
RuleやMacro内で参照できます。
例えば、Disallowed K8s User
というRuleでは、事前に許可したユーザ(eks_allowed_k8s_users
)を定義し、RuleのConditionから除外しました- list: eks_allowed_k8s_users items: [ "eks:node-manager", "eks:certificate-controller", "eks:fargate-scheduler", "eks:k8s-metrics", "eks:authenticator", "eks:cluster-event-watcher", "eks:nodewatcher", "eks:pod-identity-mutating-webhook", "eks:cloud-controller-manager", "eks:vpc-resource-controller", "eks:addon-manager", ] - rule: Disallowed K8s User desc: Detect any k8s operation by users outside of an allowed set of users. condition: kevt and non_system_user and not ka.user.name in (allowed_k8s_users) and not ka.user.name in (eks_allowed_k8s_users) # ...
Falco RulesのOverride
既存のRuleやMacro、Listは環境や要件に応じてカスタマイズが可能です。
Overrideの方法
Custom Rule File内でoverrideセクションを使用することで、既存のList、Macro、Ruleを上書きまたは追加できます。具体的には、以下の2つの操作が可能です:
- append: 既存のListやMacro、Ruleに新しい値や条件を追加
- replace: 既存のListやMacro、Ruleを完全に置き換え
前述のk8s_auditの例を利用して、Overrideのやり方を紹介します。
conditionのOverride
例えば、K8s Deployment CreatedというRuleに「default Namespace以外」という条件を追加し、既存のRuleをOverrideします。
k8s_auditのRule本文:
- macro: kcreate
condition: ka.verb=create
- macro: kactivity
condition: (kevt and consider_activity_events)
- macro: response_successful
condition: (ka.response.code startswith 2)
- macro: deployment
condition: ka.target.resource=deployments
- rule: K8s Deployment Created
desc: Detect any attempt to create a deployment
condition: (kactivity and kcreate and deployment and response_successful)
# ...
Override時の構文:
- rule: K8s Deployment Created
condition: and ka.target.namespace != default # Appendの場合は追加部分のみを記載
desc: Detect any attempt to create a deployment except default namespace # Replaceの場合は新しい内容を用意する
override:
condition: append
desc: replace
listのOverride
例えば、Disallowed K8s User
というRuleに特定ユーザを許可するようにOverrideします
k8s_auditのRule本文:
- list: eks_allowed_k8s_users
items:
[
"eks:node-manager",
"eks:certificate-controller",
"eks:fargate-scheduler",
"eks:k8s-metrics",
"eks:authenticator",
"eks:cluster-event-watcher",
"eks:nodewatcher",
"eks:pod-identity-mutating-webhook",
"eks:cloud-controller-manager",
"eks:vpc-resource-controller",
"eks:addon-manager",
]
- rule: Disallowed K8s User
desc: Detect any k8s operation by users outside of an allowed set of users.
condition: kevt and non_system_user and not ka.user.name in (allowed_k8s_users) and not ka.user.name in (eks_allowed_k8s_users)
# ...
Override時の構文:
- list: eks_allowed_k8s_users # List名も識別子です
items:
[
"eks:network-policy-controller",
"eks:coredns-autoscaler",
"eks:az-poller"
]
override:
items: append
enableのOverride
上記の二つのRuleをdisableにする例です。
- rule: K8s Deployment Created
enable: false
override:
enable: replace
- rule: Disallowed K8s User
enable: false
override:
enable: replace
Falco Rulesの難しさ
難点1: セキュリティエンジニアの不在
すべての組織にセキュリティ専門のエンジニアがいるわけではありません。
特に小規模なチームでは、DevOpsやSREの特定メンバーがFalcoの導入と運用を兼任するケースが多く、Ruleの最適化に時間を割くのが難しいです。
難点2: Ruleの精査とチューニングの負担
Falcoはデフォルトで多数のRuleを提供していますが、すべての環境で適用できるわけではありません。むしろ、多くのRuleが過剰なアラートを生み出し、ノイズが増えてしまうことがあります。
そのため、
- Ruleの内容を理解し、自組織に適したものを選別する
- 不要なRuleを無効化または調整する
といった作業が必要になります。この精査とチューニングには、セキュリティに関する一定の知識が求められるため、導入のハードルが上がります。
小規模環境での最適な運用方法
小規模な環境でFalcoを効率的に運用するには、以下の方針を意識すると良いと思います。
Ruleはできるだけ新規作成せず、既存のものを活用
特定のセキュリティ問題がない限り、ゼロからRuleを作成するのではなく、既存のRuleを活用しましょう。新しいRuleを増やすと、その分メンテナンスコストも上がります。
既存のRuleの活用方法は以下となります。
-
必要なRuleのみを抽出して新しいRule Fileを作成
組織の要件に合うRuleだけを選別し、新しいRule Fileを作成すると管理しやすくなります。
例えば、AWS関連のRuleSetを作成したい場合、以下のFalco RulesからAWS関連のRuleを抽出して、新しいRuleSetとして利用することができます。-
AWS CloudTrail Rules
- (必要に応じて)全て
-
Falco Stable Rules
- Find AWS Credentials
-
Falco Incubating Rules
- Contact EC2 Instance Metadata Service From Container
-
AWS CloudTrail Rules
-
既存のRule Fileを導入し、一部のRulesを無効化または調整
Default Ruleをそのまま使うのではなく、
- 不要なRuleを無効化
- 一部のRuleを組織のポリシーに合わせて修正
することで、誤検知を減らしつつ必要なセキュリティ監視を維持できます。
例えば、ExternalSecretOperatorを利用している場合、k8s_audit RuleSetの K8s Secret Get Successfully Error Ruleに引っかかってしまいます。
そのため、以下の修正を加えることでExternalSecretOperatorからのイベントを条件から外すことができます。- rule: K8s Secret Get Successfully condition: and not ka.user.name startswith "system:serviceaccount:external-secret-operator:external-secrets-" override: condition: append
また、一部のRuleが要らないであれば、以下の方法でdisableすることもできます。
- rule: Create Sensitive Mount Pod enabled: false override: enabled: replace - rule: Create HostNetwork Pod enabled: false override: enabled: replace - rule: Pod Created in Kube Namespace enabled: false override: enabled: replace
EKSでのプラクティス
私のEKS上でのFalco運用経験に基づき、以下のアプローチがある程度効果的だと考えています。
1. KubernetesのAuditログを監視する
ほとんどの組織では、KubernetesのAuditログを監視するだけで、基本的なセキュリティニーズを満たせます。
-
k8saudit-eks pluginを利用
-
Falco Controller(Daemon) DaemonSetは使用しない
-
k8s_audit Ruleを適用
-
一部のRuleはListを追加して調整するか、無効化する
# Helm customRules: k8s_audit_rules_common_override.yaml: |- # customRules以下のFileは自動的に`/etc/falco/rules.d`で作成される - rule: Create HostNetwork Pod enabled: false override: enabled: replace - rule: Pod Created in Kube Namespace enabled: false override: enabled: replace serviceAccount: create: true annotations: - eks.amazonaws.com/role-arn: <IAM Role ARN> # CloudWatch Logsの権限が必要 driver: # 各ノードの監視が不要であるため enabled: false collectors: # 各ノードの監視が不要であるため enabled: false controller: kind: deployment # デフォルトはDaemonSet deployment: replicas: 1 falco: rules_files: - /etc/falco/k8s_audit_rules.yaml # k8s_audit_rulesのみ追加 - /etc/falco/rules.d load_plugins: [ k8saudit-eks, json ] plugins: - name: k8saudit-eks library_path: libk8saudit-eks.so init_config: shift: 10 polling_interval: 10 use_async: false buffer_size: 500 open_params: <EKS Cluter名> - name: json library_path: libjson.so init_config: ""
2. コンテナ内部のファイル操作や通信アクティビティの監視
必要に応じて、コンテナ内部の動作も監視対象に含めることができます。
-
FalcoのDefault stable ruleを導入
-
監視対象が多くなりすぎないよう、重要なRuleを選別
-
不要なRuleは無効化または調整
# Helm customRules: falco-sandbox_rules_selected.yaml |- # 選別したSandbox Rules追加 falco-incubating_rules_selected.yaml |- # 選別したIncubating Rules追加 falco_rules_override.yaml |- # Stable Rulesの置き換え serviceAccount: create: true annotations: - eks.amazonaws.com/role-arn: <IAM Role ARN> # CloudWatch Logsの権限が必要 falco: rules_files: - /etc/falco/falco_rules.yaml # Stable Rules追加 - /etc/falco/k8s_audit_rules.yaml # k8s_audit_rulesのみ追加 - /etc/falco/rules.d load_plugins: [ k8saudit-eks, json ] plugins: - name: k8saudit-eks library_path: libk8saudit-eks.so init_config: shift: 10 polling_interval: 10 use_async: false buffer_size: 500 open_params: <EKS Cluter名> - name: json library_path: libjson.so init_config: ""
おすすめのRules
- Stable Rules:
- Incubating Rules:
-
Network Connection outside Local Subnet
namespace_scope_network_only_subnet
対象のContainerになるので、事前の定義が必要 -
Launch Package Management Process in Container
特に本番環境では利用した方がいい - Contact EC2 Instance Metadata Service From Container
- Unexpected UDP Traffic
-
Network Connection outside Local Subnet
- Sandbox Rules:
- K8s Audit Rules:
-
Create Privileged Pod
Gatekeeperとの併用がおすすめです -
Attach/Exec Pod
デフォルトはNOTICE
レベルですが、本番環境ではERROR
レベルに上げるのおすすめです -
Disallowed K8s User
k8s_audit_rulesの中に、事前に定義済みのリストがあります。例えば、Disallowed K8s UserというRulesは、以下のConditionの中で二つのListallowed_k8s_users
とeks_allowed_k8s_users
を利用しています。
condition: kevt and non_system_user and not ka.user.name in (allowed_k8s_users) and not ka.user.name in (eks_allowed_k8s_users)
既存のListへ信頼できるユーザを追加してもいいし、正規表現で一括除外しても良いです- list: allowed_k8s_users items: [ "system:serviceaccount:kube-system:argocd-manager" ] override: items: append - list: eks_allowed_k8s_users items: [ "eks:network-policy-controller", "eks:coredns-autoscaler", "eks:az-poller" ] override: items: append - rule: Disallowed K8s User condition: and not ka.user.name regex "^arn:aws:iam::[0-9]+:role/(role-a|role-b)/.+" override: condition: append
-
重要なリンク
Falco Default Rules
Stable, Incubating, Sandboxの3種類が用意されています。
Falco PluginのRules
Rulesのブラウザ
DefaultとPlugin Rulesが含まれています。公式ではないため、あくまで参考用です。
自前のRule Setを作成した場合、下記のRepoから自前で運用した方がいいと思います。
Falco Rules公式ドキュメント
文法のチェックやRulesの一覧を確認するには有用です。
コミュニティRules
conditionを書く際に役にたつリンク
Conditionは大抵のロジックを表現できます。また、パターンマッチやstartswithなどのComparison operatorsも利用できます。
Conditionで設定するイベントとフィールドは幅広く利用できます。詳細は以下のドキュメントで参照できます。
Pluginで利用するフィールドは、各PluginのREADMEで記載されています。
例えばk8s_audit
まとめ
本記事では、Falco Ruleの基本構成や運用方法について解説しました。Falcoを適切にカスタマイズすることで、誤検知を減らしつつセキュリティ監視を強化できます。
次回は、FalcoをHelmで導入する方法について詳しく紹介します。