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

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

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を紹介します。

TERAOKA Keisuke

August 05, 2022
Tweet

More Decks by TERAOKA Keisuke

Other Decks in Technology

Transcript

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

    Devチーム • 2022 APN ALL AWS Certifications Engineer & 2021 APN AWS Top Engineer • 趣味 ◦ 紅茶、ビール 発表者紹介 @toda_kk
  2. 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
  3. • 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
  4. • ユーザープロセスとカーネルは分離されている ◦ ユーザープロセスがカーネル上の動作や振る舞いを検知するため には、なんらかの仕組みが必要 • カーネルモジュールという、カーネルを拡張できる機能 をLinuxカーネルが提供している ◦ 自由度が高い反面、安全性が保証できない

    • eBPFでは、Linuxカーネルそのものは書き換えず、イベ ントをフックしてカーネル内のVMで処理を実行する ◦ 使えるLinuxの機能や文法に制限はあるものの、プログラムの安 全性を検証する仕組みを持つ LinuxカーネルモジュールとeBPF
  5. • 通常はC言語で処理を実装し、LLVM Clangでバイトコー ドにコンパイルする • 簡単にeBPFプログラムを実装できるように、IO Visorか らBCCというライブラリが用意されている ◦ BPF

    Compiler Collection ◦ PythonやLuaをフロントエンドとして用いてeBPFプログラミン グできるようにするもの ◦ IO Visorではないが、他にもGoやRustで実装可能にするライブ ラリが公開され、他言語による実装のための環境が整いつつある BCCを使ったeBPFプログラミング https://github.com/iovisor/bcc
  6. #!/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
  7. #!/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プログラム本体
  8. #!/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プログラムの読み込み
  9. #!/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)システムコール実行を トリガーとして指定
  10. #!/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 実行する関数名を指定
  11. #!/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プログラムをカーネルに アタッチ
  12. • 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/
  13. • 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/
  14. 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/
  15. • コンテナライフサイクルのフェーズに従って整理 ◦ 安全なイメージのビルド / レジストリの保護 / オーケストレーター の保護 /

    ホストのセキュリティ / コンテナランタイムセキュリティ https://dev.classmethod.jp/articles/developersio-2022-container-security-with-oss-tools/ コンテナセキュリティ概要
  16. • OPA(Open Policy Agent) ◦ JSONデータを介してリクエストを評価するポリシーエンジン ◦ 汎用ポリシー言語であるRegoを用いてポリシーを記述する • ユーザープロセスによるシステムコールの実行イベント

    をeBPFによって取得する • OPAと組み合わせることで、取得したイベントデータが 事前に定義したポリシーに適合しているか評価する 参考: OPAとeBPFを組み合わせる https://blog.byte.builders/post/bpf-opa/
  17. • 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/
  18. • 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
  19. 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/
  20. • 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/
  21. • カーネルにアクセス利用できないワークロードでFalcoを 実行する際に選択するモード ◦ e.g. AWS Fargate • ユーザー空間からイベントを取得する •

    ptraceを使うpdigライブラリをサポートしている ◦ ただし、pdigライブラリは正直、導入が厄介 ◦ もしAWS Fargateを利用している場合は、eBPFがサポートされ ることに期待 ▪ https://github.com/aws/containers-roadmap/issues/1027 補足: Userspace instrumentationモード
  22. • プリセットなルールが豊富に用意されているので、その まますぐに使い始められる ◦ プリセットなルール定義の一覧 ▪ 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/
  23. • 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
  24. • 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/
  25. • 別のターミナルから不正な操作を実行してみる ◦ /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>)
  26. • 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
  27. • プリセットなルールによって不正な操作が検出された 不正な操作の検出を定義したルール - 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
  28. • プリセットなルールを上書きできる ◦ カスタムルールの設定ファイルに定義を記述する - 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
  29. • 別のターミナルから不正な操作を実行してみる ◦ 先ほどと同様にコマンドを実行する • 実行ログが 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>)
  30. • ホストにドライバーをインストールする必要がある ◦ 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
  31. • 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/
  32. • 別のターミナルから不正な操作を実行してみる ◦ 先ほどと同様 • 不正な操作を検知し、実行ログが出力される • カスタムルールを適用したい場合は、カスタムルール設定ファイ ルを含めた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
  33. • 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
  34. • 複数のFalcoプロセスからイベントデータを集約し、様々 な出力先に対してアラートを通知できるコンポーネント ◦ Datadog / Elasticsearch / Loki /

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

    カーネルバージョンに注意 • プリセットなルールが用意されているため導入が容易 ◦ カスタムルールも定義して適用できる • Falcosidekickを利用することでイベントデータを集約で きる Falcoに関するまとめ
  36. • 2つのコンポーネントで構成される ◦ tracee-ebpf ▪ eBPFで取得したイベントデータの変換・加工やキャプチャを行う ▪ イベントデータをtracee-rulesに送信する ◦ tracee-rules

    ▪ tracee-ebpfから受け取ったイベントデータを事前に定義された ルールに従って評価し、不正なイベントを検知する ▪ 検知したイベントを出力し、他のツールに送信することも可能 Traceeのアーキテクチャ https://aquasecurity.github.io/tracee/v0.8.0/architecture/
  37. 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
  38. • 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
  39. • 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}]} (以下略)
  40. {"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
  41. • 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
  42. $ 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/
  43. • 別のターミナルから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
  44. • 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
  45. • 別のターミナルで侵入用のコンテナを実行する ◦ 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 コンテナとして実行する
  46. • 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
  47. • 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
  48. • tracee-ebpfとtracee-rulesの2つのコンポーネントが組 み合わさって実行されている ◦ どちらも拡張性が高く、様々なユースケースに対応できそう ◦ 特に、tracee-ebpfはトレーシングツールとして役立つ • ドライバーやライブラリのインストールが不要なので、 コンテナでの実行が容易

    • 少量ではあるが、プリセットなルールが用意されている ◦ GoやRegoといった汎用言語でカスタムルールを定義できるの で、ワークロードに合わせた運用がしやすい印象 Traceeに関するまとめ
  49. • セキュリティイベントの検知だけでなく防止が可能 ◦ 検知した後、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
  50. • 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
  51. • 別のターミナルで侵入用のコンテナを実行する • コンテナ実行時のイベントが全て出力される $ 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
  52. • 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
  53. • 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
  54. • kubectl execコマンドでコンテナに侵入し、実行可能 ファイルをダウンロードしてみる $ kubectl exec test-nginx -it bash

    root@test-nginx:/# apt-get update root@test-nginx:/# apt-get install -y wget Kubernetesでの利用
  55. • 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での利用
  56. • 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での利用
  57. 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
  58. 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
  59. • 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
  60. • 修正したマニフェストを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:/#
  61. • 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
  62. • セキュリティイベントの検知だけでなく防止が可能 ◦ SIGKILLを送信して不正なプロセスをkillすることで、ポリシーの 適用を強制する仕組み • Kubernetes CRDのみではあるものの、ポリシーの examplesが用意されている ◦

    プリセットなポリシーとして、そのまま適用可能 • 現在、Kubernetes以外の環境での実行はサポートされて いない? ◦ 全体的にドキュメントが未整備 ◦ 発表からまだ日が浅いので、今後のサポートに期待 Tetragonに関するまとめ
  63. • 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/ 参考資料
  64. • 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 参考資料
  65. • 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/ 参考資料
  66. • コンテナセキュリティについて ◦ 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/ 参考資料