ブログ
HOME Developer Square ブログ 【SCSK技術者によるブログ】Falco初学者講座 - condition編
【SCSK技術者によるブログ】Falco初学者講座 - condition編
皆さんこんにちは。
第14回担当の渡邊です。
今回はSysdigのふるまい検知で利用されているFalcoのルールについて解説していきます。
はじめに
Sysdigユーザや、OSSのFalcoを利用されている方の中には「Falcoのカスタマイズ性、ロジックの透明性の高さが魅力だ」という方が多数いらっしゃるのではないでしょうか。
一方でSysdigを使い始めたユーザからは「ふるまい検知の記述式や考え方がよくわからない」といった声が寄せられることもあるため、「Falcoって複雑そうだ」と苦手意識を感じている方も多いのではないでしょうか。
今回は初めてFalcoを学習する人向けにFalcoの概要からFalcoのルールで最も重要なconditionとその構成要素について解説していきます。
Falcoとは何でしょうか
Falcoは実行環境上のシステムコールを監視し、条件に当てはまった振る舞い(システムコール)をアラートとしてユーザへ通知するOSSです。
元々はSysdigが開発していましたが、CNCFへ寄贈され、2024年からはCNCFでもGraduated(卒業)という位置づけに変わり現在に至ります。
FalcoはSysdigのふるまい検知(XDR)のコア技術となっています。
OSSのFalcoについては次のページで確認してみてください。
Falco - https://falco.org
Falcoのルールとは
Falcoではふるまい検知の定義をルールと呼び、その中でもアラートとして通知する条件文をconditionという要素として記述します。
SysdigではこのルールをFalco Ruleと呼んで扱います。
ルールがどのような構成かについては次の項目で説明します。
ルールの例
Falcoのルールは以下のように定義されます。
細かい部分は省略しますが、このルールでは「コンテナ上でbashもしくはkshが呼び出された」際にアラートを通知します。
```yaml - rule: shell_in_container desc: notice shell activity within a container condition: > evt.type = execve and evt.dir = < and container.id != host and (proc.name = bash or proc.name = ksh) output: > shell in a container (user=%user.name container_id=%container.id container_name=%container.name shell=%proc.name parent=%proc.pname cmdline=%proc.cmdline) priority: WARNING ```
参考: https://falco.org/docs/rules/basic-elements/#rules
Conditionについて
ご紹介したルールではrule, desc, condition, output、priorityの5つの要素によって構成されていることが分かります。 この中で最も重要な要素がconditionです。conditionはfalcoで検知したいふるまいを定義する要素で、ルールの根幹です。
上記のルールはユーザ目線では次のような意味になります。
「execveシステムコール、かつexitイベントのシステムコールであり、かつコンテナIDがhostではなく、さらにプロセス名がbashかkshのいずれか」の際にFalcoがアラートを通知します。
conditionについてさらに深堀してみましょう。
conditionで使用する記述(論理演算子、初級編)
ルールをご覧いただいてお分かりになった方もいらっしゃると思いますが、ルールの記述にはいくつかの演算子が必要です。 ここでは、その中でも基本となる演算子、=, not, and, orの4つを紹介します。
- = (Xと一致するとき)
=(イコール)は、左辺のKey(Falcoではフィールドと呼びます)が右辺のValueと一致する値を持つ場合。という条件を構成できます。 上記の中ではevt.type = execveが当てはまり、ユーザ目線で解釈すると「execveシステムコールが検知されたとき」という意味になります。
その他にもproc.name = bashであれば、「プロセス名がbashの時」という意味です。
evt.typeとかproc.nameという語が突然出てきて困惑された方もいるかもしれませんね。
これはフィールドと呼ばれ、項目ごとに決まった値が格納されるようになっています。
例えばproc.nameであればプロセス名が格納される。といったように、フィールドごとに取り得る値が決まっています。
フィールドについては記事の末尾に補足情報として載せているので、気になった方は確認してみてください。 - notもしくは!= (Xと一致しないとき)
notは!=とも表現することができ、左辺のKeyが右辺のValueと一致する値を持たない場合。という条件を構成できます。
上記の中では、container.id != hostが当てはまり、ユーザ目線で解釈すると「containerIDがhost以外の値を持つとき」という意味になります。
また、notは他の演算子と組み合わせる事ができ、and not, or not の様に表現することができます。 - and (XかつYのとき)
andは2つ以上の条件を同時に満たす場合。という条件を構成できます。
上記の中では evt.type = execve and evt.dir = < の部分が当てはまり、
ユーザ目線で解釈すると「execveシステムコールかつ、exitイベントのシステムコールのとき」という意味になります。
exitイベントのシステムコール。というのはなじみのない言葉かもしれませんが、以下のドキュメントを参考にしてみてください。
https://falco.org/docs/reference/rules/supported-fields/#field-class-evt-for-system-calls
端的に言えば、OSからのレスポンスを意味します。 - or (XもしくはYのとき)
orは2つ以上の条件のいずれかを満たす場合。という条件を構成できます。
上記の中ではproc.name = bash or proc.name = kshが当てはまり、ユーザ目線での解釈では「プロセス名がbash、もしくはkshのとき」という意味になります。
conditionで使用する記述(括弧編)
ルールでは括弧を使用することもできます。
括弧は、括弧の中に記述される式をひとかたまりに扱う。という意味になります。
先ほどのshell_in_containerでは(proc.name = bash or proc.name = ksh)の部分が当てはまります。
括弧が使われている個所を抽出すると container.id != host and (proc.name = bash or proc.name = ksh) の様になりますが、これは「container.idがhostでないことに加え、proc.nameがbash、もしくはkshのとき」という意味になります。 見方を変えると、上記の式は次のように分解することもできます。
-------------------------------------------- container.id != host and proc.name = bash or container.id != host and proc.name = ksh --------------------------------------------
補足情報: evt.typeやproc.nameって何?
ここまでルールのconditionについてざっと説明してきましたが、evt.typeやproc.nameといった要素には触れてきませんでした。
これらはフィールドと呼ばれ、システムコールに付随する様々な要素が格納されます。
取り得る値はフィールドごとに決まっていて、例えばproc.nameであればプロセス名が格納されるようになっています。
フィールドをうまく使う事で、宛先IPアドレスが192.168.0.0/24以外と通信した時にアラートを通知するといった監視も実現できます。 詳しくは以下のドキュメントを見てみてください。
参考: 条件と出力でサポートされているフィールド https://falco.org/docs/reference/rules/supported-fields/
理解度クイズ
さて、conditionへの理解を深めていただけたでしょうか?
最後に理解度を確かめるための問題を出します。よく考えてみてくださいね。
Q1. proc.nameがcatの時にアラートを通知するルールを作ってみてください。
Q2. user.name = root and not proc.name = tailのルールはどの様な振る舞いをアラートとして通知しますか?
Q3. proc.ttyが0でないとき、かつproc.pnameがbash、もしくはzsh、かつfd.sip.nameがsysdigの時にアラートを通知するルールを作ってみてください。
答えは次のようになります。
Q1の答え: proc.name = cat
Q2の答え: ユーザ名がrootかつ、プロセス名がtailではないふるまい。
Q3の答え:
例: proc.tty != 0 and (proc.pname = bash or proc.pname = zsh) and fd.sip.name = sysdig
最後に
今回はFalcoの仕組みを解説しました。初めてFalcoに触れる方の学習の一助になれば幸いです。Falcoはカスタマイズ性が非常に高いため、自分でカスタマイズできるようになると、今まであきらめていたセキュリティ要件を実現するなど、ワンランク上のSysdig活用術を身につけることができます。
今後もFalco Ruleに関する情報をご紹介できればと思います。
担当者紹介
- 担当者名
- 渡邊
- コメント
- コード好き。アニメやドラマにターミナルの画面が出てくると、その内容がどのぐらい正確か必ずチェックします。
- 保有資格
- Certified Kubernetes Administrator
Certified Kubernetes Application Developer