昼飯を買いに行くついでに、さくらでも取ろうと一眼レフを持っていったけど、人の多さに嫌気がさしたので、さんまだけ買って帰ってきました。
たけけんさんは大学に入ってから大二病を患うまではインターネットの仕事がしたかったので、むかしのTCP/IPの本がそこそこあるのです。
衣替えのついでに本も触ってたんだけど、さすがにTCP/IPの中身は変わらないので、最初は処分しようと思ってたんだけど、結構読んでしまった。
そんな感じで、tcpdumpについて調べようと思ってたところでちょうどよさげな内容があったのでちょっとやってみた。
本を捨てずに置いていたのもすごいことだが、今になって役に立つとはこの本を買った当時の自分には想像もつかんだろう。
うむ、よいことです。
実験のために前に作っていたVMを2個立ち上げる。
freebsdとScientificです。
どうせなのでFreeBSD側が受信側(tcpdumpした方)でScientific側が送信側にしよう。
さくっと終わると思ったら、最初だからか(んなわけねー)pingが通らない。
$ ping 192.168.24.180 PING 192.168.24.180 (192.168.24.180) 56(84) bytes of data. ^C --- 192.168.24.180 ping statistics --- 12 packets transmitted, 0 received, 100% packet loss, time 11136ms
ipf.rulesを見ると通さないようにしていたようだ。
block in log quick proto icmp all group 100 pass in log quick proto icmp all icmp-type 0 group 100
PASSに書き換えた。
pass in log quick proto icmp all group 100 pass in log quick proto icmp all icmp-type 0 group 100
ルールを適用しよう。
% ipf -Fa -Z -f /etc/ipf.rules bad packets: in 0 out 0 input packets: blocked 243 passed 3028 nomatch 0 counted 0 output packets: blocked 0 passed 2101 nomatch 3 counted 0 input packets logged: blocked 105 passed 0 output packets logged: blocked 0 passed 0 packets logged: input 0-0 output 0-0 unknown name "***.***.***.***" unknown name "***.***.***.***"
こんどは通りました。
$ ping 192.168.24.180 PING 192.168.24.180 (192.168.24.180) 56(84) bytes of data. 64 bytes from 192.168.24.180: icmp_seq=1 ttl=64 time=0.191 ms 64 bytes from 192.168.24.180: icmp_seq=2 ttl=64 time=0.762 ms 64 bytes from 192.168.24.180: icmp_seq=3 ttl=64 time=0.647 ms ^C --- 192.168.24.180 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2280ms rtt min/avg/max/mdev = 0.191/0.533/0.762/0.247 ms
ではdumpしてみたんだけど、なんだこりゃ!なんか思ってたのと違う・・・
% tcpdump -s 1 -i em0 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on em0, link-type EN10MB (Ethernet), capture size 1 bytes 12:51:24.603812 [|ether] 12:51:24.603820 [|ether] 12:51:24.933780 [|ether] 12:51:24.933918 [|ether] 12:51:24.936318 [|ether] 12:51:24.986176 [|ether]
よくある事だがFreebsdとLinuxではオプションが違うみたいなので、オプションを調べるのにちょっと時間がかかったけど、ほしい情報はとれた。
% tcpdump -s 0 -X -l -i em0 -p icmp tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on em0, link-type EN10MB (Ethernet), capture size 65535 bytes 12:54:25.584215 IP 192.168.24.60 > 192.168.24.180: ICMP echo request, id 44584, seq 1, length 64 0x0000: 4500 0054 0000 4000 4001 8868 c0a8 183c E..T..@.@..h...< 0x0010: c0a8 18b4 0800 0131 ae28 0001 71db 3c53 .......1.(..q.<S 0x0020: 0000 0000 d3a3 0800 0000 0000 1011 1213 ................ 0x0030: 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 .............!"# 0x0040: 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 $%&'()*+,-./0123 0x0050: 3435 3637 4567 12:54:25.584257 IP 192.168.24.180 > 192.168.24.60: ICMP echo reply, id 44584, seq 1, length 64 0x0000: 4500 0054 24cc 4000 4001 639c c0a8 18b4 E..T$.@.@.c..... 0x0010: c0a8 183c 0000 0931 ae28 0001 71db 3c53 ...<...1.(..q.<S 0x0020: 0000 0000 d3a3 0800 0000 0000 1011 1213 ................ 0x0030: 1415 1617 1819 1a1b 1c1d 1e1f 2021 2223 .............!"# 0x0040: 2425 2627 2829 2a2b 2c2d 2e2f 3031 3233 $%&'()*+,-./0123 0x0050: 3435 3637 4567
これだよ、これ。
それではIPヘッダーフォーマットと比べてみようか。
1バイト目が45、IPのバージョンが4で、IPヘッダの長さが5だ。
4×5の20がIPヘッダ長となるようだ。
IPヘッダの10バイト目が01なので、ICMPってことが分かる。
IPヘッダ長は20バイトなので、ICMPヘッダの先頭は21バイト目。
ICMPメッセージの種類を示すタイプ番号から始まるので08はメッセージ番号となって
8 エコー要求(echo request)なので間違いない。
応答側の21バイト目を見てみると00だ。
0 エコー応答(echo reply)なので、こちらもちゃんと合っていて問題ない。
ヘッダーフォーマットはこんな具合に見ていくようだね。うん、勉強になった。
この感動はまるでずいぶんと前に買った本を読んで感動した時のようだな。
ん?たとえになってない?
よく気づいたな。
ではせっかくなのでTCPでも軽くだけやってみよう。
13:31:41.800270 IP 192.168.24.60.52534 > 192.168.24.180.ssh: Flags [P.], seq 0:21, ack 50, win 229, options [nop,nop,TS val 8365109 ecr 1318760935], length 21 0x0000: 4500 0049 88a6 4000 4006 ffc7 c0a8 183c E..I..@.@......< 0x0010: c0a8 18b4 cd36 0016 6f0c 2c8e e252 2113 .....6..o.,..R!. 0x0020: 8018 00e5 f14d 0000 0101 080a 007f a435 .....M.........5 0x0030: 4e9a b1e7 5353 482d 322e 302d 4f70 656e N...SSH-2.0-Open 0x0040: 5353 485f 352e 330d 0a SSH_5.3..
さっきと同じく20バイトがIPヘッダってのは一緒だね。だけど今回は10バイト目が6なのでTCPだってことが分かる。
21バイト目からがTCPヘッダってことだな。
TCPヘッダフォーマットと合わせてみてみると、最初の2バイトはsrc側のポート番号なので、cd36を10進数にしてみると52534。次の2バイトがdst側のポート番号なので、0016を10進数にすると22なので、これはsshのポートと一致しますな。
続いてシーケンシャル番号と続いていくわけである。
ここまでにしようかな。けっしてめんどくさいわけでないよっと。