シェルスクリプトマガジン

もしインターネットの1秒が1年だったら 第2回(vol.48掲載)

written by hakatashi・Mine02C4

編注:本記事は「SunPro 2016 技術書典」で発表された記事に説明・イラストを追加し、シェルマガvol.48に掲載したものです。
以下リンク先で、オリジナル版の全文が公開されています。
https://sunpro.io/techbookfest/

インターネットが日本中のあらゆる人間に行き渡るようになってから、すでに10年単位の時間が経過しています。今日においてインターネットを支えるネットワーク技術が重要であることは言うまでもありませんが、実際にネットワークでどのタイミングで何が起こり、どれくらいの時間が費やされるのかということを身を持って体感している人は、たとえネットワークに精通している人でも少ないのではないでしょうか? この記事では、1 秒というわずかな時間を1年にまで拡大し、ネットワーク上で何が起こっているかを人間スケールでざっくりと解説していきます。

はじめに

こんにちは。博多市(@hakatashi) です。前回に引き続き、2016年の技術書典にSunProとして発表した「インターネットの1秒がもし1年だったら」という記事を、シェルスクリプトマガジン向けに再構成してお届けします。この記事は、インターネット通信においてクライアントがサーバーとコミュニケーションする様子を、1秒を1年にというスケールに引き伸ばし、クライアントとサーバーをそれぞれ「クライアントちゃん」と「サーバーちゃん」として、人間スケールに置き換えて順に見ていこうという企画です。
前回の記事では、クライアントがサーバーと通信するための前段階として、サーバーの住所を調べる、つまりIPアドレスを問い合わせる名前解決までの処理を解説しました。3回のDNSリクエストの末にサーバーちゃんの住所をゲットしたクライアントちゃんは、いよいよサーバーちゃんとの直接の通信を行っていきます。果たしてサーバーちゃんとクライアントちゃんの文通の行方はどうなるのでしょうか。引き続きお楽しみください。

サーバーちゃん   クライアントちゃん

 

TCP接続ハンドシェイク

2月19日 午後3時27分 TCPハンドシェイク+SYNパケット送信

各地のネームサーバーの協力を得て、無事サーバーちゃんの住所を入手したクライアントちゃんですが、お淑やかなクライアントちゃんはいきなり本題の手紙を送りつけるような真似はしません。まずはサーバーちゃんにご挨拶をします。
 TCP上の通信では、データ伝送を行う前にコネクションの確立という処理を行う必要があります。これは、相手のサーバーが通信可能な状態であることを保証したり、以降のデータが正しい順序で到着することを保証するためのシーケンス番号を互いに交換したりするためです。
 シーケンス番号とは、現在のパケットが送信しているデータが、全体のデータのうちのどの部分に該当するのかを示す値であり、ハンドシェイクで最初にランダムな値にセットされ、以降データを送信するごとに増加していく値です。TCPは双方向通信なので、このシーケンス番号はサーバーとクライアントで別々の値を保持しています。
 クライアントちゃんはランダムに生成したシーケンス番号を端に添えて、サーバーちゃんに文通してよいかを問う内容の手紙を作りました。色よい返事が返ってくることを期待して、再びポストに投函しました。手紙はいよいよ石狩に向かいます。
 ところで、サーバーちゃんの住所が判明してから最初にサーバーちゃんにコンタクトをとるまで9日もかかっています。
きっとバのつくイベントで忙しかったのでしょう。妬ましい。

*1 実際の理由はおそらくローカルホストのDNSサーバーからアプリケーション(curl)にDNS情報を受け渡す際にオーバーヘッドが発生するためです。

2月27日  午後6時30分 TCPハンドシェイク+SYNパケット受信

北海道――新千歳空港から車で50分の石狩の大地に、目的のデータセンターは存在します。冬の北海道の空気は冷たく厳しく、この時期の気温は昼間でも0度を上回ることはありません。この冷涼な外気がサーバールームから効率的に排熱するのです。
すぐ脇を通る道は国道337号線です。地元ではかつて天売島に住んでいた鳥の名前からとって「オロロンライン」と呼ばれるこの道は、眼前に手稲山を望むゆったりとした広い道路です。小樽からこの道を進んで左手側、空港のターミナルを髣髴とさせる白い横長な建物が石狩データセンターです。
この場所でサーバーちゃんは他のサーバーと肩を並べて*2、静かに443番ポートを開けて待ち続けています。  今回キャプチャしたパケットの中で最も数が多かったのはARPのパケットでした。512台*3近い数のサーバーがARPで常に囁きあい、互いの居場所を確認しあっている状態といえるかもしれません。
そんな退屈な生活の中で、サーバーちゃんはクライアントちゃんからの手紙を受け取りました。
クライアントちゃんが手紙を投函してから8日目のことです。伝送には22ミリ秒かかりました。
冒頭では東京と石狩の物理的な片道時間は5.9ミリ秒と述べましたが、当然これは理想的な通信のことであり、実際には無線通信やルーティングなどにおけるオーバーヘッドによってそれ以上の時間がかかります。
受け取った手紙は一般的なTCPハンドシェイクでした。手紙にはシーケンス番号が添えられています。クライアントちゃんからの久しぶりの手紙に喜んだサーバーちゃんは、喜んで通信を受け入れました。

*2 もちろんVPSなので物理的なサーバーマシンとして存在しているわけではありませんが。
*3 今回使用したサーバーはサブネットマスク23ビットという中途半端な値のネットワークに繋がっていました。今回も、クライアントちゃんとサーバーちゃんの通信の始まりです。

 

2月27日  午後8時11分 TCPハンドシェイクSYN+ACKパケット送信

サーバーはTCPによる通信を受け入れた証として、クライアントからのSYNパケットに対する応答を返します。サーバーはクライアントから受け取ったシーケンス番号を認識し、これに1を加えた値を返答パケットに記して送ります。シーケンス番号は送信するデータの先頭バイトを表すので、本来はデータを送信しない段階では加算しないのですが、ハンドシェイクにおいてはパケットを正しく受け取った印として特別に1を加算します。

同時に、サーバー側でもシーケンス番号を生成して返信用のパケットに記します。これでサーバーとクライアントの間で一対のランダムなシーケンス番号が初期化されます。

サーバーちゃんはクライアントちゃんに向けて通信可能な旨を記した手紙を書きました。クライアントちゃんからの手紙と同じく、隅っこにシーケンス番号を記しておきます。このパケットはSYNとACKのフラグが立てられているため、SYN+ACKパケットなどと呼ばれます。

3月9日  午前3時43分 TCPハンドシェイクSYN+ACKパケット受信

今度は石狩から東京へと手紙が運ばれます。配達にはふたたび10日近い時間を要しました。
クライアントちゃんにとってはサーバーちゃんからの初めての手紙です。だいぶ非常識な時間に配達された手紙ですが、クライアントちゃんは飛び起きて、サーバーちゃんからの手紙をじっくり読み、さっそく返事に取りかかりました。
クライアントは、サーバーからのハンドシェイクを受け取ると、先ほど説明したシーケンス番号の他に、Window Size  ValueやMaximum Segment SizeなどのTCP通信に必要な値を確認し、記録しておきます。

3月 9日 午前4時5分 TCPハンドシェイクSYN+ACKパケット送信

サーバーちゃんからの手紙で、サーバーちゃんが手紙を出せる状態であることを確認したクライアントちゃんは、その手紙に問題がないことを伝えるため、ハンドシェイクを完了させる手紙を送ります。
クライアントもサーバーと同じく、シーケンス番号を認識した証として、サーバーから送られたシーケンス番号に1を加えて返答します。このパケットにより両者の間でそれぞれのシーケンス番号が共有され、お互いにデータを送り合う事ができるようになります。

3月16日  午後3時21分 TCPハンドシェイクSYN+ACKパケット受信

ふたたび手紙は東京から石狩へ。サーバーちゃんはクライアントちゃんからちゃんと返事が届いたことにほっと安心しました。これで、いつでも通信を受け入れることができます。
このように、TCPのハンドシェイクでは通信路を3 回通る必要があるため、3ウェイ・ハンドシェイクとも呼ばれます。

TSLハンドシェイク

 

TLSハンドシェイクが終わって、クライアントちゃんとサーバーちゃんは無事通信が開始できるようになりました。クライアントちゃんはさっそく本題の質問を投げかけようと思ったのですが、ここでふと思ったことがあります。
クライアントちゃんとサーバーちゃんは、ハガキを使って互いにやり取りをしています。ハガキには特に何も細工をしていないので、書いている内容は周りの人には丸見えです。クライアントちゃんがポストに投函しに行くまではいいとしても、そこから先、ルーターから先のことに関しては何も保証できません。実はポストの中に盗撮カメラが仕掛けてあるかもしれませんし、郵便局員がハガキの内容をチラ見するかもしれませんし、サーバーちゃんの上司に内容を検閲されているかもしれません。
これは困ります。花も恥じらう乙女であるところのクライアントちゃんは、サーバーちゃん以外の誰にも手紙の内容を知られたくありません。クライアントちゃんはサーバーちゃんとのやり取りを暗号化するため、TLS(Transport Layer Security)を使用することにしました。
TLSは、TCPのようなコネクションの上で暗号技術を使って通信の機密性や完全性を確保するための仕組みです。公開鍵暗号を用いて安全に交換した鍵を使って共通鍵暗号を行い、暗号化されたコネクションをアプリケーションに提供します。
この記事は暗号理論の説明はいたしません。ちょこちょこ出てくる用語の説明はほとんどしていません。なので、やり取りする情報のさらなる意味を知りたい方は、ぜひ他の専門書を参照してください。