盗み聞きしてみた(コンテナ上のnginxプロセスと、ホスト間の通信パケットをtcpdumpでキャプチャしてみた〜CoreOS toolboxを使ってみる〜)
パケットキャプチャとは
サーバさんたちがどんなおはなしをしているのか、
ぬすみぎきすることだよ(白目)
いきさつ
ホスト間とコンテナ上のnginxがどういう通信をしているのか気になった。
普通のサーバへの通信と変わらないのかな。
こういうときは実験だ。
盗み聞きまでの手順
nginxコンテナを起動
$ docker pull nginx:latest $ docker run --name nginx_test -d -p 8080:80 nginx:latest
CoreOSにtcpdumpを入れる
CoreOS toolboxを使用すると、tcpdumpが使えるみたい。
盗み聞きする
Docker上で走っているコンテナとホスト間は、
docker0という仮想ブリッジでつながっている。
(ホスト上でifconfigをするとdocker0があることがわかるよ)
なのでdocker0を盗みぎきするNICに設定。
$ tcpdump -i docker0
結果
14:06:21.082183 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [S], seq 584948487, win 65535, options [mss 1460,nop,wscale 5,nop,nop,TS val 1315360133 ecr 0,sackOK,eol], length 0 14:06:21.082237 IP 172.18.0.6.http > 172.17.8.1.55248: Flags [S.], seq 636172623, ack 584948488, win 28960, options [mss 1460,sackOK,TS val 3302158741 ecr 1315360133,nop,wscale 7], length 0 14:06:21.083531 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [.], ack 1, win 4117, options [nop,nop,TS val 1315360133 ecr 3302158741], length 0 14:06:21.083662 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [P.], seq 1:587, ack 1, win 4117, options [nop,nop,TS val 1315360134 ecr 3302158741], length 586: HTTP: GET / HTTP/1.1 14:06:21.083677 IP 172.18.0.6.http > 172.17.8.1.55248: Flags [.], ack 587, win 236, options [nop,nop,TS val 3302158743 ecr 1315360134], length 0 14:06:21.083835 IP 172.18.0.6.http > 172.17.8.1.55248: Flags [P.], seq 1:181, ack 587, win 236, options [nop,nop,TS val 3302158743 ecr 1315360134], length 180: HTTP: HTTP/1.1 304 Not Modified 14:06:21.084186 IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [.], ack 181, win 4112, options [nop,nop,TS val 1315360134 ecr 3302158743], length 0
ちょっと見てみる。
パケット解析
3 way hand shake
サーバ同士でお話するときはいきなり話しかけない。
「ちょっとお話しませんか?」
「いいですよ。こっちもちょっと話していいですか?」
「いいですよ」
という紳士的なやり取りをして、はじめてお話が始まる。
それを
3 way hand shake
という。
↓ その痕跡がこれ
(1)IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [S] (2)IP 172.18.0.6.http > 172.17.8.1.55248: Flags [S.], ack (3)IP 172.17.8.1.55248 > 172.18.0.6.http: Flags [.], ack
ここで大事なのはFlags[S]とack。
(1)接続元が接続先に対して「ちょっとお話しませんか?」と聞いている
Flags [S]は、
SYN(コネクション確立要求)の先頭文字。
相手に対して、
「ちょっとお話しませんか?」と聞いてる感じ。
(2)接続先が接続元へ「いいですよ。私も話していいですか?」と聞いている
ack が「いいですよ」
S が「私も話していいですか?」
(3)接続元が接続先へ「いいですよ」いってる。
ack が「いいですよ」
この3つの過程を経て、ようやく通信ができるようになる。
GETリクエスト
IP 172.17.8.1.55248 > 172.18.0.6.http: (省略) HTTP: GET / HTTP/1.1
/ ディレクトリへアクセス。
確認応答
IP 172.18.0.6.http > 172.17.8.1.55248: Flags [.], ack 587
ここは勉強不足で、どこらへんが確認応答なのかわかっていない…
レスポンス
172.18.0.6.http > 172.17.8.1.55248: (省略) HTTP: HTTP/1.1 304 Not Modified
何度か通信していたので、取得したコンテンツが更新されていないことが確認できた。
まとめ
コンテナ - ホスト間の通信は、
普通のhttp通信と同じようにみえる。
違うのは、docker0という仮想ブリッジを通した通信だ、ということくらいかな。