Upgrade to Pro — share decks privately, control downloads, hide ads and more …

pakeana27

Masaya YAMAMOTO
April 27, 2015
770

 pakeana27

パケットモニタリングツール自作のススメ

Masaya YAMAMOTO

April 27, 2015
Tweet

Transcript

  1. パケットモニタリングツール  
    ⾃自作のススメ
    KLab  Inc.  
    @pandax381
    第27回  ネットワークパケットを読む会(仮)  
    #pakeana

    View Slide

  2. ⾃自⼰己紹介
    ・⼭山本  雅也(@pandax381)  
      ・https://github.com/pandax381  
    ・KLab株式会社(2012/05  〜~)  
      ・「Kラボラトリー」という研究開発部⾨門に所属  
      ・⽇日々、パケットと戯れたり変なツール作ったり  
      ・ゲーム開発とは関係ないことばかりやっています  
    ・書籍  
      ・Xen3.0による仮想化サーバの構築(絶版)  
      ・プロトコルスタック⾃自作本(執筆中)

    View Slide

  3. アジェンダ
    ・miruo  の紹介  
    ・パケットモニタリングツールの作り⽅方  
    ・gopacket  の紹介

    View Slide

  4. みなさん、今⽇日も⼀一⽇日  tcpdump  お疲れさまでした

    View Slide

  5. ところで、どんな時に  tcpdump  使いますか?

    View Slide

  6. ⼤大好きなあの娘のパケットを(ry

    View Slide

  7. tcpdump  を使うとき
    ・障害発⽣生時に通信レイヤで異異常がないか確認する  
      ・サーバに接続できない  
      ・通信が切切断される  
      ・想定外のタイムアウトが発⽣生する  
      ・etc..  
    ・だいたい緊急なのでのんびりWiresharkで解析する暇なし  
      ・ほとんどの通信は正常なパケットが⾶飛び交う  
      ・膨⼤大なパケットの中から怪しいパケットを探し出す  
      ・五感を研ぎ澄ませてパケットの流流れを追う

    View Slide

  8. miruo

    View Slide

  9. miruo  #1
    ・https://github.com/KLab/miruo  
    ・Pretty  print  TCP  session  monitor/analizer  
    ・出⼒力力が⾒見見易易い  tcpdump  ⾵風のツール  
    ・興味がありそうなパケットを抽出して表⽰示

    View Slide

  10. miruo  #2
    ・2011年年頃に開発したツールですが、現役で活躍してます  
      http://dsas.blog.klab.org/archives/51977201.html  
    ・最近(先週)BSD対応したので  Mac  でも使えます  

    View Slide

  11. miruo  #3
    ・出⼒力力トリガを細かく指定できます  
      ・確⽴立立から指定時間が経過したセッション  
        ※  出⼒力力はセッション終了了時にまとめて⾏行行われるため  
            接続しっぱなしのセッションには不不向きです  
      ・再送パケット(SYNの再送は別途指定可能)  
      ・RSTの受信  
      ・ACK受信までに時間がかかったパケット  
      ・etc..

    View Slide

  12. 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 -
    0001:0001 17:27:30.099 | ESTABLISHED <-A--S-< SYN_RECV | 5F9DC421/1B5B2032 78 -
    0001:0002 17:27:30.099 | ESTABLISHED >-A----> ESTABLISHED | 1B5B2032/5F9DC422 66 -
    0001:0003 17:27:30.099 | ESTABLISHED >-AP---> ESTABLISHED | 1B5B2032/5F9DC422 572 -
    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 -
    DPI:HTTP:ResponseLine >>> HTTP/1.1 200 OK

    0001:**** | |

    0001:0016 17:27:30.136 | ESTABLISHED <-A---F< FIN_WAIT1 | 5F9DF149/1B5B222C 66 -
    0001:0017 17:27:30.136 | CLOSE_WAIT >-A----> FIN_WAIT2 | 1B5B222C/5F9DF149 66 -
    0001:**** | |

    0001:0019 17:27:30.136 | LAST_ACK >-A---F> FIN_WAIT2 | 1B5B222C/5F9DF14A 66 -
    0001:0020 17:27:30.142 | CLOSED <-A----< TIME_WAIT | 5F9DF14A/1B5B222D 66 - ・DPIモードを有効にするとHTTPの内容も出⼒力力できます

    View Slide

  13. パケットモニタリングツールの作り⽅方

    View Slide

  14. パケットモニタリングツールの作り⽅方  #1
    libpcap  
      ・https://github.com/the-‐‑‒tcpdump-‐‑‒group/libpcap  
      ・パケットキャプチャの定番ライブラリ  
      ・tcpdump  をライブラリ化したもの  
      ・tcpdump  と同じフィルタ構⽂文が使える  
      ・プラットフォームに依存しない  API  を提供してくれる

    View Slide

  15. パケットモニタリングツールの作り⽅方  #2
    #include    
    !
    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ハンドルを作成  
    !
    !
    //  フィルタ構⽂文をコンパイル  
    //  コンパイル済みのフィルタをハンドルに適⽤用  
    !
    !
    //  コールバック関数を登録してキャプチャ開始

    View Slide

  16. パケットモニタリングツールの作り⽅方  #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)  */

    View Slide

  17. パケットモニタリングツールの作り⽅方  #4
    ・IPパケットの処理理はとても簡単  
      ・基本はヘッダを解析するだけ  
      ・フラグメント化したIPパケットの再構成くらい  
    ・TCPになるとセッションのステート管理理が⼤大変  
      ・とにかくRFC読んで頑張る  
      ・libpcap  が取りこぼす可能性もあるので空気読んであげる  
    ・L7の解析に⼿手を出すとかなり地獄  
      ・TCPセグメントをまたぐデータどうするの...  
      ・TCPのストリームを復復元するところからはじめる  
      ・プロトコルスタックの気持ちを理理解する

    View Slide

  18. gopacket

    View Slide

  19. gopacket  #1
    ・https://github.com/google/gopacket  
    ・golang  のパケットライブラリ(Google謹製)  
    ・キャプチャ部分は  libpcap  を  wrap  している  
    ・gopacket/tcpassembly  がスゴい!  
      ・TCP  Assembly  /  Reassembly  
      ・受信したTCPセグメントを  Reassembly  に⾷食わせると  
          TCPセッションをリアセンブルできる  
      ・ファイルを読み出す感覚でストリーム処理理できる

    View Slide

  20. gopacket  #2

    View Slide

  21. 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[]    map[]    /  }  with  0  bytes  in  
    request  body  
    ...
    https://github.com/google/gopacket/tree/master/
    examples/httpassembly

    View Slide

  22. ありがとうございました

    View Slide