君は心理学者なのか?

大学時代に心理学を専攻しなぜかプログラマになった、サイコ(心理学)プログラマかろてんの雑記。

盗み聞きしてみた(コンテナ上のnginxプロセスと、ホスト間の通信パケットをtcpdumpでキャプチャしてみた〜CoreOS toolboxを使ってみる〜)

f:id:karoten512:20180112224543p:plain

パケットキャプチャとは

サーバさんたちがどんなおはなしをしているのか、

ぬすみぎきすることだよ(白目)

いきさつ

ホスト間とコンテナ上のnginxがどういう通信をしているのか気になった。

普通のサーバへの通信と変わらないのかな。

こういうときは実験だ。

盗み聞きまでの手順

nginxコンテナを起動

$ docker pull nginx:latest
$ docker run --name nginx_test -d -p 8080:80 nginx:latest

CoreOSにtcpdumpを入れる

qiita.com

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という仮想ブリッジを通した通信だ、ということくらいかな。