モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

工作HardwareHub ロゴ画像 (Laptop端末利用時)
工作HardwareHub ロゴ画像 (Mobile端末利用時)

tcpdumpチートシート

モーダルを閉じる

ステッカーを選択してください

モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2014/09/22
最終更新最終更新
2021/01/07
記事区分記事区分
一般公開

目次

    アカウント プロフィール画像 (サイドバー)

    アルゴリズムが大好きなエンジニアです。グラフ理論や効率的な解法に関する記事を書く予定。

    0
    ステッカーを贈るとは?

    pcap (packet capture) というパケットキャプチャ用APIの実装には、UNIX系のlibpcapとWindowsのWinPcapがあります。これらのライブラリを利用したアプリケーションとしては、UNIX系のtcpdumpとWindowsのWiresharkが有名です。また、スクリプト言語にはlibpcap/WinPcapのラッパーが存在しており、パケットキャプチャアプリケーションの開発時に利用できます。例えばPerlにはNet::Pcapというラッパーがあります。

    以下にtcpdumpコマンドを用いたパケットキャプチャのチートシートを記載します。キャプチャしたものの解析に必要となるヘッダ情報の意味自体は「TCPDUMPの出力を見てみよう」などを参照してください。

    キャプチャするパケットの絞り込み

    インターフェースを指定

    tcpdumpを実行するPCに複数のネットワークインターフェースが存在する場合に、それらのうちどれでパケットキャプチャするかを指定します。-i オプションを指定しないと up 状態のインタフェースの中で番号が一番小さいものが自動的に選択されることに注意します。システムによっては lo (ループバックインタフェース) を含むすべてのインタフェースに関してキャプチャを行う -i any がサポートされています。

    $ tcpdump -i eth0
    

    ポート番号で絞り込む

    あるネットワークインターフェースには様々なTCP/UDPパケットが到着します。それらのうち、TCP/UDPパケットのヘッダにおける「送信元ポート番号」または「宛先ポート番号」が特定の番号のもののみに絞り込むことができます。

    $ tcpdump -i eth0 port 80
    $ tcpdump -i eth0 src port 80 ← 「送信元ポート番号」が80番のもののみ
    $ tcpdump -i eth0 dst port 80 ← 「宛先ポート番号」が80番のもののみ
    $ tcpdump -i eth0 dst port 80 or dst port 443 ← 条件は 'or' で緩められます
    

    IPアドレスで絞り込む

    あるネットワークインターフェースには様々なIPパケットが到着します。それらのうち、IPパケットのヘッダにおける「送信元IPアドレス」または「宛先IPアドレス」が特定の番号のもののみに絞り込むことができます。

    $ tcpdump -i eth0 host 10.0.2.15
    $ tcpdump -i eth0 src host 10.0.2.15 ← 「送信元IPアドレス」で絞り込み
    $ tcpdump -i eth0 dst host 10.0.2.15 ← 「宛先IPアドレス」で絞り込み
    

    サブネットマスクを使用して、複数のIPアドレスを指定することもできます。

    $ tcpdump -i eth0 net 10.0.2.15 mask 255.255.255.255 ← "host 10.0.2.15" と同義
    $ tcpdump -i eth0 net 10.0.2.0 mask 255.255.255.0 ← "10.0.2.0",...,"10.0.2.255"
    

    自分宛のパケットのみをキャプチャ

    tcpdumpコマンドを実行するマシンの、指定したネットワークインターフェース宛てではないパケットを無視するためには、ネットワークカードのプロミスキャスモードを '-p' オプションを付与して無効にします。

    $ tcpdump -i eth0 port 80 -p
    

    パケットを丸ごとキャプチャ

    パケットのペイロードのサイズがある既定値を越えると、パケットキャプチャ時に超過した部分が切り捨てられ、tcpdumpの処理上無視されます。この既定値を無限にするためには '-s0' オプションを付与します。

    $ tcpdump -i eth0 port 80 -s0
    

    キャプチャしたパケットの情報表示

    出力を詳細にする

    '-vvv' オプションを付与すると詳細な情報が出力されます。

    $ tcpdump -i eth0 port 80 -vvv
    

    時間情報を表示しない

    $ tcpdump -i eth0 port 80 -t
    

    ポート番号を文字列に変換して表示しない

    'http' ではなく '80' と表示されるようにするには '-nn' オプションを付与します。

    $ tcpdump -i eth0 port 80 -nn
    

    ペイロード部分をアスキーで表示

    通常実行時はヘッダ情報だけが表示されます。それに加えて、ペイロード情報をアスキー表示するためには '-A' または '-X' オプションを付与します。前述の '-s0' オプションと併用するとよいです。

    $ tcpdump -i eth0 port 80 -s0 -A  ← アスキー表示
    $ tcpdump -i eth0 port 80 -s0 -X  ← アスキーだけでなく16進数でも表示
    

    ファイル入出力

    ファイルに出力

    '-w' オプションを付与すると標準出力ではなくファイル出力ができます。pcapの生データでありエディタで開いてもその意味はよく分かりませんが、tcpdumpやWiresharkで読み込むことができます。

    $ tcpdump -i eth0 port 80 -w http.cap
    

    ファイルから読み込む

    $ tcpdump -r http.cap
    $ tcpdump -r http.cap -t ← オプション指定が可能
    

    分割してファイル書き込み

    一つの巨大なファイルが生成されることを避け、指定秒数毎にファイル分割を行うためには '-G' オプションを付与します。なお、パケットが発生しなかった場合はファイル作成自体がなされません。

    $ tcpdump -i eth0 port 80 -s0 -G 3600 -w http_%Y%m%d_%H%M.cap
    

    YahooサイトへのHTTPアクセスのパケットキャプチャ例

    バックグラウンドでパケットキャプチャ用にtcpdumpコマンドを実行しておきます。

    $ tcpdump -i eth0 port 80 -p -s0 -w http.cap &
    

    Yahooサイトへアクセスします。

    $ curl http://www.yahoo.co.jp/
    

    tcpdumpコマンドをフォアグラウンドに戻して終了させます。

    $ fg
    (Ctrl-C)
    

    ファイルから読み込んで一連のやりとりをアスキー表示してみます。

    $ tcpdump -r http.cap -Atvvv | less
    

    表示された内容を見ると、TCPの教科書に記載されている通りの通信がなされていることが確認できます。

    1. 「3ウェイ・ハンドシェイク」によるコネクション確立
    2. ウィンドウサイズ内でのデータ転送 (シーケンス番号とAck番号に注目)
    3. "FIN" を送信してのコネクション終了

    ping と tcpdump でネットワークの疎通確認のヒントを得る

    ping と併用するとネットワークの疎通確認時などに便利です。icmp と指定することで TCP および UDP パケットを無視できます。また、前述の通り -i オプションを指定しないと up 状態のインタフェースの中で番号が一番小さいものが自動的に選択されることに注意します。

    $ ping 127.0.0.1
    PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
    64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.046 ms
    64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.051 ms
    ...
    
    $ sudo tcpdump -i lo icmp
    tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
    listening on lo, link-type EN10MB (Ethernet), capture size 65535 bytes
    14:41:15.458338 IP localhost > localhost: ICMP echo request, id 47689, seq 1, length 64
    14:41:15.458360 IP localhost > localhost: ICMP echo reply, id 47689, seq 1, length 64
    14:41:16.457353 IP localhost > localhost: ICMP echo request, id 47689, seq 2, length 64
    14:41:16.457365 IP localhost > localhost: ICMP echo reply, id 47689, seq 2, length 64
    ...
    

    パケット解析の例

    インタフェースの確認

    $ traceroute www.example.com
    traceroute to www.example.com (93.184.216.34), 30 hops max, 60 byte packets
     1  gateway (10.0.2.2)  0.195 ms  0.093 ms  0.135 ms
    ...
    
    $ ip a | grep -B2 10.0.2
    2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 08:00:27:08:17:39 brd ff:ff:ff:ff:ff:ff
        inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
    

    パケットキャプチャ

    sudo tcpdump -ienp0s3 -p -s0 -X -t -vvv -nn port 80
    curl www.example.com
    

    ローカルホストから外部サーバへの HTTP リクエストが含まれる IP パケット

    IP (tos 0x0, ttl 64, id 3530, offset 0, flags [DF], proto TCP (6), length 119)
        10.0.2.15.44370 > 93.184.216.34.80: Flags [P.], cksum 0x4253 (incorrect -> 0x2a00), seq 1:80, ack 1, win 29200, length 79: HTTP, length: 79
            GET / HTTP/1.1
            Host: www.example.com
            User-Agent: curl/7.52.1
            Accept: */*
    
            0x0000:  4500 0077 0dca 4000 4006 eacd 0a00 020f  E..w..@.@.......
            0x0010:  5db8 d822 ad52 0050 6834 dd99 2c93 2202  ]..".R.Ph4..,.".
            0x0020:  5018 7210 4253 0000 4745 5420 2f20 4854  P.r.BS..GET./.HT
            0x0030:  5450 2f31 2e31 0d0a 486f 7374 3a20 7777  TP/1.1..Host:.ww
            0x0040:  772e 6578 616d 706c 652e 636f 6d0d 0a55  w.example.com..U
            0x0050:  7365 722d 4167 656e 743a 2063 7572 6c2f  ser-Agent:.curl/
            0x0060:  372e 3532 2e31 0d0a 4163 6365 7074 3a20  7.52.1..Accept:.
            0x0070:  2a2f 2a0d 0a0d 0a                        */*....
    

    上記は TCP セグメントを含む IP パケットです。

    • IP ヘッダ 20 バイト
    • TCP ヘッダ 20 バイト

    TCP データ部は 41 バイト目 4745 5420 2f20 4854 から始まります。今回は以下のコマンドで数値を ASCII コードに変換して確認できます。マルチバイト文字やバイナリデータの場合は適宜処理します。

    $ echo -e '\x47\x45\x54\x20\x2f\x20\x48\x54'
    GET / HT
    $ echo 'print chr(0x47)' | python
    G
    $ echo 'print hex(ord("G"))' | python
    0x47
    

    送信元IPアドレス 32bit 0a00 020f、宛先IPアドレス 32bit 5450 2f31

    $ echo '
    > import socket, struct
    > print socket.inet_ntoa(struct.pack("!I", 0x0a00020f))' | python
    10.0.2.15
    $ mysql -uroot -e "select inet_ntoa(`echo 'obase=10; ibase=16; 0A00020F' | bc`)"
    +----------------------+
    | inet_ntoa(167772687) |
    +----------------------+
    | 10.0.2.15            |
    +----------------------+
    

    送信元ポート番号 16bit + 宛先ポート番号 16bit ad52 0050

    $ echo 'print 0xad52' | python
    44370
    $ echo 'print 0x0050' | python
    80
    

    TCPヘッダ長 4bit + 将来の機能拡張用の予約 6bit + コードビット 6bit 5018

    `5` * 1ワード(32ビット(4バイト)) = 20 バイト
    

    パケット解析の例2 (UDP)

    インタフェースの確認

    traceroute 8.8.8.8
    ip r
    

    パケットキャプチャ

    sudo tcpdump -ienp0s3 -p -s0 -X -t -vvv -nn udp and port 53
    

    DNS クエリ (id: 43521)

    $ dig @8.8.8.8 www.example.com
    
    ; <<>> DiG 9.10.3-P4-Debian <<>> @8.8.8.8 www.example.com
    ; (1 server found)
    ;; global options: +cmd
    ;; Got answer:
    ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43521  <-- ID は 43521 です。
    ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
    
    ;; OPT PSEUDOSECTION:
    ; EDNS: version: 0, flags:; udp: 512
    ;; QUESTION SECTION:
    ;www.example.com.               IN      A
    
    ;; ANSWER SECTION:
    www.example.com.        6354    IN      A       93.184.216.34
    
    ;; Query time: 87 msec
    ;; SERVER: 8.8.8.8#53(8.8.8.8)
    ;; WHEN: Sun Sep 02 16:05:08 JST 2018
    ;; MSG SIZE  rcvd: 60
    

    DNS からの応答 IP パケット

    IP (tos 0x0, ttl 64, id 24556, offset 0, flags [none], proto UDP (17), length 88)
        8.8.8.8.53 > 10.0.2.15.36621: [udp sum ok] 43521$ q: A? www.example.com. 1/0/1 www.example.com. [1h45m54s] A 93.184.216.34 ar: . OPT UDPsize=512 (60)
            0x0000:  4500 0058 5fec 0000 4011 fe8a 0808 0808  E..X_...@.......
            0x0010:  0a00 020f 0035 8f0d 0044 1ccd aa01 81a0  .....5...D......
            0x0020:  0001 0001 0000 0001 0377 7777 0765 7861  .........www.exa
            0x0030:  6d70 6c65 0363 6f6d 0000 0100 01c0 0c00  mple.com........
            0x0040:  0100 0100 0018 d200 045d b8d8 2200 0029  .........].."..)
            0x0050:  0200 0000 0000 0000                      ........
    
    • IP ヘッダ 20 バイト
    • UDP ヘッダ 8 バイト

    送信元ポート番号 16bit + 宛先ポート番号 16bit 0035 8f0d

    $ echo 'print 0x0035' | python
    53
    $ echo 'print 0x8f0d' | python
    36621
    

    UDP データの開始 aa01 81a0

    $ echo 'print 0xaa01' | python
    43521
    

    ID が取得できました。

    0
    詳細設定を開く/閉じる
    アカウント プロフィール画像 (本文下)

    アルゴリズムが大好きなエンジニアです。グラフ理論や効率的な解法に関する記事を書く予定。

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    さらに詳しく →
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。