Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
pakeana27
Masaya YAMAMOTO
April 27, 2015
2
760
pakeana27
パケットモニタリングツール自作のススメ
Masaya YAMAMOTO
April 27, 2015
Tweet
Share
Featured
See All Featured
WebSockets: Embracing the real-time Web
robhawkes
58
6k
It's Worth the Effort
3n
177
26k
GraphQLとの向き合い方2022年版
quramy
20
9.8k
Building Flexible Design Systems
yeseniaperezcruz
314
35k
Web Components: a chance to create the future
zenorocha
304
40k
Designing for Performance
lara
601
65k
Creating an realtime collaboration tool: Agile Flush - .NET Oxford
marcduiker
6
830
Responsive Adventures: Dirty Tricks From The Dark Corners of Front-End
smashingmag
239
19k
Let's Do A Bunch of Simple Stuff to Make Websites Faster
chriscoyier
500
130k
VelocityConf: Rendering Performance Case Studies
addyosmani
317
22k
Documentation Writing (for coders)
carmenintech
51
2.9k
A Tale of Four Properties
chriscoyier
149
21k
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
ありがとうございました