curlコマンドからネットワークを理解する 第一章: TCP/IP Protocol Suiteを理解する


# この記事の概要

`ネットってどうやって動いているんだろう?`

僕はwebアプリケーションエンジニア歴が3年くらいなのですが、3年前の始めたてのころはネットワーク上をhtmlファイルが飛んでくるものだと思っていました(笑)
OSやそもそものコンピューターの仕組みを少しは理解した今も、この単純な質問に自信をもって答えられません。

この疑問への答えをcurlコマンドからスタートし、追っていきます。

# はじめに抑えておきたいこと

色んなことに言えることなのですが、エンジニアの世界で`なにかが分からない`ときに、
そのなにかがそもそも複雑というのももちろんそうなのですが、
`そのなにかが目に見えない`という理由がすごく大きいと思っています。

実際に目で見て、触れて、試せるものを理解するのは比較的簡単ですが、
エンジニアが主に相手にするのは`1と0の世界、ビットの世界、情報の世界`で目に見えるものといえば、
CPU, メモリ, HDD, 流れる電気と記憶された磁気などなど、とても少ないです。

いま自分が分からないのは実装の話なのか、それとも仕様の話なのか、
物理的な話なのか、仮想的な話なのか、あるいは思想の話なのか、
`抽象`と`具象`の文脈をきっちり把握したほうが理解しやすいです。

今回の記事は、ネットの話なのでプロトコル(仕様)の話も出るには出るのですが、
それは色んな場所で説明されていてかつあんまりおもしろくもないので、
プロトコルはどこで実装されているのか、パケットはどう流れているのかなど、
実際に目で見て分かるようにしていきたいと思います。

# 目次

- 第一章: TCP/IP Protocol Suiteを理解する(この記事)
- [第二章: curlを追え! データ構造(パケットキャプチャ)とロジック(システムコール)からcurlを見る](https://qiita.com/Kohei909Otsuka/private/2743d40184453da6cf3f)
- 番外編: httpsを通じて暗号通信を理解する(comming soon)

# 第一章: TCP/IP Protocol Suiteを理解する

ざっくりとした全体像を説明します。
全体像を把握するのがまず大事だと思うからです。
それぞれのプロトコルの詳細を知りたい方は参考文献を参照してください。

## TCP/IP Protocol Suiteの意味

ネットワークで実現したいことは、コンピューター間の通信、つまりコミュニティケーションです。
相手に伝え、相手が言っていることを理解するには、お互いになにかしらの約束事を決めておく必要があります。

- 日本語
- UML
- メートル法
- Restful API & JSON

上記はその`なにかしらの約束事`の例です。
まったく同じことがコンピューター同士のコミュニティケーションでもいえます。

そしてプロトコルというのはこの`なにかしらの約束事`, つまり仕様です。
***仕様なので、あまり深く考えず、ふーんそういう風に頭のいい人達が決めたんだー、と素直に受け入れるのが大事です。***

HTTPプロトコルは`htmlなどのコンテンツを送受信するための仕様`
SMTPプロトコルは`メールの送信をするための仕様`
FTPプロトコルは`ファイルの転送をするための仕様`

などなど、目的に応じてプロトコルがたくさんあります。

そして TCP/IP Protocol Suiteというのは、メインのTCPプロトコル/IPプロトコルを軸に、
その周辺にあるプロトコル(HTTPなど)も含めた集合を指す言葉です。

ここで下記の2つの疑問から、もう少し深くみていきます。

1. プロトコルの集合を指すのはわかったが、それぞれのプロトコルはどのように関連しているのか?
3. プロトコルが仕様ということは、その実装はどこでされているのか?

## プロトコルの集合を指すのはわかったが、それぞれのプロトコルはどのように関連しているのか?

ここで大事なことは2つです

1. 上のレイヤーは下のレイヤーに依存している
2. 各レイヤーはパケットを共通のデータ構造とする

### 上のレイヤーは下のレイヤーに依存している

下記の図のように、TCP/IP Protocol Suiteの関連は表現できます。

![tcp_ip.jpg](https://qiita-image-store.s3.amazonaws.com/0/106693/c3d87647-bc03-3d85-edd5-1520a07ead8f.jpeg)


たとえばhtmlファイルを取得するにも、メールを送信するにも,ファイルを転送するにも,
`相手を特定する`ことが必要になります。そしてこの`相手を特定する`ことに関する仕様がIPプロトコルです。
このようにHTTP/SMTP/FTPはそれぞれがIPに依存しています。


### 各レイヤーはパケットを共通のデータ構造とする

下記の図のようにレイヤー間のやり取りは、そのままパケットの受け渡しとして表現できます。

![packet.jpg](https://qiita-image-store.s3.amazonaws.com/0/106693/4fc4855a-0a23-a151-1acd-fb3e4fe03da8.jpeg)


各レイヤーが、その役割に応じて情報を書き込み/読み込みをして、次のレイヤーに渡します。

この`パケット`というものを理解することで、ネットワークが理解できると思っています。
プログラムの基本である`データ構造`と`ロジック`でいえばデータ構造にあたるものがパケットです。
データ構造を理解すれば、ロジックもだいたいわかります。
(厳密にパケットというとIPパケットのことを指すようですが、ここでいっているのは図のようなデータ構造のことをいっています。)

## プロトコルが仕様ということは、その実装はどこでされているのか?

仕様があれば、実装もあるはずです。
下記の表にプロトコル/実装の関係があります。
Linuxを前提としています。

|プロトコル|実装しているもの/実装されている場所|
|----------|----------|
|TCP|OS|
|IP|OS|
|HTTP|Apache, Nginx, Google Chrome|
|SMTP|Postfix|
|FTP|vsftpd|
|TLS/SSL|openssl|

大事なことは、***OSはTCPプロトコル, IPプロトコルとそれより下のレイヤーしか実装していない***
ということだと思います。それより上のレイヤーは、OSにもともと実装されているわけではなく、
別々の/個別のソフトウェアとして実装されており、通常それを`yum`などでインストールすることで初めて使えるようになります。
`openssl`とか、なんとなく入れていたパッケージが実はこういう風につながってくるのが分かると思います。

# 参考文献

# 参考文献

[インフラ/ネットワークエンジニアのためのネットワーク技術&設計入門](https://www.amazon.co.jp/gp/product/4797373512/ref=oh_aui_detailpage_o08_s00?ie=UTF8&psc=1)
[ネットワークはなぜつながるのか 第2版 知っておきたいTCP/IP、LAN、光ファイバの基礎知識](https://www.amazon.co.jp/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AF%E3%81%AA%E3%81%9C%E3%81%A4%E3%81%AA%E3%81%8C%E3%82%8B%E3%81%AE%E3%81%8B-%E7%AC%AC2%E7%89%88-%E7%9F%A5%E3%81%A3%E3%81%A6%E3%81%8A%E3%81%8D%E3%81%9F%E3%81%84TCP-IP%E3%80%81LAN%E3%80%81%E5%85%89%E3%83%95%E3%82%A1%E3%82%A4%E3%83%90%E3%81%AE%E5%9F%BA%E7%A4%8E%E7%9F%A5%E8%AD%98-%E6%88%B8%E6%A0%B9/dp/4822283119/ref=sr_1_1?ie=UTF8&qid=1524129584&sr=8-1&keywords=%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%81%AF)
[マスタリングTCP/IP 入門編　第5版](https://www.amazon.co.jp/gp/product/B00MLUGZKG/ref=oh_aui_d_detailpage_o08_?ie=UTF8&psc=1)
[Eli The Computer Guy, Understanding Switches](https://www.youtube.com/watch?v=9yYqNqTNnqI&t=1186s)
[ネットワークエンジニアとして](http://www.infraexpert.com/)
[Linuxカーネルの基本機能](http://tech.nikkeibp.co.jp/it/article/COLUMN/20080501/300463/)