定期的にパケットキャプチャ(tcpdump)を実行したい

# はじめに
LinuxにせよWindowsにせよ、トラブルシューティングに大活躍のパケットキャプチャ。
インフラエンジニアならば、必須のスキルと言っても過言ではないだろう。
普通は、事象発生のタイミングにあわせてtcpdumpコマンド実行したりするのだろうが、
そんなタイミングよく事象発生しないような意地悪いトラブルを相手にすることだってあるはず。
むしろよくある。

そんなときは、**毎日定時にtcpdumpを仕掛けておいて、あとで事象発生した場合はパケットキャプチャの結果を解析**したくなるはずだ。
というわけで。

# tcpdumpを定期的に実行
みんな大好きtcpdumpをcronで定期的に実行させてみよう。
別にcronでなくても良いのだが、まぁトラブルシューティングということで、
ある一定期間にだけ必要なのであれば、大それた定期実行システムを構築する必要性はない。
cronで十分だ。

```bash
00 9 * * * /bin/timeout 900 /usr/sbin/tcpdump -i eth0 port 80 or port 443 -w /$(date +'\%Y\%m\%d').pcap
# 15 9 * * * /bin/kill -15 $(ps ax | grep [t]cpdump | awk '{print $1}')
```

# 中身の解説
上記の例の場合、毎日9:00過ぎに実行されるバッチ処理で問題が起きているため、
その時間帯にのみパケットキャプチャをしたい、という前提があると仮定しておく。

1行目で9時ぴったりにtcpdumpを実行。
timeoutコマンドで900秒を指定し、つまり15分後にtcpdumpが正常終了されるようにしている。
またこの場合のtcpdumpはeth0というインターフェースに限定し、HTTP/HTTPSプロトコルを狙い撃ちしている。
そして、 `-w`でファイルとして保存しておく。
当たり前の話だが、これでは投げっぱなしジャーマンだ。
絶対的に必要なのは`-w`でファイル保存させておくという点。これでpcap形式で保存しておける。
また、保存する際のファイル名は動的なものにしておかないと、上書きされてしまう。
そのため、この例ではdateコマンドで年月日を付与して保存している。
cronの中ではdateフォーマットの`%`は`\`でエスケープさせなければならない点にも注意。

~~2行目で15分後にkillさせる。~~
~~`ps, grep, awk`コマンドを使ってPIDを抜いてきてkill -15で正常終了させている。~~
~~psは`ax`をつけないとtcpdumpのプロセスが表示されないので必須。~~
~~grepは[t]cpdumpとしてやることで、よくあるpsとgrepの組み合わせでgrepコマンド自体も抜いてきちゃう、というのを防いでいる。~~
~~awkはデフォでタブあるいは半角スペースで区切ってくれるので、print $1で区切った最初(PID)だけ表示させている。~~

**2018/11/29追記**
コメント欄で非常に素敵なご指摘頂きました。
わざわざkill使わくても、timeoutコマンドでスマートに終了させられるのこと。
timeoutコマンドはその名の如く、一定時間経つと引数で指定したコマンドに対して任意のシグナルを投げられるという非常に便利なコマンド。
このコマンド今まで知りませんでしたorz
何も指定しないと、 **15(KILLTERM)** を投げてくれるので、秒数とコマンドだけ指定するだけでお手軽一定時間実行！！素晴らしい！！

詳しくまとめてくださっている方がいらっしゃったので、以下の記事をどうぞ。
[一定時間でシェルコマンドを終了させるたった1つの方法](https://qiita.com/ma2saka/items/741b614418bf8fce04de)

これでキレイにtcpdumpが終了される。
やはり立つ鳥は跡を濁すべきではない。

# 解析
さてさて、何日か経って、お目当ての事象が発生したとしよう。
よーし。仕事だ。解析だ！

方法としては普通にtcpdumpに読み込ませるパターンと、
Windowsに持っていってWireSharkなどの好きなパケットキャプチャツールに読み込ませるパターンがある。
pcapなので代表的なツールなら皆読み込めるはず。
ガッツリ解析するなら、WireSharkのほうが良いだろう。私はそうしてる。

以下はtcpdumpで読み込ませるパターン。 `-r`で読み込ませられる。

```bash
[root@localhost ~]# tcpdump -r /20181128.pcap
reading from file /20181128.pcap, link-type EN10MB (Ethernet)
07:37:32.059512 IP localhost.localdomain.37054 > nas1500.ftp.pub.2iij.net.http: Flags [S], seq 4024263417, win 29200, options [mss 1460,sackOK,TS val 542043 ecr 0,nop,wscale 6], length 0
07:37:32.067900 IP nas1500.ftp.pub.2iij.net.http > localhost.localdomain.37054: Flags [S.], seq 97216001, ack 4024263418, win 65535, options [mss 1460], length 0
07:37:32.067917 IP localhost.localdomain.37054 > nas1500.ftp.pub.2iij.net.http: Flags [.], ack 1, win 29200, length 0
07:37:32.068058 IP localhost.localdomain.37054 > nas1500.ftp.pub.2iij.net.http: Flags [P.], seq 1:171, ack 1, win 29200, length 170: HTTP: GET /pub/linux/centos/7.5.1804/updates/x86_64/Packages/tzdata-2018f-2.el7.noarch.rpm HTTP/1.1
```

オプションをつければ詳細に解析もできる。

```bash
[root@localhost ~]# tcpdump -nn -XX -r /20181128.pcap
reading from file /20181128.pcap, link-type EN10MB (Ethernet)
07:37:32.059512 IP 10.0.2.15.37054 > 202.232.140.70.80: Flags [S], seq 4024263417, win 29200, options [mss 1460,sackOK,TS val 542043 ecr 0,nop,wscale 6], length 0
        0x0000:  5254 0012 3502 5254 00c0 42d5 0800 4500  RT..5.RT..B...E.
        0x0010:  003c 27a2 4000 4006 afdc 0a00 020f cae8  .<'.@.@.........
        0x0020:  8c46 90be 0050 efdd 62f9 0000 0000 a002  .F...P..b.......
        0x0030:  7210 636c 0000 0204 05b4 0402 080a 0008  r.cl............
        0x0040:  455b 0000 0000 0103 0306                 E[........
07:37:32.067900 IP 202.232.140.70.80 > 10.0.2.15.37054: Flags [S.], seq 97216001, ack 4024263418, win 65535, options [mss 1460], length 0
        0x0000:  5254 00c0 42d5 5254 0012 3502 0800 4500  RT..B.RT..5...E.
        0x0010:  002c 39d5 0000 4006 ddb9 cae8 8c46 0a00  .,9...@......F..
        0x0020:  020f 0050 90be 05cb 6601 efdd 62fa 6012  ...P....f...b.`.
        0x0030:  ffff e525 0000 0204 05b4 0000            ...%........
07:37:32.067917 IP 10.0.2.15.37054 > 202.232.140.70.80: Flags [.], ack 1, win 29200, length 0
        0x0000:  5254 0012 3502 5254 00c0 42d5 0800 4500  RT..5.RT..B...E.
        0x0010:  0028 27a3 4000 4006 afef 0a00 020f cae8  .('.@.@.........
        0x0020:  8c46 90be 0050 efdd 62fa 05cb 6602 5010  .F...P..b...f.P.
        0x0030:  7210 6358 0000                           r.cX..
```

もちろん、原因などが特定できて仕事が終わったら、cronの中身は消しておこう。
※忘れがち

# あとがき
~~別に特殊なことは何もやっておらず、多分インフラエンジニアならよくやっているようなことをわざわざ書いてみた。~~
~~なぜかって・・・？俺がここからコピペで持っていきたいからさhahaha~~
~~※dateのエスケープのことよく忘れる~~
非常に恥ずかしい。私はまだまだ何も知らないお馬鹿さんだったようだ。。。精進せねば。