Upgrade to Pro — share decks privately, control downloads, hide ads and more …

eBPFで実現するコンテナランタイムセキュリティ / Container Runtime Security with eBPF

eBPFで実現するコンテナランタイムセキュリティ / Container Runtime Security with eBPF

オンラインテックカンファレンス CloudNative Security Conference 2022 by CloudNative Days で発表した「eBPFで実現するコンテナランタイムセキュリティ」の登壇資料です。
https://event.cloudnativedays.jp/cnsec2022

資料内のURLは、PDFをダウンロードするとクリックで遷移できます。

eBPFはLinuxカーネルが提供する機能の一つで、近年、ネットワークやObservabilityといった文脈で注目を集めています。本セッションでは、セキュリティの観点から、eBPFを利用することで実現できることについて整理した上で、コンテナランタイムセキュリティを実現する具体的なeBPFツールとしてFalco、Tracee、Tetragonを紹介します。

2f73f93f91c4401b0baf12029226a681?s=128

TERAOKA Keisuke
PRO

August 05, 2022
Tweet

More Decks by TERAOKA Keisuke

Other Decks in Technology

Transcript

  1. eBPFで実現する コンテナランタイムセキュリティ 2022/8/5 CloudNative Security Conference 2022 TERAOKA Keisuke

  2. 寺岡慶佑 (とばち) • クラスメソッド株式会社 ◦ ソリューションアーキテクト ◦ → 8/1〜 prismatix

    Devチーム • 2022 APN ALL AWS Certifications Engineer & 2021 APN AWS Top Engineer • 趣味 ◦ 紅茶、ビール 発表者紹介 @toda_kk
  3. 本セッションで話すこと • eBPFとは何か? • コンテナのセキュリティに関してeBPFをどのように活用 できるのか? • eBPFを利用したコンテナセキュリティツールを紹介 ◦ Falco

    / Tracee / Tetragon ◦ 各ツールを比較して優劣をつけることではなく、各ツールの特徴 や使い方を紹介することが目的
  4. 今日のタイトル eBPFで実現する コンテナランタイムセキュリティ

  5. 今日のタイトル eBPFで実現する コンテナランタイムセキュリティ ? ?

  6. eBPFとは何か?

  7. Linuxに対するeBPFは HTMLに対するJavaScriptみたいなもの eBPFとは何か?

  8. eBPFとは何か? eBPF does to Linux what JavaScript does to HTML.

    (Sort of.) So instead of a static HTML website, JavaScript lets you define mini programs that run on events like mouse clicks, which are run in a safe virtual machine in the browser. And with eBPF, instead of a fixed kernel, you can now write mini programs that run on events like disk I/O, which are run in a safe virtual machine in the kernel. In reality, eBPF is more like the v8 virtual machine that runs JavaScript, rather than JavaScript itself. eBPF is part of the Linux kernel. https://www.brendangregg.com/blog/2019-01-01/learn-ebpf-tracing.html
  9. • Linuxカーネルが提供する機能のひとつ • パケットフィルタリングやシステムコールの実行など カーネルにおける多くのイベントをフックして、任意の 処理を実行できる ◦ カーネル内のサンドボックス化されたVM上で実行できる ◦ 通常はC言語で処理を実装する

    • カーネルの挙動を変えずにイベントを取得できる ◦ カーネルのオーバーヘッドが少なくて済む eBPFとは何か?
  10. eBPFでは多くのイベントを取得可能 https://www.brendangregg.com/blog/2019-01-01/learn-ebpf-tracing.html

  11. • 1992年、バークレー研究所の論文でBerkley Packet Filter(BPF)が発表される ◦ その名の通り、パケットフィルタリングの技術として発表される • 1997年、LinuxカーネルにLinux Socket Filterとして

    BPFが追加される • 2013年、Alexei StarovoitovがBPFの拡張を提案する ◦ extended BPF → eBPF ▪ 現在はBPFと言えばeBPFを指し、それ以前の機能はcBPFと呼ばれる • 2014年、LinuxカーネルにeBPFが追加される eBPF登場までの経緯 https://blog.yuuk.io/entry/2021/ebpf-tracing
  12. そもそも Linuxカーネルよくわからん

  13. Linuxカーネルよくわからん

  14. • Linuxではユーザー空間とカーネル空間で分離されている ◦ ユーザーが実行するプロセスはユーザー空間で実行され、安全上 の理由からアクセスできる領域が制限される • カーネルでは、プロセスやメモリやネットワークなどを 管理する ◦ さらにその下にハードウェアがあり、カーネルがハードウェアを

    抽象化することでユーザー空間から扱えるようになっている • ユーザープロセスからカーネルの処理を呼び出すには、 Linuxカーネルに対してシステムコールを通じて依頼する Linuxカーネルよくわからん
  15. • ユーザープロセスとカーネルは分離されている ◦ ユーザープロセスがカーネル上の動作や振る舞いを検知するため には、なんらかの仕組みが必要 • カーネルモジュールという、カーネルを拡張できる機能 をLinuxカーネルが提供している ◦ 自由度が高い反面、安全性が保証できない

    • eBPFでは、Linuxカーネルそのものは書き換えず、イベ ントをフックしてカーネル内のVMで処理を実行する ◦ 使えるLinuxの機能や文法に制限はあるものの、プログラムの安 全性を検証する仕組みを持つ LinuxカーネルモジュールとeBPF
  16. eBPFの仕組み https://ebpf.io/what-is-ebpf

  17. eBPFの仕組み https://ebpf.io/what-is-ebpf eBPFプログラムを バイトコードに コンパイル

  18. eBPFの仕組み https://ebpf.io/what-is-ebpf bpf(2)システ ムコールで Verifierに 渡す

  19. eBPFの仕組み https://ebpf.io/what-is-ebpf Verifierで eBPFプログラムの 安全性を検証

  20. eBPFの仕組み https://ebpf.io/what-is-ebpf 最適化のために バイトコードを マシン命令セットに 変換

  21. eBPFの仕組み https://ebpf.io/what-is-ebpf eBPFプログラムを 各イベントに アタッチ

  22. • 通常はC言語で処理を実装し、LLVM Clangでバイトコー ドにコンパイルする • 簡単にeBPFプログラムを実装できるように、IO Visorか らBCCというライブラリが用意されている ◦ BPF

    Compiler Collection ◦ PythonやLuaをフロントエンドとして用いてeBPFプログラミン グできるようにするもの ◦ IO Visorではないが、他にもGoやRustで実装可能にするライブ ラリが公開され、他言語による実装のための環境が整いつつある BCCを使ったeBPFプログラミング https://github.com/iovisor/bcc
  23. #!/usr/bin/python from bcc import BPF from bcc.utils import printb prog

    = """ int hello(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; } """ b = BPF(text=prog) b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello") b.trace_print() BCCを使ったHello World https://zenn.dev/masibw/articles/068bdfe5edee17 hello_world.py
  24. #!/usr/bin/python from bcc import BPF from bcc.utils import printb prog

    = """ int hello(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; } """ b = BPF(text=prog) b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello") b.trace_print() BCCを使ったHello World https://zenn.dev/masibw/articles/068bdfe5edee17 hello_world.py eBPFプログラム本体
  25. #!/usr/bin/python from bcc import BPF from bcc.utils import printb prog

    = """ int hello(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; } """ b = BPF(text=prog) b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello") b.trace_print() BCCを使ったHello World https://zenn.dev/masibw/articles/068bdfe5edee17 hello_world.py eBPFプログラムの読み込み
  26. #!/usr/bin/python from bcc import BPF from bcc.utils import printb prog

    = """ int hello(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; } """ b = BPF(text=prog) b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello") b.trace_print() BCCを使ったHello World https://zenn.dev/masibw/articles/068bdfe5edee17 hello_world.py clone(2)システムコール実行を トリガーとして指定
  27. #!/usr/bin/python from bcc import BPF from bcc.utils import printb prog

    = """ int hello(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; } """ b = BPF(text=prog) b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello") b.trace_print() BCCを使ったHello World https://zenn.dev/masibw/articles/068bdfe5edee17 hello_world.py 実行する関数名を指定
  28. #!/usr/bin/python from bcc import BPF from bcc.utils import printb prog

    = """ int hello(void *ctx) { bpf_trace_printk("Hello, World!\\n"); return 0; } """ b = BPF(text=prog) b.attach_kprobe(event=b.get_syscall_fnname("clone"), fn_name="hello") b.trace_print() BCCを使ったHello World https://zenn.dev/masibw/articles/068bdfe5edee17 hello_world.py kprobeを使って eBPFプログラムをカーネルに アタッチ
  29. • Observability ◦ bpftrace(IO Visor) ▪ eBPFを利用したトレーシングを簡単に行えるツール ◦ Pixie(New Relicが買収、CNCFに寄贈)

    ▪ Kubernetesネイティブなツール、ユーザー空間とカーネル空間の両 方のイベントデータを取得できる ◦ Hubble(Isovalent社) ▪ Kubernetes ServiceにおけるNetworkの依存関係やMetricsを可視 化できるツール eBPFが活用されている分野と事例 https://mmi.hatenablog.com/entry/2020/12/02/031534 https://newrelic.com/jp/blog/best-practices/what-is-ebpf https://cilium.io/blog/2019/11/19/announcing-hubble/
  30. • Network ◦ XDP(IO Visor) ▪ eXpress Data Path ▪

    NICドライバーにeBPFプログラムをアタッチすることで、パケット のフィルタリングやフォワーディングを実現する ▪ NetworkにおけるeBPF利用のベースとなっている ◦ Katran(Facebook社) ▪ eBPF/XDPを活用したL4ロードバランサー eBPFが活用されている分野と事例 https://www.iovisor.org/technology/xdp https://engineering.fb.com/2018/05/22/open-source/open-sourcing-katran-a-scalable-network-lo ad-balancer/
  31. eBPFが活用されている分野と事例 • Network ◦ Calico(Tigera社、Project Calico Community) ▪ iptablesベースのkube-proxyをeBPF/XDPによって置き換えるCNI ◦

    Cilium(Isovalent社) ▪ iptablesベースのkube-proxyをeBPF/XDPによって置き換えるCNI ▪ eBPFによるSidecar-free Service Meshが提供されている(Beta) ◦ CloudFlareのNetwork Security ▪ eBPFを活用したDDoS保護の機能 https://cfp.cloud-native.rejekts.io/media/Calico_eBFP_Dataplane_-_CN_Rejekts.pdf https://isovalent.com/blog/post/cilium-service-mesh/ https://blog.cloudflare.com/ja-jp/programmable-packet-filtering-with-magic-firewall-ja-jp/
  32. How eBPF will solve Service Mesh – Goodbye Sidecars https://isovalent.com/blog/post/2021-12-08-ebpf-servicemesh/

  33. 今日のタイトル eBPFで実現する コンテナランタイムセキュリティ ! ?

  34. • コンテナライフサイクルのフェーズに従って整理 ◦ 安全なイメージのビルド / レジストリの保護 / オーケストレーター の保護 /

    ホストのセキュリティ / コンテナランタイムセキュリティ https://dev.classmethod.jp/articles/developersio-2022-container-security-with-oss-tools/ コンテナセキュリティ概要
  35. • コンテナの実行時におけるセキュリティ • ランタイムにおける振る舞いを動的にスキャンし、異常 な振る舞いを検知する ◦ あらかじめ用意したルールに適合するかフィルタリングし、適合 すればアラートを出力する • 商用のセキュリティ製品では、異常な振る舞いの検知だ

    けでなく防止も実施できるものもある ◦ Sysdig Secure / Aqua Enterprise / Prisma Cloud など コンテナランタイムセキュリティ
  36. • なんらかの手段でコンテナの認証情報が奪取され、 docker/kubectl execコマンドなどで侵入される • コンテナ上でマイニングツールなど不正なファイルをダ ウンロードされ、実行されてしまう コンテナ実行時の脅威のシナリオ Attacker Container

    侵入 ダウンロード Malware
  37. • コンテナに対してランタイムセキュリティを導入するこ とで、異常な振る舞いを動的に検知できる ◦ 実行中のコンテナに対する不正な侵入 ◦ 不正なファイルのダウンロードや実行 ◦ など ランタイムセキュリティ導入のメリット

    Attacker Container 侵入 ダウンロード Malware ! !
  38. • OPA(Open Policy Agent) ◦ JSONデータを介してリクエストを評価するポリシーエンジン ◦ 汎用ポリシー言語であるRegoを用いてポリシーを記述する • ユーザープロセスによるシステムコールの実行イベント

    をeBPFによって取得する • OPAと組み合わせることで、取得したイベントデータが 事前に定義したポリシーに適合しているか評価する 参考: OPAとeBPFを組み合わせる https://blog.byte.builders/post/bpf-opa/
  39. 参考: OPAとeBPFを組み合わせる https://blog.byte.builders/post/bpf-opa/

  40. 今日のタイトル eBPFで実現する コンテナランタイムセキュリティ ! !

  41. 改めまして コンテナランタイムセキュリティを eBPFを使って実現する

  42. 3つのOSSツールを紹介

  43. • Falco(Sysdig社が開発、CNCFに寄贈) ◦ 2016年に発表され、コンテナランタイムセキュリティにおける デファクトスタンダードなツールと言える ▪ CKS(Kubernetesセキュリティ認定試験)にも組み込まれている ◦ C++で実装されている ◦

    当初はLinuxカーネルモジュールを利用してセキュリティイベン トを取得する方式だった ▪ 2019年頃にeBPFを利用した方式が追加 3つのOSSツールを紹介 https://sysdig.com/blog/sysdig-falco/ https://sysdig.com/blog/sysdig-and-falco-now-powered-by-ebpf/
  44. • Tracee(Aqua Security社) ◦ 2019年に発表された ▪ Trivyの買収もこの時期 ◦ Goで実装されている ▪

    GoでeBPFを扱うlibbpfgoというライブラリが公開されている • https://github.com/aquasecurity/libbpfgo ◦ eBPFベースでコンテナ環境におけるトレーシングを実現する ▪ 将来的に、検知だけでなくポリシーの強制(Enforce)の実装も検 討されている 3つのOSSツールを紹介 https://www.aquasec.com/products/tracee/ https://www.creationline.com/lab/30664 https://knqyf263.hatenablog.com/entry/2019/08/20/120713
  45. 3つのOSSツールを紹介 • Tetragon(Isovalent社) ◦ 2022年5月に発表された ▪ 以前からIsovalent Cilium Enterpriseのセキュリティ機能として提 供していたものがOSSとして公開された

    ◦ Goで実装されている ▪ GoでeBPFを扱うcilium/ebpfというライブラリが公開されている • https://github.com/cilium/ebpf ◦ 異常な振る舞いの検知だけでなく、防止の機能を持つ ▪ Real-Time Enforcement https://isovalent.com/blog/post/2022-05-16-tetragon/
  46. None
  47. Falcoのアーキテクチャ https://github.com/falcosecurity/libs

  48. • Kernel moduleモード(デフォルト) ◦ Linuxカーネルモジュールを利用してイベントを取得するモード • eBPF probeモード ◦ eBPFを利用してイベントを取得するモード

    ◦ Linuxカーネルバージョン4.14以上が必要 • Userspace instrumentationモード ◦ ユーザー空間からイベントを取得するモード ◦ ptraceによりイベントを取得するpdigライブラリをサポート ▪ ptraceは、他プロセスの制御を提供するシステムコール Falcoの実行モード https://falco.org/docs/event-sources/drivers/ https://falco.org/blog/choosing-a-driver/
  49. • カーネルにアクセス利用できないワークロードでFalcoを 実行する際に選択するモード ◦ e.g. AWS Fargate • ユーザー空間からイベントを取得する •

    ptraceを使うpdigライブラリをサポートしている ◦ ただし、pdigライブラリは正直、導入が厄介 ◦ もしAWS Fargateを利用している場合は、eBPFがサポートされ ることに期待 ▪ https://github.com/aws/containers-roadmap/issues/1027 補足: Userspace instrumentationモード
  50. • プリセットなルールが豊富に用意されているので、その まますぐに使い始められる ◦ プリセットなルール定義の一覧 ▪ https://github.com/falcosecurity/falco/blob/master/rules /falco_rules.yaml ◦ カスタムルールも定義できる

    • 独自の言語によってルールを定義する ◦ OPA/Regoと違い汎用ポリシー言語を提供しているわけではない Falcoのルール定義 https://falco.org/docs/event-sources/drivers/ https://falco.org/blog/choosing-a-driver/
  51. • Amazon Linux 2 on EC2でFalcoをインストールする • eBPF probeモード実行にはドライバーが必要 $

    sudo rpm --import https://falco.org/repo/falcosecurity-3672BA8F.asc $ sudo curl -s -o /etc/yum.repos.d/falcosecurity.repo https://falco.org/repo/falcosecurity-rpm.repo $ sudo yum -y install kernel-devel-$(uname -r) $ sudo yum -y install falco Linux環境での利用 https://falco.org/docs/getting-started/installation/ $ sudo falco-driver-loader bpf
  52. • eBPF probeモードでFalcoを実行する ◦ 環境変数 FALCO_BPF_PROBE を指定して実行する ▪ インストールしたeBPF probeドライバーのパス(デフォルトは

    ~/.falco/falco-bpf.o)を指定する ◦ 動作確認のための一時的な実行 $ export FALCO_BPF_PROBE=”” $ sudo -E falco Sun Aug 5 06:15:00 2022: Falco version 0.32.1 Sun Aug 5 06:15:00 2022: Falco initialized with configuration file /etc/falco/falco.yaml Sun Aug 5 06:15:00 2022: Loading rules from file /etc/falco/falco_rules.yaml: Sun Aug 5 06:15:00 2022: Loading rules from file /etc/falco/falco_rules.local.yaml: Sun Aug 5 06:15:00 2022: Starting internal webserver, listening on port 8765 Linux環境での利用 https://falco.org/docs/event-sources/drivers/
  53. • 別のターミナルから不正な操作を実行してみる ◦ /bin 以下にファイル作成の操作を実行 • 上記の不正なコマンドが実行されたイベントを検知し、 実行ログが出力される Linux環境での利用 $

    sudo touch /bin/surprise Sun Aug 5 06:15:00 2022: Starting internal webserver, listening on port 8765 06:15:10.282132116: Error File below a known binary directory opened for writing (user=root user_loginuid=-1 command=touch /bin/surprise file=/bin/surprise parent=sudo pcmdline=sudo touch /bin/surprise gparent=sh container_id=host image=<NA>)
  54. • Falcoの起動時に設定ファイルがロードされる ◦ デフォルトのパスは /etc/falco/falco.yaml • ルール設定ファイルが別にあり、Falcoの設定ファイルで はルール設定ファイルのリストを指定している • デフォルトでは下記のように指定されている

    Falcoルールの設定ファイル rules_file: - /etc/falco/falco_rules.yaml - /etc/falco/falco_rules.local.yaml - /etc/falco/rules.d https://falco.org/docs/configuration/ https://falco.org/docs/rules/ /etc/falco/falco.yaml
  55. • プリセットなルールによって不正な操作が検出された 不正な操作の検出を定義したルール - macro: bin_dir condition: fd.directory in (/bin,

    /sbin, /usr/bin, /usr/sbin) - rule: Write below binary dir desc: an attempt to write to any file below a set of binary directories condition: > bin_dir and evt.dir = < and open_write and not package_mgmt_procs and not exe_running_docker_save and not python_running_get_pip and not python_running_ms_oms and not user_known_write_below_binary_dir_activities output: > File below a known binary directory opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository) priority: ERROR tags: [filesystem, mitre_persistence] /etc/falco/falco_rules.yaml
  56. • プリセットなルールを上書きできる ◦ カスタムルールの設定ファイルに定義を記述する - rule: Write below binary dir

    desc: an attempt to write to any file below a set of binary directories condition: > bin_dir and evt.dir = < and open_write and not package_mgmt_procs and not exe_running_docker_save and not python_running_get_pip and not python_running_ms_oms and not user_known_write_below_binary_dir_activities output: > File below a known binary directory opened for writing (user=%user.name user_loginuid=%user.loginuid command=%proc.cmdline file=%fd.name parent=%proc.pname pcmdline=%proc.pcmdline gparent=%proc.aname[2] container_id=%container.id image=%container.image.repository) priority: NOTICE tags: [filesystem, mitre_persistence] カスタムルールの設定 /etc/falco/falco_rules.local.yaml
  57. • 別のターミナルから不正な操作を実行してみる ◦ 先ほどと同様にコマンドを実行する • 実行ログが ERROR から NOTICE に変わっている

    カスタムルールの動作確認 $ sudo touch /bin/surprise2 06:16:10.247858281: Notice File below a known binary directory opened for writing (user=root user_loginuid=-1 command=touch /bin/surprise2 file=/bin/surprise2 parent=sudo pcmdline=sudo touch /bin/surprise2 gparent=sh container_id=host image=<NA>)
  58. • ホストにドライバーをインストールする必要がある ◦ falcosecurity/falco-driver-loaderを使う コンテナとして実行する https://falco.org/docs/getting-started/running/ $ docker run --rm

    -it \ --privileged \ -v /root/.falco:/root/.falco \ -v /proc:/host/proc:ro \ -v /boot:/host/boot:ro \ -v /lib/modules:/host/lib/modules:ro \ -v /usr:/host/usr:ro \ -v /etc:/host/etc:ro \ falcosecurity/falco-driver-loader:latest bpf
  59. • DockerコンテナとしてFalcoを実行する ◦ falcosecurity/falco もしくは falco-no-driver を使う ◦ 動作確認のため -it

    オプションで一時的な実行 $ docker run --rm -it \ --cap-drop all \ --cap-add sys_admin \ --cap-add sys_resource \ --cap-add sys_ptrace \ -v /var/run/docker.sock:/host/var/run/docker.sock \ -e FALCO_BPF_PROBE="" \ -v /root/.falco:/root/.falco \ -v /etc:/host/etc \ -v /proc:/host/proc:ro \ falcosecurity/falco-no-driver:latest コンテナとして実行する https://falco.org/docs/getting-started/running/
  60. • 別のターミナルから不正な操作を実行してみる ◦ 先ほどと同様 • 不正な操作を検知し、実行ログが出力される • カスタムルールを適用したい場合は、カスタムルール設定ファイ ルを含めたFalcoコンテナをビルドして実行する 2022-08-05T06:18:00+0000:

    Starting internal webserver, listening on port 8765 2022-08-05T06:19:00.625154977+0000: Error File below a known binary directory opened for writing (user=root user_loginuid=-1 command=touch /bin/surprise file=/bin/surprise parent=sudo pcmdline=sudo touch /bin/surprise gparent=sh container_id=hostimage=<NA>) コンテナとして実行する $ sudo touch /bin/surprise
  61. • Helm Chartが用意されている ◦ values.yaml でドライバーとしてeBPFを指定する • マニフェストをapplyして実行することも可能 Kubernetesでの利用 https://falco.org/docs/getting-started/deployment/

    https://github.com/falcosecurity/charts/tree/master/falco https://github.com/falcosecurity/deploy-kubernetes/tree/main/kubernetes/falco/templates driver: enabled: true kind: ebpf values.yaml $ helm repo add falcosecurity https://falcosecurity.github.io/charts $ helm repo update $ helm install falco falcosecurity/falco --namespace falco --create-namespace
  62. • 複数のFalcoプロセスからイベントデータを集約し、様々 な出力先に対してアラートを通知できるコンポーネント ◦ Datadog / Elasticsearch / Loki /

    Prometheus / etc. • Web UIが用意されており、SIEMのような使い方もできる Falcosidekick https://github.com/falcosecurity/falcosidekick https://falco.org/blog/extend-falco-outputs-with-falcosidekick/
  63. • eBPF probeだけでなく、Kernel moduleモードやユー ザー空間からイベントを取得するモードがある ◦ 様々なワークロードに対してコンテナランタイムセキュリティを 導入可能 ◦ ただし、ドライバーやライブラリなどの利用が必要になるので、

    カーネルバージョンに注意 • プリセットなルールが用意されているため導入が容易 ◦ カスタムルールも定義して適用できる • Falcosidekickを利用することでイベントデータを集約で きる Falcoに関するまとめ
  64. None
  65. Traceeのアーキテクチャ https://aquasecurity.github.io/tracee/v0.8.0/architecture/

  66. • 2つのコンポーネントで構成される ◦ tracee-ebpf ▪ eBPFで取得したイベントデータの変換・加工やキャプチャを行う ▪ イベントデータをtracee-rulesに送信する ◦ tracee-rules

    ▪ tracee-ebpfから受け取ったイベントデータを事前に定義された ルールに従って評価し、不正なイベントを検知する ▪ 検知したイベントを出力し、他のツールに送信することも可能 Traceeのアーキテクチャ https://aquasecurity.github.io/tracee/v0.8.0/architecture/
  67. tracee-ebpf https://aquasecurity.github.io/tracee/v0.8.0/tracing/ https://aquasecurity.github.io/tracee/v0.8.0/capturing/ • tracee-ebpfを単体で実行することで、eBPFで取得した イベントデータの収集・トレーシングが可能 ◦ トラブルシューティングやセキュリティ調査に利用できる • 加えて、様々なアーティファクトをキャプチャできる

    ◦ 書き込みされたファイル ◦ 実行されたファイル ◦ 保護が 書き込み+実行 から 実行のみ に変更されたメモリ領域 ◦ ネットワークパケット ◦ ロードされたカーネルモジュール
  68. tracee-rules https://aquasecurity.github.io/tracee/v0.8.0/detecting/ https://aquasecurity.github.io/tracee/v0.8.0/detecting/rules/ https://aquasecurity.github.io/tracee/v0.8.0/integrating/webhook/ • プリセットなルールが用意されている ◦ 現在は14件あり、実行時に適用するルールの選択が可能 • カスタムルールの定義でサポートしている記述形式

    ◦ Go / Rego / cel-go(プレビュー) ▪ cel-goは、Googleが提供しているCELライブラリ • Common Expression Language • 式の評価を高速かつ安全に実行するための言語 • 検知したイベントを様々な送信先に出力できる ◦ Webhook / Postee / Falcosidekick
  69. • Traceeをインストールする Linux環境での利用 https://aquasecurity.github.io/tracee/v0.8.0/installing/getting/ $ curl -L -O https://github.com/aquasecurity/tracee/releases/download/v0.8.0/tracee.v0.8.0.tar.gz $

    tar -xvf tracee.v0.8.0.tar.gz $ tree ./dist ./dist ├── rules │ ├── ... ├── tracee-ebpf ├── tracee-rules └── tracee.bpf.core.o
  70. • tracee-ebpfを実行する ◦ lsコマンドの実行を出力する • 別のターミナルからlsコマンドを実行してみる ◦ コマンドの実行から終了までの間のイベントが全て出力される Linux環境での利用 https://aquasecurity.github.io/tracee/v0.8.0/detecting/

    $ sudo ./dist/tracee-ebpf --trace comm=ls --output json {"timestamp":1659444925827665303,"threadStartTime":2512799922241,"processorId":0,"processId":4300,"cgroupId":1,"threadId":4300,"parentProcessId":3820,"hostProcessId":4300,"hostThreadId":4 300,"hostParentProcessId":3820,"userId":1000,"mountNamespace":4026531840,"pidNamespace":4026531836,"processName":"ls","hostName":"ip-10-1-0-33.ap","containerId":"","containerImage":""," containerName":"","podName":"","podNamespace":"","podUID":"","eventId":"707","eventName":"sched_process_exec","argsNum":10,"returnValue":0,"stackAddresses":null,"args":[{"name":"cmdpath ","type":"const char*","value":"/bin/ls"},{"name":"pathname","type":"const char*","value":"/usr/bin/ls"},{"name":"argv","type":"const char**","value":["ls","--color=auto"]},{"name":"dev","type":"dev_t","value":211812353},{"name":"inode","type":"unsigned long","value":8467457},{"name":"invoked_from_kernel","type":"int","value":0},{"name":"ctime","type":"unsigned long","value":1658432741010152344},{"name":"stdin_type","type":"umode_t","value":8192},{"name":"inode_mode","type":"umode_t","value":33261},{"name":"interp","type":"const char*","value":"/bin/ls"}]} {"timestamp":1659444925828479003,"threadStartTime":2512799922241,"processorId":0,"processId":4300,"cgroupId":1,"threadId":4300,"parentProcessId":3820,"hostProcessId":4300,"hostThreadId":4 300,"hostParentProcessId":3820,"userId":1000,"mountNamespace":4026531840,"pidNamespace":4026531836,"processName":"ls","hostName":"ip-10-1-0-33.ap","containerId":"","containerImage":""," containerName":"","podName":"","podNamespace":"","podUID":"","eventId":"21","eventName":"access","argsNum":2,"returnValue":-2,"stackAddresses":null,"args":[{"name":"pathname","type":"const char*","value":"/etc/ld.so.preload"},{"name":"mode","type":"int","value":4}]} (以下略)
  71. {"timestamp":1659448860658487909,"threadStartTime":1056204106432,"processorId":0,"processId":3820,"cgroupId":1,"threadId":3820,"parentProcessId":3819,"hostProcessId":3820,"hostThreadId":3 820,"hostParentProcessId":3819,"userId":1000,"mountNamespace":4026531840,"pidNamespace":4026531836,"processName":"bash","hostName":"ip-10-1-0-33.ap","containerId":"","containerImage": "","containerName":"","podName":"","podNamespace":"","podUID":"","eventId":"724","eventName":"security_socket_create","argsNum":4,"returnValue":0,"stackAddresses":null,"args":[{"name":"fam ily","type":"int","value":16},{"name":"type","type":"int","value":3},{"name":"protocol","type":"int","value":9},{"name":"kern","type":"int","value":0}]} {"timestamp":1659448860658483828,"threadStartTime":1056204106432,"processorId":0,"processId":3820,"cgroupId":1,"threadId":3820,"parentProcessId":3819,"hostProcessId":3820,"hostThreadId":3 820,"hostParentProcessId":3819,"userId":1000,"mountNamespace":4026531840,"pidNamespace":4026531836,"processName":"bash","hostName":"ip-10-1-0-33.ap","containerId":"","containerImage": "","containerName":"","podName":"","podNamespace":"","podUID":"","eventId":"41","eventName":"socket","argsNum":3,"returnValue":3,"stackAddresses":null,"args":[{"name":"domain","type":"int", "value":16},{"name":"type","type":"int","value":3},{"name":"protocol","type":"int","value":9}]} {"timestamp":1659448860658608569,"threadStartTime":1056204106432,"processorId":0,"processId":3820,"cgroupId":1,"threadId":3820,"parentProcessId":3819,"hostProcessId":3820,"hostThreadId":3 820,"hostParentProcessId":3819,"userId":1000,"mountNamespace":4026531840,"pidNamespace":4026531836,"processName":"bash","hostName":"ip-10-1-0-33.ap","containerId":"","containerImage":

    "","containerName":"","podName":"","podNamespace":"","podUID":"","eventId":"711","eventName":"cap_capable","argsNum":1,"returnValue":0,"stackAddresses":null,"args":[{"name":"cap","type":"i nt","value":29}]} (以下略) • tracee-ebpfを実行する ◦ bashが生成するプロセスによるイベントを全て出力する • 別のターミナルからコマンドを実行してみる ◦ コマンドの実行から終了までの間のイベントが全て出力される Linux環境での利用 https://github.com/aquasecurity/tracee/blob/main/cmd/tracee-ebpf/flags/filter.go $ sudo ./dist/tracee-ebpf --trace comm=bash --trace follow --output json
  72. • tracee-rulesでプリセットなルールを確認する ◦ 検知するイベントのリストを確認する ◦ ルールIDを指定して確認する $ ./dist/tracee-rules --rules TRC-2

    --list-events ptrace Linux環境での利用 https://aquasecurity.github.io/tracee/v0.8.0/detecting/ https://github.com/aquasecurity/tracee/tree/main/signatures $ ./dist/tracee-rules --list-events execve,hooked_syscalls,init_module,magic_write,mem_prot_alert,process_vm_writev,ptrace,sched_proce ss_exec,security_bprm_check,security_file_open,security_kernel_read_file,security_sb_mount
  73. $ sudo ./dist/tracee-ebpf --output json --trace comm=bash --trace follow \

    --output option:detect-syscall --output option:parse-arguments --output option:exec-env \ --trace event=$(./dist/tracee-rules --rules TRC-2 --list-events) \ | ./dist/tracee-rules --input-tracee format:json --input-tracee file:stdin --rules TRC-2 • tracee-ebpfとtracee-rulesでイベントを検知する ◦ tracee-rulesのインプットとしてtracee-ebpfの出力を利用する ◦ tracee-ebpfでは --trace event オプションでトレーシングした いイベントを指定できる ▪ TRC-2ルールの対象となるイベントを展開して指定している ◦ パイプで繋いでtracee-rulesで入力として標準入力を指定する Linux環境での利用 https://aquasecurity.github.io/tracee/v0.8.0/detecting/
  74. • 別のターミナルからstraceコマンドを実行してみる ◦ straceでは内部でptrace(2)システムコールを呼び出す • ptraceイベントの実行が検知され、出力される $ strace ls Linux環境での利用

    https://aquasecurity.github.io/tracee/v0.8.0/detecting/ *** Detection *** Time: 2022-08-05T06:20:00Z Signature ID: TRC-2 Signature: Anti-Debugging Data: map[] Command: strace Hostname: ip-10-0-0-1.ap
  75. • DockerコンテナとしてTraceeを実行する ◦ 動作確認のため -it オプションで一時的な実行 コンテナとして実行する https://aquasecurity.github.io/tracee/v0.8.0/ $ docker

    run \ --name tracee --rm -it \ --pid=host --cgroupns=host --privileged \ -v /etc/os-release:/etc/os-release-host:ro \ -e LIBBPFGO_OSRELEASE_FILE=/etc/os-release-host \ aquasec/tracee:0.8.0
  76. • 別のターミナルで侵入用のコンテナを実行する ◦ docker execコマンドでコンテナに侵入し、実行可能ファイルを ダウンロードしてみる $ docker run -d

    --name test-nginx nginx:latest $ docker exec -it test-nginx bash root@b36762680a1a:/# apt-get update root@b36762680a1a:/# apt-get install -y wget コンテナとして実行する
  77. • Traceeコンテナの出力を確認すると、実行可能ファイル のダウンロードが検知されている *** Detection *** Time: 2022-08-05T06:21:00Z Signature ID:

    TRC-9 Signature: New Executable Was Dropped During Runtime Data: map[file path:/usr/bin/wget.dpkg-new] Command: dpkg Hostname: b36762680a1a コンテナとして実行する https://github.com/aquasecurity/tracee/tree/main/signatures https://github.com/aquasecurity/tracee/blob/main/signatures/rego/dropped_executable.rego
  78. • Helm Chartが用意されている • マニフェストをapplyして実行することも可能 Kubernetesでの利用 https://aquasecurity.github.io/tracee/v0.8.0/installing/kubernetes/ https://github.com/aquasecurity/tracee/tree/main/deploy/kubernetes $ git

    clone --depth 1 --branch v0.8.0 https://github.com/aquasecurity/tracee.git $ cd tracee $ helm repo add aqua-charts https://aquasecurity.github.io/helm-charts $ helm dependency update ./deploy/helm/tracee $ helm install tracee ./deploy/helm/tracee \ --namespace tracee-system --create-namespace \ --set hostPID=true \ --set postee.enabled=true
  79. • tracee-ebpfとtracee-rulesの2つのコンポーネントが組 み合わさって実行されている ◦ どちらも拡張性が高く、様々なユースケースに対応できそう ◦ 特に、tracee-ebpfはトレーシングツールとして役立つ • ドライバーやライブラリのインストールが不要なので、 コンテナでの実行が容易

    • 少量ではあるが、プリセットなルールが用意されている ◦ GoやRegoといった汎用言語でカスタムルールを定義できるの で、ワークロードに合わせた運用がしやすい印象 Traceeに関するまとめ
  80. None
  81. Tetragonの概要図 https://isovalent.com/blog/post/2022-05-16-tetragon/

  82. Real-Time Security Enforcer https://isovalent.com/blog/post/2022-05-16-tetragon/

  83. • セキュリティイベントの検知だけでなく防止が可能 ◦ 検知した後、SIGKILLを送信して不正なプロセスをkillする ◦ Kubernetesクラスターにおける状態を、事前に定義したポリ シーに沿うように強制できる • ポリシーの定義でサポートされている形式 ◦

    Kubernetes CRD / JSON API / OPA ◦ Kubernetes CRDのexamplesがいくつか用意されており、プリ セットなポリシーとして利用可能 ▪ https://github.com/cilium/tetragon/tree/main/crds Real-Time Security Enforcer https://www.youtube.com/watch?v=Xs3MBK17kCk
  84. • Helm Chartが用意されている • TetragonがDaemonSetとして実行される • Podのログを標準出力で表示して動作確認 $ kubectl logs

    -n kube-system -l app.kubernetes.io/name=tetragon -c export-stdout -f Kubernetesでの利用 https://github.com/cilium/tetragon $ helm repo add cilium https://helm.cilium.io $ helm repo update $ helm install tetragon cilium/tetragon -n kube-system
  85. • 別のターミナルで侵入用のコンテナを実行する • コンテナ実行時のイベントが全て出力される $ kubectl run test-nginx --image=nginx:latest {"process_exec":{"process":{"exec_id":"aXAtMTAtMS0yLTIxMi5hcC1ub3J0aGVhc3QtMS5jb21wdXRlLmludGVybmFsOjE5Njg5NjAzNDc4MjQzMzo4MTY3","pid":81

    67,"uid":0,"cwd":"/","binary":"/docker-entrypoint.sh","arguments":"/docker-entrypoint.sh nginx -g \"daemon off;\"","flags":"execve rootcwd clone","start_time":"2022-08-05T06:25:00.000Z","auid":4294967295,"pod":{"namespace":"default","name":"test-nginx","container":{"id":"docker://fbcabe2df8 9b252048ca1aede821af8bca87752c81be8ee0081518f2ea4fc49a","name":"test-nginx","image":{"id":"docker-pullable://nginx@sha256:691eecfa41f219b32acea5 a3561a8d8691d8320e5a00e1cb4574de5827e077a7","name":"nginx:latest"},"start_time":"2022-08-05T06:25:00Z","pid":1}},"docker":"fbcabe2df89b252048ca1a ede821af8","parent_exec_id":"aXAtMTAtMS0yLTIxMi5hcC1ub3J0aGVhc3QtMS5jb21wdXRlLmludGVybmFsOjE5Njg5NTk2MzczOTA0Mjo4MTMz","refcnt":429496 7290},"parent":{"exec_id":"aXAtMTAtMS0yLTIxMi5hcC1ub3J0aGVhc3QtMS5jb21wdXRlLmludGVybmFsOjE5Njg5NTk2MzczOTA0Mjo4MTMz","pid":8133,"uid":0," cwd":"/run/containerd/io.containerd.runtime.v2.task/moby/fbcabe2df89b252048ca1aede821af8bca87752c81be8ee0081518f2ea4fc49a/","binary":"/usr/bin/co ntainerd-shim-runc-v2","arguments":"-namespace moby -id fbcabe2df89b252048ca1aede821af8bca87752c81be8ee0081518f2ea4fc49a -address /run/containerd/containerd.sock","flags":"execve clone","start_time":"2022-08-05T06:25:00.000Z","auid":4294967295,"parent_exec_id":"aXAtMTAtMS0yLTIxMi5hcC1ub3J0aGVhc3QtMS5jb21wdXRlLmludGVyb mFsOjE5Njg5NTk1OTkwNTYyNTo4MTI3"}},"node_name":"ip-10-0-0-1.ap-northeast-1.compute.internal","time":"2022-08-05T06:25:00.000Z"} (以下略) Kubernetesでの利用 https://github.com/cilium/tetragon
  86. • Tetragon CLIを利用することで出力を確認しやすくする $ GOOS=$(go env GOOS) $ GOARCH=$(go env

    GOARCH) $ curl -L --remote-name-all \ https://github.com/cilium/tetragon/releases/download/tetragon-cli/tetragon-${GOOS}-${GOARCH}. tar.gz{,.sha256sum} $ sha256sum --check tetragon-${GOOS}-${GOARCH}.tar.gz.sha256sum $ sudo tar -C /usr/local/bin -xzvf tetragon-${GOOS}-${GOARCH}.tar.gz $ rm tetragon-${GOOS}-${GOARCH}.tar.gz{,.sha256sum} Kubernetesでの利用 https://github.com/cilium/tetragon
  87. • Tetragon CLIを利用することで出力を確認しやすくする $ kubectl logs -n kube-system -l app.kubernetes.io/name=tetragon

    -c export-stdout -f \ | tetragon observe process default/test-nginx /proc/self/fd/6 init process default/test-nginx /docker-entrypoint.sh /docker-entrypoint.sh nginx -g "daemon off;" process default/test-nginx /usr/bin/find /docker-entrypoint.d/ -mindepth 1 -maxdepth 1 -type f -print -quit process default/test-nginx /usr/bin/sort -V process default/test-nginx /usr/bin/find /docker-entrypoint.d/ -follow -type f -print (中略) process default/test-nginx /usr/bin/basename /docker-entrypoint.d/30-tune-worker-processes.sh process default/test-nginx /usr/sbin/nginx -g "daemon off;" Kubernetesでの利用 https://github.com/cilium/tetragon
  88. • kubectl execコマンドでコンテナに侵入し、実行可能 ファイルをダウンロードしてみる $ kubectl exec test-nginx -it bash

    root@test-nginx:/# apt-get update root@test-nginx:/# apt-get install -y wget Kubernetesでの利用
  89. • Tetragon CLIの出力を確認すると、実行可能ファイルの ダウンロードが検知されている ◦ コマンドの実行から終了までの間のイベントが全て出力される process default/test-nginx /bin/bash process

    default/test-nginx /usr/bin/apt-get update (中略) exit default/test-nginx /usr/bin/apt-get update 0 process default/test-nginx /usr/bin/apt-get install -y wget (中略) exit default/test-nginx /usr/bin/apt-get install -y wget 0 Kubernetesでの利用
  90. • Real-Time Security Enforcementの動作確認 ◦ crds/examples/sys_write_follow_fd_prefix.yamlを変更する ▪ https://github.com/cilium/tetragon/blob/main/crds/examp les/sys_write_follow_fd_prefix.yaml $

    curl -O \ https://raw.githubusercontent.com/cilium/tetragon/main/crds/examples/sys_write_follow_fd_prefi x.yaml $ cp sys_write_follow_fd_prefix.yaml sys_write_follow_fd_prefix_kill.yaml Kubernetesでの利用
  91. apiVersion: cilium.io/v1alpha1 kind: TracingPolicy metadata: name: "sys-read-follow-prefix" spec: kprobes: -

    call: "fd_install" syscall: false return: false args: - index: 0 type: int - index: 1 type: "file" selectors: - matchPIDs: - operator: NotIn followForks: true isNamespacePID: true values: - 1 Kubernetesでの利用 sys_write_follow_fd_prefix.yaml
  92. Kubernetesでの利用 matchArgs: - index: 1 operator: "Prefix" values: - "/etc/"

    matchActions: - action: FollowFD argFd: 0 argName: 1 (中略) - call: "__x64_sys_write" syscall: true args: - index: 0 type: "fd" - index: 1 type: "char_buf" sizeArgIndex: 3 - index: 2 type: "size_t" sys_write_follow_fd_prefix.yaml
  93. • Real-Time Security Enforcementの動作確認 ◦ selectors.matchActions.action: Sigkill を追加 (略) -

    call: "__x64_sys_write" syscall: true args: - index: 0 type: "fd" - index: 1 type: "char_buf" sizeArgIndex: 3 - index: 2 type: "size_t" selectors: - matchActions: - action: Sigkill Kubernetesでの利用 sys_write_follow_fd_prefix_kill.yaml
  94. • 修正したマニフェストをapplyしてポリシーを適用する • kubectl execコマンドでコンテナに侵入し、 /etc/passwdを変更してみると、強制終了される $ kubectl apply -f

    sys_write_follow_fd_prefix_kill.yaml Kubernetesでの利用 $ kubectl exec test-nginx -it bash root@test-nginx:/# apt-get install -y vim root@test-nginx:/# vi /etc/passwd Killed root@test-nginx:/#
  95. • Tetragon CLIの出力を確認すると、SIGKILLが送信され てプロセスがkillされている Kubernetesでの利用 process default/test-nginx /usr/bin/vi /etc/passwd open

    default/test-nginx /usr/bin/vi /etc/ld.so.cache close default/test-nginx /usr/bin/vi open default/test-nginx /usr/bin/vi /etc/vim/vimrc (中略) open default/test-nginx /usr/bin/vi /etc/.passwd.swp read default/test-nginx /usr/bin/vi /etc/.passwd.swp 1024 bytes close default/test-nginx /usr/bin/vi open default/test-nginx /usr/bin/vi /etc/.passwd.swm write default/test-nginx /usr/bin/vi /etc/.passwd.swm 4096 bytes exit default/test-nginx /usr/bin/vi /etc/passwd SIGKILL
  96. • セキュリティイベントの検知だけでなく防止が可能 ◦ SIGKILLを送信して不正なプロセスをkillすることで、ポリシーの 適用を強制する仕組み • Kubernetes CRDのみではあるものの、ポリシーの examplesが用意されている ◦

    プリセットなポリシーとして、そのまま適用可能 • 現在、Kubernetes以外の環境での実行はサポートされて いない? ◦ 全体的にドキュメントが未整備 ◦ 発表からまだ日が浅いので、今後のサポートに期待 Tetragonに関するまとめ
  97. 本セッションのまとめ

  98. • eBPFはLinuxカーネルから提供される機能 ◦ システムコールなど様々なイベントをトリガーに処理を実装可能 • eBPFを利用することでコンテナにおける動的な振る舞い をスキャンできる • eBPFを利用したコンテナランタイムセキュリティを実現 するOSSツールを紹介

    ◦ Falco / Tracee / Tetragon ◦ 各ツール検証の上、目的に合わせて利用をご検討ください 本セッションのまとめ
  99. • eBPFについて ◦ Liz Rice “What is eBPF” (O'Reilly Media)

    ▪ https://www.oreilly.com/library/view/what-is-ebpf/97814920972 66/ ◦ Jed Salazar, Natalia Reka Ivanko “Security Observability with eBPF” (O'Reilly Media) ▪ https://www.oreilly.com/library/view/security-observability-with /9781492096719/ ◦ David Calavera, Lorenzo Fontana “Linux Observability with BPF” (O'Reilly Media) ▪ https://www.oreilly.com/library/view/linux-observability-with/97 81492050193/ 参考資料
  100. • eBPFについて(日本語の動画資料) ◦ 「おいしくてつよくなる」eBPFのはじめかた ▪ https://www.youtube.com/watch?v=SvjdyLT9SH0 ◦ KubeCon + CloudNativeCon

    EU 2022 Recap ▪ https://youtu.be/9eps0YXFNAE?t=2397 ◦ CiliumによるKubernetes Network Policyの実現 ▪ https://event.cloudnativedays.jp/cndt2021/talks/1243 ◦ eBPFってなんだ? ▪ https://www.youtube.com/watch?v=CiurR2HAao0 参考資料
  101. • Linuxについて ◦ 武内覚 『[試して理解]Linuxのしくみ~実験と図解で学ぶOSと ハードウェアの基礎知識』 (技術評論社) ▪ https://gihyo.jp/book/2018/978-4-7741-9607-7 ◦

    Brian Ward, 柴田芳樹訳『スーパーユーザーなら知っておくべき linuxシステムの仕組み』 (インプレス) ▪ https://book.impress.co.jp/books/1121101019 ◦ Michael Hausenblas “Learning Modern Linux” (O'Reilly Media) ▪ https://www.oreilly.com/library/view/learning-modern-linux/9781 098108939/ 参考資料
  102. • コンテナセキュリティについて ◦ Liz Rice “Container Security” (O'Reilly Media) ▪

    https://www.oreilly.com/library/view/container-security/978149 2056690/ ◦ Loris Degioanni, Leonardo Grasso “Practical Cloud Native Security with Falco” (O'Reilly Media) ▪ htps://www.oreilly.com/library/view/practical-cloud-native/9781 098118563/ 参考資料
  103. Thank you!