Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
コードで理解する eBPF セキュリティモニタリング
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
mrtc0
February 17, 2024
Technology
330
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
コードで理解する eBPF セキュリティモニタリング
*
https://engineercafe.connpass.com/event/309223/
*
https://github.com/mrtc0/ebpf-demo/
mrtc0
February 17, 2024
More Decks by mrtc0
See All by mrtc0
Datadog を使ったプロダクトとクラウドの セキュリティモニタリング
mrtc0
0
3.5k
Product Security Casual Talk #1 - Datadog を使ったセキュリティモニタリングと 自動化の取り組み
mrtc0
2
730
GMO ペパボ株式会社 23卒・24卒向け セキュリティ勉強会 実践 DevSecOps パイプライン
mrtc0
1
780
実践 DevSecOps パイプライン ~システム開発へのセキュリティの取り入れ方~
mrtc0
2
630
脅威モデリングで考える Kubernetes セキュリティ / CloudNative Days Tokyo 2021 #CNDT2021 #CNDT2021_B
mrtc0
8
3.6k
ProSec-IT 2021 Container Security
mrtc0
2
840
GMO Developer Day 2021 - DevSecOps 推進の取り組みの紹介.pdf
mrtc0
4
1.9k
Web セキュリティ研修 / GMO ペパボ 新卒研修 2021
mrtc0
7
47k
実践コンテナ & Kubernetes セキュリティ
mrtc0
12
4.2k
Other Decks in Technology
See All in Technology
#jawssonic2026 あの時代が悪かった ~動かなかったSageMakerと共に迎えたイベント当日~
ktkn1129
0
150
Podは生きているのにGoだけが落ちる:GOGCとGOMEMLIMITで追うInvisible OOM Killの謎
tkc66buzz
1
600
Reactの設計論
uhyo
15
8.4k
From Vanilla Kubernetes to a Batteries-Included Platform: Developer Experience at 1,300+ Clusters
yosshi_
0
690
NW運用でNWトポロジ可視化ツールに期待すること/shumoku-meetup1
corestate55
2
120
AI時代に顧客へ最速で価値を 届けるための試行錯誤 〜「AI × マネジメント」領域におけるmentoのケース〜
posterkeisuke
0
110
幾何アルゴリズムで なめらかなピン操作を / iOSDC Japan 2026 / smoothpin
kazumanagano
0
270
TinyGo 開発サイクルを高速化する:Go で作るエミュレータ入門
zozotech
PRO
1
650
Snowflakeで実現する全社横断の顧客の声(VOC)分析・活用基盤@Snowflake World Tour Tokyo 2026
yuto16
0
190
enechainの内製セルフサービスプラットフォーム
hiyosi
0
160
2026-09-10 【Snowflake World Tour Tokyo 2026】dbt Core と Snowflake で実現する多層的なデータガバナンス / Multi-Layered Data Governance Powered by dbt Core and Snowflake
civitaspo
0
350
作品が生態系になった ─ Mini Tokyo 3D から世界へ
nagix
0
160
Featured
See All Featured
The Spectacular Lies of Maps
axbom
PRO
1
990
The Art of Programming - Codeland 2020
erikaheidi
57
14k
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
830
Darren the Foodie - Storyboard
khoart
PRO
3
3.9k
How to build a perfect <img>
jonoalderson
1
6k
Evolving SEO for Evolving Search Engines
ryanjones
0
280
jQuery: Nuts, Bolts and Bling
dougneiner
66
8.6k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1k
Typedesign – Prime Four
hannesfritz
42
3.2k
Agile that works and the tools we love
rasmusluckow
331
22k
The Curious Case for Waylosing
cassininazir
1
500
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
280
Transcript
コードで理解する eBPF セキュリティモニタリング 2023/02/15 eBPF & コンテナ情報交換会 @ 福岡
森田 浩平 / Kohei Morita 2018年にGMOペパボ株式会社に新卒入社, 2022年より株式会社グラファーにてプロダクトセキュリティに従事。 OWASP Fukuoka Chapter
Leader,セキュリティ・キャンプ講師, 著書に「基礎から学ぶコンテナセキュリティ」など。 出身は愛媛県松山市、現在は福岡で妻+猫1匹と生活中
https://gihyo.jp/book/2023/978-4-297-13635-2
モニタリング用途で使用される。現在はこちらが多めな印象。 より強固にしたい場面で。ただし、実装としては少ない印象。
何を監視するのか • 次のようなイベントをトレースし、普段と異なる挙動を検出できる。プロセスのコンテキスト情報を手 軽に深く安全に取得できるのが eBPF の特徴 • システムコールの呼び出し • ネットワークトラフィック
• ファイルアクセス
コードで理解する eBPF セキュリティモニタリング 題材として “curl のときに example.com への通信をブロックする” 小さいプログラムを作る 。
1. 通信を発生させる関数に attach してプロセスコンテキストを取得・表示する 2. eBPF Map に設定を書き込んでユーザーランドで表示結果をフィルタする 3. curl のとき example.com への接続の場合に通信をブロックする コードは https://github.com/mrtc0/ebpf-demo にあります。
アタッチする関数の決定 $ dig +short example.com 93.184.216.34 $ sudo strace curl
https://example.com |& grep 93.184 connect(5, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("93.184.216.34")}, 16) = -1 EINPROGRESS (Operation now in progress) getpeername(5, {sa_family=AF_INET, sin_port=htons(443), sin_addr=inet_addr("93.184.216.34")}, [128 => 16]) = 0
connect システムコールを確認する
#include "vmlinux.h" #include <asm/unistd.h> #include <bpf/bpf_core_read.h> #include <bpf/bpf_helpers.h> #include <bpf/bpf_tracing.h>
#define AF_INET 2 #define TASK_COMM_LEN 16 char LICENSE[] SEC("license") = "Dual BSD/GPL"; SEC("kprobe/security_socket_connect") int handle_security_socket_connect(struct pt_regs *ctx) { struct event evt; /* int security_socket_connect(struct socket *sock, struct sockaddr *address, int addrlen); PT_REGS_PARM2 は第二引数の address を取得するマクロ */ struct sockaddr *address = (struct sockaddr *)PT_REGS_PARM2(ctx); sa_family_t fam; bpf_core_read(&fam, sizeof(fam), &address->sa_family); if (fam != AF_INET) { return 0; } } https://github.com/mrtc0/ebpf-demo/blob/master/bpf/trace_connect.c
#define EVENTS_RING_SIZE (4*4096) struct event { struct in_addr dst; u8
comm[TASK_COMM_LEN]; }; // events をユーザーランドと共有するための Map struct { __uint(type, BPF_MAP_TYPE_RINGBUF); __uint(max_entries, EVENTS_RING_SIZE); } events SEC(".maps"); https://github.com/mrtc0/ebpf-demo/blob/master/bpf/trace_connect.c
SEC("kprobe/security_socket_connect") int handle_security_socket_connect(struct pt_regs *ctx) { struct event evt; struct
sockaddr *address = (struct sockaddr *)PT_REGS_PARM2(ctx); sa_family_t fam; __builtin_memset(&evt, 0, sizeof(evt)); bpf_core_read(&fam, sizeof(fam), &address->sa_family); if (fam != AF_INET) { return 0; } // events Map に書き込む struct sockaddr_in *addr = (struct sockaddr_in *)address; bpf_get_current_comm(&evt.comm, sizeof(evt.comm)); evt.dst = BPF_CORE_READ(addr, sin_addr); bpf_ringbuf_output(&events, &evt, sizeof(evt), 0); return 0; } https://github.com/mrtc0/ebpf-demo/blob/master/bpf/trace_connect.c
実行結果 $ sudo ./bbarrier tracer 2024/02/15 11:28:31 waiting for events...
2024/02/15 11:28:37 event: comm=curl addr=889192575 # 127.0.0.53 2024/02/15 11:28:37 event: comm=curl addr=584628317 # 93.184.216.34 2024/02/15 11:28:37 event: comm=curl addr=584628317 # 93.184.216.34 $ curl https://example.com/ $ dig +short example.com 93.184.216.34
IP アドレスが 93.184.216.34 のときだけ検知したい • ユーザーランドでフィルタしても良いが今回は eBPF プログラム内で行ってみる
BPF_MAP_TYPE_LPM_TRIE
struct { __uint(type, BPF_MAP_TYPE_LPM_TRIE); __uint(max_entries, 256); __type(key, struct ipv4_lpm_key); __type(value,
__u32); __uint(map_flags, BPF_F_NO_PREALLOC); } denied_ipaddr_map SEC(".maps"); int handle_security_socket_connect(struct pt_regs *ctx) { ... struct ipv4_lpm_key key = { .prefixlen = 32, .data = evt.dst.s_addr }; if (bpf_map_lookup_elem(&denied_ipaddr_map, &key)) { bpf_ringbuf_output(&events, &evt, sizeof(evt), 0); } ... } err = objs.DeniedIPAddrMap.Put(&socketConnectIpv4LpmKey{ Prefixlen: 32, Data: network.IPToInt(exampleComIPAddr), }, uint32(0)) https://github.com/mrtc0/ebpf-demo/blob/master/bpf/trace_connect.c https://github.com/mrtc0/ebpf-demo/blob/master/pkg/tracer/socket_connect.go
実行結果 $ r$ sudo ./bbarrier tracer 2024/02/15 13:57:58 waiting for
events... 2024/02/15 13:58:02 event: comm=curl addr=[93 184 216 34] 2024/02/15 13:58:02 event: comm=curl addr=[93 184 216 34] $ curl https://example.com/ $ curl https://github.com/
Fault Injection (Error Injection) A. bpf_override_return() と bpf_send_signal() を使う ◦
e.g. Tetragon B. LSM BPF を使う ◦ e.g. Teleport
bpf_override_return() と bpf_send_signal() • 関数の戻り値を変更し、プロセスにシグナルを送る ◦ 戻り値を変更できるのは一部の関数のみ • 悪意あるプロセスがシグナルをハンドリングしている場合、シグナルを送っても無効化されるので、 bpf_override_return()
と組み合わせるべし BPF LSM を使う • 素朴に BPF プログラム内で return -EPERM とかすれば良い • Ubuntu 22.04 LTS では、起動時のパタメータを変更する必要があって、シュッとは使えない
bpf_override_return() が使える条件 • Tracepoint では使えないので Kprobe を使う • また、Kprobe の中でも許可されている関数しか使えない
◦ cat /proc/kallsyms | grep _eil_addr ◦ 対象のほとんどがシステムコール • 今は x86 でしか使えないはず (man 7 bpf-helpers 調べ) ◦ ( ちなみに LSM BPF も ARM64 は still in development だったと思う...
アタッチする場所を変更じゃ mrtc0@sandbox:~$ cat /proc/kallsyms | grep _eil_addr | grep security_socket_connect
mrtc0@sandbox:~$ cat /proc/kallsyms | grep _eil_addr | grep connect 0000000000000000 d _eil_addr___ia32_sys_connect 0000000000000000 d _eil_addr___x64_sys_connect security_socket_connect では使えない...
SEC("kprobe/sys_connect") int kprobe__sys_connect(struct pt_regs *ctx) { ... struct denied_command comm;
bpf_get_current_comm(&comm.comm, sizeof(evt.comm)); if (bpf_map_lookup_elem(&denied_ipaddr_map, &key) && bpf_map_lookup_elem(&denied_command_map, &comm)) { bpf_ringbuf_output(&events, &evt, sizeof(evt), 0); bpf_send_signal(9); bpf_override_return(ctx, -1); } return 0; } https://github.com/mrtc0/ebpf-demo/blob/master/bpf/enforce_connect.c
実行結果 $ r$ sudo ./bbarrier enforce 2024/02/15 13:57:58 waiting for
events... 2024/02/15 13:58:02 event: comm=curl addr=[93 184 216 34] mrtc0@sandbox:~$ curl -sI https://example.com Killed mrtc0@sandbox:~$ curl -sI https://github.com HTTP/2 200 server: GitHub.com mrtc0@sandbox:~$ wget https://example.com --2024-02-17 06:00:06-- https://example.com/ Resolving example.com (example.com)... 93.184.216.34, 2606:2800:220:1:248:1893:25c8:1946 Connecting to example.com (example.com)|93.184.216.34|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 1256 (1.2K) [text/html] Saving to: ʻindex.htmlʼ
eBPF でセキュリティモニタリングがどう変わる? • 従来までプロセスのコンテキストを深く追うことは Kernel Module を作るしかなかった ◦ それが非常に簡単に、かつ、安全に実現できるようになった •
従来の技術でも工夫次第で十分にモニタリングはできるが、コンテナ環境では限界がある ◦ すでに多くの企業が eBPF を使ったモニタリングを実装・運用している • 主要なディストリビューションで「カーネルのバージョンが新しい」「デフォルトで eBPF に関する Kernel Config が有効になっている」状態になると、もっと広がる • プロセスのコンテキスト情報を蓄積・分析する基盤があれば、「本当に疑わしい挙動」のみにフォーカ スできるようになる (誤検知が減る) ◦ フォレンジックの分野でも状況証拠が多く手に入る