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
Claude Codeを「使うほど育つ」AI秘書にするノウハウ
minorun365
PRO
27
22k
今話題のAI「Jev」って何? 宇宙最速で学ぶ会
minorun365
PRO
21
13k
AI時代の「技術的負債」の変質ー概念の終焉と再解釈、エージェントと共に向かう先
nwiizo
0
2.6k
10分で知る最近のOmarchy
komagata
0
330
HRC_Frontend_Conference_Fukuoka_2026.pdf
ts020
0
730
Geolonia の開発現場における AIの活用について
miya0001
0
100
山手線を徒歩で一周してわかった、 位置情報アプリは「足」が最強のデバッガー
hinakko
0
160
積み重なった技術負債への挑戦 〜初手としての全社ゴト化〜
techtekt
PRO
0
1.2k
データ界隈LT祭 第1回LT登壇
taromatsui_cccmkhd
1
1.3k
OpenTelemetryのメトリクスをCloudWatchに送ってPromQLで見てみた
ota1022
0
150
range over func 2年間の軌跡 Issue #56413 はGoのエコシステムをどう変えたか
ryujicre8ive
0
190
【技術的負債conf】事業成長に伴う技術的負債の説明責任とAIによるモニタリング、認知的負債について
i35_267
2
1.6k
Featured
See All Featured
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
How To Speak Unicorn (iThemes Webinar)
marktimemedia
1
580
Build The Right Thing And Hit Your Dates
maggiecrowley
39
3.4k
Designing Experiences People Love
moore
143
24k
Jess Joyce - The Pitfalls of Following Frameworks
techseoconnect
PRO
1
410
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Accessibility Awareness
sabderemane
1
210
Making the Leap to Tech Lead
cromwellryan
135
10k
The innovator’s Mindset - Leading Through an Era of Exponential Change - McGill University 2025
jdejongh
PRO
1
330
Designing Powerful Visuals for Engaging Learning
tmiket
1
550
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
300
Believing is Seeing
oripsolob
1
220
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 が有効になっている」状態になると、もっと広がる • プロセスのコンテキスト情報を蓄積・分析する基盤があれば、「本当に疑わしい挙動」のみにフォーカ スできるようになる (誤検知が減る) ◦ フォレンジックの分野でも状況証拠が多く手に入る