Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
pakeana27
Search
Masaya YAMAMOTO
April 27, 2015
870
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
pakeana27
パケットモニタリングツール自作のススメ
Masaya YAMAMOTO
April 27, 2015
Featured
See All Featured
Code Review Best Practice
trishagee
74
20k
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
330
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
450
StorybookのUI Testing Handbookを読んだ
zakiyama
31
6.8k
Scaling GitHub
holman
464
140k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
Evolving SEO for Evolving Search Engines
ryanjones
0
210
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
1
340
Statistics for Hackers
jakevdp
799
230k
Tell your own story through comics
letsgokoyo
1
950
Optimising Largest Contentful Paint
csswizardry
37
3.7k
Accessibility Awareness
sabderemane
1
130
Transcript
パケットモニタリングツール ⾃自作のススメ KLab Inc. @pandax381 第27回 ネットワークパケットを読む会(仮)
#pakeana
⾃自⼰己紹介 ・⼭山本 雅也(@pandax381) ・https://github.com/pandax381 ・KLab株式会社(2012/05 〜~)
・「Kラボラトリー」という研究開発部⾨門に所属 ・⽇日々、パケットと戯れたり変なツール作ったり ・ゲーム開発とは関係ないことばかりやっています ・書籍 ・Xen3.0による仮想化サーバの構築(絶版) ・プロトコルスタック⾃自作本(執筆中)
アジェンダ ・miruo の紹介 ・パケットモニタリングツールの作り⽅方 ・gopacket の紹介
みなさん、今⽇日も⼀一⽇日 tcpdump お疲れさまでした
ところで、どんな時に tcpdump 使いますか?
⼤大好きなあの娘のパケットを(ry
tcpdump を使うとき ・障害発⽣生時に通信レイヤで異異常がないか確認する ・サーバに接続できない ・通信が切切断される
・想定外のタイムアウトが発⽣生する ・etc.. ・だいたい緊急なのでのんびりWiresharkで解析する暇なし ・ほとんどの通信は正常なパケットが⾶飛び交う ・膨⼤大なパケットの中から怪しいパケットを探し出す ・五感を研ぎ澄ませてパケットの流流れを追う
miruo
miruo #1 ・https://github.com/KLab/miruo ・Pretty print TCP session monitor/analizer
・出⼒力力が⾒見見易易い tcpdump ⾵風のツール ・興味がありそうなパケットを抽出して表⽰示
miruo #2 ・2011年年頃に開発したツールですが、現役で活躍してます http://dsas.blog.klab.org/archives/51977201.html ・最近(先週)BSD対応したので Mac でも使えます
miruo #3 ・出⼒力力トリガを細かく指定できます ・確⽴立立から指定時間が経過したセッション ※
出⼒力力はセッション終了了時にまとめて⾏行行われるため 接続しっぱなしのセッションには不不向きです ・再送パケット(SYNの再送は別途指定可能) ・RSTの受信 ・ACK受信までに時間がかかったパケット ・etc..
miruo #4 $ ./miruo --all -i en0 -m http tcp
port 80 listening on en0, link-type EN10MB (Ethernet), capture size 1522 bytes 0001 0.048 | 10.0.0.100:62511 == 125.6.190.6:80 | Total 21 segments, 13397 bytes 0001:0000 17:27:30.093 | SYN_SENT >----S-> SYN_RECV | 1B5B2031/00000000 78 - <mss=1460, 0001:0001 17:27:30.099 | ESTABLISHED <-A--S-< SYN_RECV | 5F9DC421/1B5B2032 78 - <mss=1460, 0001:0002 17:27:30.099 | ESTABLISHED >-A----> ESTABLISHED | 1B5B2032/5F9DC422 66 - <timestamp 0001:0003 17:27:30.099 | ESTABLISHED >-AP---> ESTABLISHED | 1B5B2032/5F9DC422 572 - <timestamp DPI:HTTP:RequestLine >>>> GET /archives/51977201.html HTTP/1.1 DPI:HTTP:Header >>>>>>>>> Host: dsas.blog.klab.org 0001:0004 17:27:30.125 | ESTABLISHED <-AP---< ESTABLISHED | 5F9DC422/1B5B222C 1514 - <timestamp DPI:HTTP:ResponseLine >>> HTTP/1.1 200 OK 0001:**** | | 0001:0016 17:27:30.136 | ESTABLISHED <-A---F< FIN_WAIT1 | 5F9DF149/1B5B222C 66 - <timestamp 0001:0017 17:27:30.136 | CLOSE_WAIT >-A----> FIN_WAIT2 | 1B5B222C/5F9DF149 66 - <timestamp 0001:**** | | 0001:0019 17:27:30.136 | LAST_ACK >-A---F> FIN_WAIT2 | 1B5B222C/5F9DF14A 66 - <timestamp 0001:0020 17:27:30.142 | CLOSED <-A----< TIME_WAIT | 5F9DF14A/1B5B222D 66 - <timestamp ・DPIモードを有効にするとHTTPの内容も出⼒力力できます
パケットモニタリングツールの作り⽅方
パケットモニタリングツールの作り⽅方 #1 libpcap ・https://github.com/the-‐‑‒tcpdump-‐‑‒group/libpcap ・パケットキャプチャの定番ライブラリ
・tcpdump をライブラリ化したもの ・tcpdump と同じフィルタ構⽂文が使える ・プラットフォームに依存しない API を提供してくれる
パケットモニタリングツールの作り⽅方 #2 #include <pcap.h> ! char errmsg[PCAP_̲ERRBUF_̲SIZE] const
char expression[] = “tcp”; struct bpf_̲program bpf; ! pcap = pcap_̲create(“en0”, errmsg); pcap_̲set_̲promisc(pcap, 1); pcap_̲activate(pcap); pcap_̲compile(pcap, &bpf, expression, 0, 0); pcap_̲setfilter(pcap, &bpf); pcap_̲freecode(&bpf); ! pcap_̲loop(pcap, -‐‑‒1, callback, NULL); ! pcap_̲close(pcap); ! ! ! // フィルタ構⽂文 ! ! // 新しいpcapハンドルを作成 ! ! // フィルタ構⽂文をコンパイル // コンパイル済みのフィルタをハンドルに適⽤用 ! ! // コールバック関数を登録してキャプチャ開始
パケットモニタリングツールの作り⽅方 #3 // arg //
pcap_̲loop() の第4引数に渡したユーザーデータ // pkthdr // キャプチャしたパケットに関する時刻やサイズなどの情報 // pktdata // キャプチャしたパケットデータ(イーサネットフレームの先頭を指すポインタ) void callback (u_̲char *arg, const struct pcap_̲pkthdr *pkthdr, const u_̲char *pktdata) { // 受信したパケット(pktdata)を解析してゴニョゴニョする // そのまま出⼒力力すれば 劣劣化版 tcpdump の出来上がり } ! struct pcap_̲pkthdr { struct timeval ts; bpf_̲u_̲int32 caplen; bpf_̲u_̲int32 len; }; /* time stamp */ /* length of portion present */ /* length this packet (off wire) */
パケットモニタリングツールの作り⽅方 #4 ・IPパケットの処理理はとても簡単 ・基本はヘッダを解析するだけ ・フラグメント化したIPパケットの再構成くらい
・TCPになるとセッションのステート管理理が⼤大変 ・とにかくRFC読んで頑張る ・libpcap が取りこぼす可能性もあるので空気読んであげる ・L7の解析に⼿手を出すとかなり地獄 ・TCPセグメントをまたぐデータどうするの... ・TCPのストリームを復復元するところからはじめる ・プロトコルスタックの気持ちを理理解する
gopacket
gopacket #1 ・https://github.com/google/gopacket ・golang のパケットライブラリ(Google謹製) ・キャプチャ部分は libpcap を
wrap している ・gopacket/tcpassembly がスゴい! ・TCP Assembly / Reassembly ・受信したTCPセグメントを Reassembly に⾷食わせると TCPセッションをリアセンブルできる ・ファイルを読み出す感覚でストリーム処理理できる
gopacket #2
gopacket #3 $ ./httpassembly -‐‑‒i en0 2015/04/27 16:15:09 Starting
capture on interface "en0" 2015/04/27 16:15:09 reading in packets 2015/04/27 16:15:23 Received request from stream 10.0.0.100-‐‑‒ >133.242.5.116 61747-‐‑‒>80 : &{GET / HTTP/1.1 1 1 map[Accept: [*/*] User-‐‑‒Agent:[curl/7.30.0]] 0x45e3410 0 [] false www.klab.com map[] map[] <nil> map[] / <nil>} with 0 bytes in request body ... https://github.com/google/gopacket/tree/master/ examples/httpassembly
ありがとうございました