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
340
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
760
GMO ペパボ株式会社 23卒・24卒向け セキュリティ勉強会 実践 DevSecOps パイプライン
mrtc0
1
790
実践 DevSecOps パイプライン ~システム開発へのセキュリティの取り入れ方~
mrtc0
2
640
脅威モデリングで考える 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
Browser Spec: Testing Hotwire with Ruby
takahashim
1
110
Optunaの最新リリースv5.0について
pfn
PRO
0
110
Persisting Massive Data with Rails ~Designing for 60 billion rows, and fighting the bottlenecks~ Railsで挑む大量データ永続化 〜600億件を永続化するための設計とボトルネックとの戦い〜
occhi
0
710
ブラウザとサーバーから考えるAI時代のフロントエンド監視
shogo4131
3
930
Classmethod Company Deck
satoshi7
1
640
hackers_champloo_2026_tidb
makocchi
0
160
Running Kotlin + Quarkus with Lambda
nealle
1
3.5k
PagerDuty Tech Hub-鳴らすけれど、人は動かない
ezaki
0
160
AIは「聞けば答える」から「任せると自分で進める」へ - JACTIMペナン地域部会・ペナン三水会講演
knishioka
0
110
継続的なAIコスト最適化
bgpat
1
330
Local CI × GitHub Actions
gogutan
2
150
今さら理解するウェブフォントver.2026
takanorip
3
720
Featured
See All Featured
What Being in a Rock Band Can Teach Us About Real World SEO
427marketing
0
1.1k
How to Ace a Technical Interview
jacobian
280
24k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
520
Game over? The fight for quality and originality in the time of robots
wayneb77
1
300
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Why You Should Never Use an ORM
jnunemaker
PRO
61
10k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
1.1k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
KATA
mclloyd
PRO
35
16k
HDC tutorial
michielstock
2
960
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
520
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 が有効になっている」状態になると、もっと広がる • プロセスのコンテキスト情報を蓄積・分析する基盤があれば、「本当に疑わしい挙動」のみにフォーカ スできるようになる (誤検知が減る) ◦ フォレンジックの分野でも状況証拠が多く手に入る