【技術書まとめ】パケットキャプチャの教科書

ネットワークの本を4冊ほど読んで概要がわかってきたので、さらに実際のデータや実装などを知るために読んでみた。自分の言葉で要点部分だけまとめた。

# はじめに

- ネットワークは無数のパケットが光の速度で行き交うひとつの世界
- ネットワークは基盤となる部分がしっかりしている
    - サーバーやアプリケーションと比較して、急激に変化することがない


# パケットキャプチャの流れ

- パケットキャプチャとは
    - ネットワーク上を流れるパケットを「パケットキャプチャツール」で取得すること
- どんなときにパケットキャプチャするの？
    - 試験フェーズでのパケットキャプチャ
        - 失敗の原因を追求しやすくする
    - 運用管理フェーズでのパケットキャプチャ
        - トラブル対応に役立つ
- パケットキャプチャの流れ
    - 「基本情報の収集」→「事前準備」→「パケットキャプチャの実施」→「パケット解析」という4ステップで構成されている
    - Step1: 基本情報の収集
        - どんなネットワークにあるどんな端末のパケットをキャプチャしたいのか全体を把握する
    - Step2: 事前準備
        - パケットキャプチャツールの検討
            - Wireshark, tcpdump, Microsoft Message Analyzer
        - 手法の検討
            - パケットキャプチャ端末自身がやり取りしているパケットをキャプチャする
                - 端末自身が持っているNIC（Network Interface Card）を通過するパケットをソフトウェア的にインターセプト（傍受、盗み見）して、キャプチャする
                - キャプチャする際にフィルタ条件を指定して処理負荷を軽減する
            - パケットキャプチャ端末とは別の端末が端末がやりとりしているパケットをキャプチャする
                - リピーターハブ
                    - パケットをキャプチャしたい機器の間にリピーターハブを挿入する
                - ミラーポート
                    - 指定したポートでやりとりしているパケットを別のポートにリアルタイムにコピーする
                    - スイッチの一機能でキャプチャ端末に流しこめ、サービスへの影響もないため、こちらがよく使われる
            - 時刻を合わせる
            - キャッシュのクリア
            - パケットキャプチャ端末の設置位置の確認
                - パケットキャプチャ端末を設置していいのか
    - Step3: パケットキャプチャの実施
        - パッファを大きくして溢れないようにするなど
    - Step4: パケット解析
        - 「いろいろな条件で表示をフィルタ」 → 「気になるパケット・パケットシーケンスをピックアップ」 → 「パケットの中身を精査」を何度も繰り返す



## chapter:2 Wiresharkの使い方

- 実際の現場では、きっと鼻血が飛び出るほどの大量のパケットを見ることになるでしょう
- プロミスキャス
    - 受け取ったパケットをすべて取り込んで処理するNICの動作モード
        - 無効化すると、自分に関係のあるパケット（自分自身のMACアドレスを宛先としたデータ、ブロードキャスト、マルチキャストの3種類）しかキャプチャしなくなる
- キャプチャするパケットをフィルタする「キャプチャフィルタ」と、パケット一覧に表示するデータをフィルタする「表示フィルタ」がある
- キャプチャフィルタ
    - キャプチャフィルタの基本構文
        - プロトコルを表す「プロトコル名」、送信元/宛先を表す「ディレクション」、IPアドレスやネットワーク、ポート番号を表す「タイプ」、値を表す「値」の4つで構成されている
    - 表示フィルタ
        - 表示フィルタの基本構文
            - プロトコルやサブカテゴリの「フィールド名」、フィールド名と値の関係性を表す「リレーション」、フィールドの値や文字列を表す「値」の3つで構成されている




## chapter3: レイヤー2プロトコル
- データリンク層（レイヤー2、L2、第２層）は、不器用な物理層の弱点を補完しているレイヤー
    - 送信側の物理層はデータから信号に変換するときに、ちょっとした処理（符号化）を施しているので、受信側の物理層も多少のエラー（ビット誤り）であれば訂正できるが、複雑なエラーはお手上げだから
    - 　現代のレイヤー２プロトコルは、有線LANなら「Ethernet」、無線LANなら「IEEE802.11」のどちらかしかない
- Ethernet
    - [帯域幅]BASE-[ケーブルの種類]
    - Ethernetプロトコルの詳細
        - ここを流れるパケットは「Ethernetフレーム」という
        - 1982年にDEX（デック）、Intel（インテル）、Xerox（ゼロックス）が発表した独自規格「EthernetⅡ」（頭文字を取ったDIX2.0規格とも呼ぶ）がTCP/IPデータパケットのほとんどを占める
            - IEEEが標準化したIEEE802.3はほとんど使われていない
        - EthernetⅡのフレームフォーマット
            - 「プリアンブル」「宛先/送信元MACアドレス」「タイプ」「Ethernetペイロード」「FCS」という5つのフィールドで構成されている
                - 宛先/送信元MACアドレスとタイプを合わせて「Ethernetヘッダー」という
                - プリアンブル
                    - 「これからEthernetフレームを送りますよー」という合図を意味する8バイトの特別なビットパターン
                - 宛先/送信元MACアドレス
                    - 端末を表す6バイトの識別ID
                - タイプ
                    - ネットワーク層（レイヤー3、L3、第３層）でどんなプロトコルを使用しているかを表す2バイトの識別ID
                        - IPv4だったら「0x0800」など
                - Ethernetペイロード
                    - 上位層のデータそのもの
                        - 46バイト以下ならパディングを入れて、1500バイト以上なら分割する
                    - データの最大サイズのことを「MTU（Maximum Transmission Unit）」という
                - FCS（Frame Check Sequence）
                    - Ethernetペイロードが壊れていないかどうかを確認するためにある4バイトのフィールド
                        - 送信側でチェックサム計算を行い付加して、受信側が同じ計算をして照合する
                        - Ethernetのエラー制御のすべて
                        - フレーム長として換算されない
                - MACアドレス
                    - NICを製造するときにROM（Read Only Memory）に書き込まれる48ビットを16進数で表示したもの
                    - 先頭から8ビット目は「I/Gビット（Individual/Group ビット）」で、7ビット目は「U/Lビット（Unique/Localビット）」
                        - I/Gビットは１：１のユニキャストアドレスか、1:nのマルチキャストアドレスかを表す
                        - U/Lビットはグローバルアドレスかローカルアドレスかを表す
                            - 「0」の場合は、IEEEから割り当てられた世界で唯一のMACアドレス
                            - グローバルMACアドレスなら、上位24ビットは、IEEEがベンダーごとに割り当てたベンダーコードで「OUI（Organizationally Unique Identifier）」と呼ばれる
                            - 下位24ビットは各ベンダーが割り当てたシリアルコード
        - ３種類のMACアドレス
            - ネットワークの通信の種類は「ユニキャスト」「ブロードキャスト」「マルチキャスト」の3つしかない
            - ユニキャスト
                - 1:1の通信で、インターネット通信のほとんどはこれ
            - ブロードキャスト
                - 1:nの通信でそのネットワークのすべての端末に送信する
            - マルチキャスト
                - 1:nの通信で、nは特定のグループ
                - 主に動画配信や証券取引系のアプリケーションで使用される
    - Ethernetのフレームの解析
        - レイヤー2スイッチングの処理はどう見えるか
            - LANポートをたくさん搭載した機器
            - PC1がPC2にEthernetフレームを送ると、L2スイッチがPC1以外すべてにフラッディングして、PC2はPC1に返答し、PC３は破棄し、L2スイッチはPC2のMACアドレスとポート番号を自身のMACアドレステーブルに登録する
            - PC1とPC2が一定時間（5分など）通信しなくなると、L2スイッチは関連行を削除する
        - VLANタグはどう見えるか
            - VLANは1台のL2スイッチを仮想的に複数のL2スイッチのように見せかける技術
            - ポートVLANは1ポートに1つのVLANを割り当て、VLAN1とVLAN2は通信できない
            - タグVLANは1ポートでマルチVLAN
                - VLANタグがくっついているフレームは「IEEE802.1q」
                - 送信元MACアドレスとタイプの間に「TPID（Tag Protocol Identifier）」と「TCI（Tag Control Information）」が差し込まれる
                    - TPIDには必ずIEEE802.1qフレームであることを表す「0x8100」という値が入る
                    - TCIは「PCP（Priority Code Point）」、「CFI（Cannonical Format Indicator）」、VLAN IDが入る「VID」の3つで構成される
                - VLANタグの分（4バイト）だけフレームサイズが大きくなるので、「ジャンボフレーム」という
        - ブリッジングループはどう見えるか
            - Ethernetにはループを制御するフィールドがない
            - 1台のスイッチに複数のリンクができている状態で「ブロードキャストストーム」が起こる
- PPPoE
    - Ethernetは類まれな汎用性により、いろいろな形で拡張されている
    - PPPプロトコルの詳細
        - ポイントとポイント（Point-to-Point）を「データリンク」という論理的な通信路で1:1につなぐためのレイヤー２プロトコル
            - ダイヤルアップ接続などで使用されていた
        - PPPのフレームフォーマット
            - データリンク層に関する機能を制御する、「LCP（Link Control Protocol）」と、ネットワーク層に関する機能を制御する、「NCP（Network Control Protocol）」という2つのプロトコルで構成されている
        - PPPの接続処理プロセス
            - 「PAP（Password Authentication Protocol）」認証はIDもパスワードもクリアテキストで流れるため、チャレンジ値を混ぜてハッシュ化する「CHAP（Challenge Handshake Authentication Protocol）」のほうが安全
    - PPPoEプロトコルの詳細
        - PPPoEは、PPPフレームをEthernetでカプセル化しているので、データリンク層で実質2回カプセル化していることになる
        - PPPoEは「ディスカバリーステージ」と「PPPセッションステージ」という2つのステージを踏む
        - PPPをEthernetでカプセル化
            1. PPPoEクライアントは「PADI（PPPoE Active Discovery Initiation）」をブロードキャスト送出してPPPoEサーバーを探す
            1. PPPoEサーバーは「PADO（PPPoE Active Discovery Offer）」で応答する
            1. PPPoEクライアントは、「PADR（PPPoE Active Discovery Request）」でPPPoEセッション開始をお願いする
            1. PPPoEサーバーは、「PADS（PPPoE Active Discovery Session-confirmation）」でセッションIDを通知する
            1. PPPセッションステージへ移行する
- ARP（Address Resolution Protocol）
    - 物理的な「MACアドレス」と論理的な「IPアドレス」を使う、データリンク層とネットワーク層の架け橋となるプロトコルが「ARP（Address Resolution Protocol）」
    - ARPプロトコルの詳細
        - 宛先IPアドレスを持っているだけでは宛先MACアドレスがわからないので、ARPで宛先IPアドレスから宛先MACアドレスを求める
        - ARPのフレームフォーマット
            - ハードウェアタイプ
                - Ethernetの場合「0x0001」
            - プロトコルタイプ
                - IPの場合「0x0800」
            - ハードウェアアドレスサイズ
                - MACアドレスは48ビット=6バイトなので「6」が入る
            - プロトコルアドレスサイズ
                - IPv4アドレスの長さは32ビット=4バイトなので「4」が入る
            - オペレーションコード（オプコード）
                - ARP Requestは「1」、ARP Replyは「2」
            - 送信元MACアドレス/IPアドレス
            - 目標MACアドレス/IPアドレス
                - 最初はMACアドレスはわからないので、ダミーの「00:00:00:00:00:00」を入れる
    - ARPフレームの解析
        - ARPの基本的な動作はどう見えるか
            - 「〇〇さんはいますかー？」と大声で聞いて、〇〇さんが「私でーす！」と返す、病院の待合室的な様子
            - ブロードキャストとユニキャストを駆使する
                1. PC1は、まず自身の「ARPテーブル」を検索する（見つかれば6に進む）
                1. オプコードをARP Requestの「1」にする。IPアドレスがVLANの場合はそのまま目標IPアドレスとして使用し、異なるネットワークの場合は、そのEthernetネットワークの出口となる「デフォルトゲートウェイ」を目標IPアドレスとして使用する。宛先MACアドレスにダミーを入れて、ブロードキャストでカプセル化して送る
                1. 同じVLANにいる端末すべてに行き渡る。アドレス解決対象と関係ない端末（PC3）はARPフレームを破棄する
                1. PC2は、オプコードをARP Replyの「2」にする。ユニキャストでカプセル化して送る
                1. PC1はPC2を認識して、MACアドレスとIPアドレスをARPテーブルに書き込む
                1. PC１はアドレス解決したMACアドレスで通信を開始する
        - IPアドレスの重複検知はどう見えるか
            - ARPは「IPアドレスの重複検知」や「冗長構成時におけるMACアドレスてテーブルの更新」などの役割もある
            - 重複検知はARP Requestで、「このIPアドレスを使ってもいいですか？」とブロードキャストで聞くこと





## chapter: 4 レイヤー3プロトコル
- ネットワーク層（レイヤー3、L3、第３層）はEthernetで作ったネットワークをつなげて、異なるネットワークにいる端末との通信を確保するためのレイヤー
- IP（Internet Protocol）
    - IPプロトコルの詳細
        - 狭義のパケットとは、「IPヘッダー」と「IPペイロード」で構成されるIPパケットのこと
        - IPのパケットフォーマット
            - 世界中の野を越え山を越え、環境の差を吸収しながら通信できるように、たくさんのフィールドで構成されている
            - バージョン
                - IPv4だったら「4」（2進数表記で「0100」）
            - ヘッダー長
                - どこまでがIPヘッダーかわかる
                - 基本的に20バイト（160ビット=32ビットx5）
                    - 32ビット換算した値が入る
            - ToS（Type of Service）
                - IPパケットの優先度を表す
                - 有線制御や帯域制御などQoS（Quality of Service）で使用する
                - 先頭3ビットを「IPプレシデンス」、先頭6ビットを「DSCP（Diffserv Code Point）」という
                - IPプレシデンス
                    - 値ごとに用途が決められている
                - DSCP
                    - IPプレシデンスのパワーアップバージョン
                    - 先頭6ビットを使用するので、10真数では0〜63までの64段階で細やかに定義できる
                    - DSCPは64段階の好きな値を設定できるが、秩序が保てなくなるので、ルータごとの転送動作（PHB、Per Hop Behavior）に合わせた基本名と値が決められている
                        - 「EF（Expedited Forwarding、完全有線転送）」「AF（Assured Forwarding、相対的優先転送）」「CS（Class Selector）」「デフォルト」の4種類が定義されている
                        - EF
                            - 絶対優先のPHB
                            - VoIP（音声パケット）などで使用する
                            - DSCP値は「46」（10進数）のみ
                                - IPプレシデンスの値の「5」に対応する
                        - AF
                            - EFほどではないが優先的に処理するPHB
                            - 4つのクラスと3つの破棄確率でできている
                        - CS
                            - CSはIPプレジデンスとの下位互換を確保するためにあるPHB
                            - DSCPを認識できない端末のためにある
                            - 上位3ビットはそのままIPプレジデンス値
                        - デフォルト
                            - デフォルトPHBは、ベストエフォートサービスのためのPHBで、すべての値が「0」
            - パケット長
                - どこまでがIPパケットなのかわかる
                - MTUいっぱいなら「1600」（16進数で「05dc」）
            - 識別子
                - 「フラグメンテーション（断片化）」に関連するフィールド
                    - フラグメントされていることがわかる
                - フラグメントされると、フラグメントパケットは同じ識別子をコピーして持つ
            - フラグ
                - 3ビットで構成されていて、1ビット目は使用しない
                - 2ビット目は「DFビット（Don't Fragmentビット）」
                    - 処理遅延を考慮して上層でデータサイズを調整することもある
                - 3ビット目は「MFビット（More Fragmentsビット）」
                    - フラグメントされたIPパケットが後ろに続くかどうか表す
            - フラグメントオフセット
                - オリジナルのIPパケットの先頭からどこに位置しているかを表す
                    - 1500バイトのパケットが先頭から976バイトでフラグメントされた場合、1つ目のパケットのフラグメントオフセットには「0」、2つ目のパケットのフラグメントオフセットには「976」が入る
                - 先頭からのバイト数を見て、正しい順番に並べ替える
            - TTL（Time To Live）
                - パケットの寿命
                - TTLが0になったら、TTL ExceededのICMPパケットを返す
                - 「ルーティングループ」の防止
                    - EthernetにはTTLの概念がないが、IPパケットはどこかで破棄される
            - プロトコル番号
                - IPペイロードがどんなプロトコルで構成されているか表す
            - ヘッダーチェックサム
                - 「1の補数演算」という計算方法
                1. IPヘッダーを16ビットずつ区切って、ヘッダーチェックサムを取り除く
                1. 区切った値を合計する
                1. 16ビット超えた部分を取って、足し合わせる
                1. ビットを反転する
            - 送信元/宛先IPアドレス
                - 「IPアドレス」はIPネットワークにおける住所
        - IPアドレス
            - IPアドレスは、IPネットワークに接続された端末の識別ID
            - 8ビット（オクテット）ずつ区切られた32ビットで構成されている
            - IPアドレスは、「サブネットマスク」とセットで機能する
                - 「ネットワーク部」と「ホスト部」の2つ
                - サブネットマスクは区切りの目印
                    - 「1」のビットがネットワーク部、「0」のビットがホスト部
                - 「10進数表記」と「CIDR表記」がある
                    - 「192.168.100.1」というIPアドレス
                        - 「255.255.255.0」が10進数表記
                        - 「192.168.100.1/24」がCIDR表記
        - IPアドレスは用途に応じて分類する
            - IPアドレスは、「0.0.0.0」〜「255.255.255.255」まで、2の32乗の約43億個ある
                - ICANNと下部組織が管理している
            - 使用用途による分類
                - クラスAからクラスEまでネットワーク規模で分けられている
            - 使用場所による分類
                - 「グローバルIPアドレス」と「プライベートIPアドレス」
                    - プライベートIPアドレスは「NAT（Network Address Translation）」で変換する
            - 端末には設定できないアドレス（除外アドレス）
                - ネットワークアドレス
                    - ホスト部のビットがすべて「0」のIPアドレス
                        - 「192.168.1.1」であれば「192.168.1.0」（サブネットマスクが「255.255.255.0」の場合）
                    - 「ネットワークそのもの」を表す
                - デフォルトルートアドレス
                    - IPアドレス、サブネットマスクともにすべて「0」
                        - 「0.0.0.0」
                    - 「すべてのネットワーク」を表す
                - ブロードキャストアドレス
                    - ホスト部のビットがすべて「1」
                        - 「192.168.1.1」であれば「192.168.1.255」（サブネットマスクが「255.255.255.0」の場合）
                    - 「そのネットワークにある全端末」を表す
                - ループバックアドレス
                    - 第一オクテットが「127」
                        - 「127.0.0.1/8」を使用するのが一般的
                    - 「自分自身」を表す
    - IPパケットの解析
        - ルーティングの処理はどう見えるか
            - IPで動作する機器はなんと言っても「ルータ」か「レイヤー3スイッチ」
                - 異なるEthernetネットワークをつなぐ機器
                - ルータは「宛先ネットワーク」とIPパケットを、「ネクストホップ」を管理して転送する
                    - 転送先を切り替える機能を「ルーティング」という
                    - 宛先ネットワークとネクストホップを管理するテーブルを「ルーティングテーブル」という
                    - ルータではルーティングテーブルとARPテーブルが重要
            - 宛先ネットワークとネクストホップを管理する
                1. PC1は宛先IPアドレスにPC2のIPアドレスをセットして、IPヘッダーでカプセル化し、自身のルーティングテーブルを検索する。「192.168.2.1」にドンピシャで該当する宛先ネットワークはない。だが、「192.168.2.1」はすべてのネットワークを表すデフォルトルートアドレス（0.0.0.0/0）にマッチする。今度は、デフォルトルートアドレスのネクストホップのMACアドレスをARPテーブルから検索すると、R1(e0/0）だとわかる。宛先MACアドレスにR1（e0/0）をセットして、Ethernetでカプセル化し、ケーブルに流す。
                    - デフォルトルートのネクストホップのことを「デフォルトゲートウェイ」という。端末は不特定多数のサイトにアクセスするとき、とりあえずデフォルトゲートウェイにIPパケットを送信し、あとはデフォルトゲートウェイの機器にルーティングを任せる
                1. R1は自身のルーティングテーブルを検索する。宛先IPアドレスは「192.168.2.1」なので、ルーティングテーブルの宛先ネットワーク「192.168.2.0/24」とマッチする。今度は、「192.168.2.0/24」のネクストホップ「192.168.12.2」のMACアドレスをARPテーブルから検索する。「192.168.12.2」のMACアドレスはR2（e0/0）とわかるので、セットしてEthernetでカプセル化し、ケーブルに流す。
                1. R2もルーティングテーブルを検索する。宛先IPアドレスの「192.168.2.1」は宛先ネットワーク「192.168.2.0/24」とマッチする。今度は直接接続された「192.168.2.1」のMACアドレスをARPテーブルから検索する。「192.168.2.1」のMACアドレスはPC2(eth0）なので、セットしてEthernetでカプセル化し、ケーブルに流す。
                1. PC2は、データリンク層で宛先MACアドレス、ネットワーク層で宛先IPアドレスを見て、パケットを受け入れて上位層へ処理を引き渡す
        - ルーティングループはどう見えるか
            - IPパケットが複数のルータを伝って、ぐるぐる回る現象を「ルーティングループ」という
                - TTLによって自動的にストップがかかる
            - ルートの設定間違いがルーティングループの始まり
- IPsec
    - IPsecとは
        - 「IPsec（Security Architecture for Internet Protocol）」
            - IPsecVPNなどで使用される
    - IPsecプロトコルの詳細
        - IPsecは「ISAKMP(Internet Security Association Key Management Protocol）」、「ESP（Encapsulation Security Payload)」、「AH（Authentication Header）」という3つのプロトコルを組み合わせて、VPNを作るために必要な機能を提供する
        - 2つの事前準備フェーズでSAを作る
            - IPsecが作る仮想的な専用線（トンネル）を「SA（Security Association）」という
            - 「フェーズ1」と「フェーズ2」がある
                - フェーズ1
                    - ISAKMPを使用して、対向機器やメッセージを認証する
                    - フェーズ２の暗号化で使用する暗号鍵を共有する
                - フェーズ2
                    - ISAKMPを使用して「ISAKMP SA」という制御用のSAを作る
                    - 実際のやりとりはフェーズ2の後にできる「IPsec SA」で暗号化して行う
        - ISAKMPのパケットフォーマット
        - ESPのパケットフォーマット
            - IPsec SAで使用するカプセル化モードとプロトコル
                - カプセル化モードには、「トンネルモード」と「トランスポートモード」がある
                    - トンネルモードはオリジナルのIPパケットを新しいIPヘッダーでカプセル化するモード
                - IPsec SAで使用するプロトコルには、「ESP」と「AH」がある
                    - 「AH」には暗号化機能がない
                - 日本国内でIPsec VPNするときは、「ESPのトンネルモード」一択
            - トンネルモードでカプセル化したときのESPのパケットフォーマット
                - トンネルモードのESPは、暗号化とカプセル化の2段階
    - IPsecパケットの解析
        1. PC1からR1にIPパケットを送信
        1. R1はIPパケットのIPアドレスから、暗号化対象リストを検索する。マッチしたらフェーズ1の処理を開始する。
            1. SAパラメータや各種拡張機能のネゴシエーション
                - SAパラメータは、「暗号化アルゴリズム（AES）」「ハッシュアルゴリズム（SHA）」「ライフタイム」など
                - イニシエーターR1「このパラメータでどうですか？」に対し、レスポンダーR2「このパラメータで鍵交換しましょう！」
        1. SAパラメータが確定したら、ISAKMP SAで使用する共通鍵の素を交換する
            - 鍵の共有には「DH（Diffie-Hellman）鍵共有」というアルゴリズムを使う
                - DHグループという素数とジェネレータを使う
            - まず公開鍵を計算して、互いに送信しあう
            - 次に受診した相手の公開鍵と素数、乱数から共通鍵を計算する
                - 素数=13、生成元=2、R1が生成する乱数（乱数X）=9、R2が生成する乱数（乱数Y）=7なら、共通鍵「8」を共有できる
        1. [2]で確定させた暗号化アルゴリズム、[3]で生成した共通鍵を使って、暗号化通信とメッセージ認証を開始する
            - R1はSHAなどのハッシュ関数と、[3]で生成した共通鍵を使用して、メッセージのハッシュ値を算出し、ペイロードに含める
            - R2は同じ計算をしてハッシュ値を比較し、改ざんされていないか確認する
                - これがメッセージ認証
            - 相手を識別するID（事前共有鍵認証ではIPアドレス）も確認する
                - これが対向認証
        1. ここからフェーズ2、別名「クイックモード」。認証に成功したら、暗号化通信とメッセージ認証を施したISAKMP SAを使用して、今度はIPsec SAのためのSAパラメータやID、ハッシュ値を交換する。交換し終わったら、最後にハッシュ値を検証して、上り通信用と下り通信用の2本のIPsec SAができ上がる
        1. クイックモードが終了したら、ESPの出番。R1は[5]で作った共通鍵を使用して、オリジナルのIPパケット（[1]のパケットをESPでカプセル化・ハッシュ化・暗号化の処理を行う。R2も[5]で作った共通鍵を使用して非カプセル化・認証・復号の処理を行う
        1. R2はPC2に対してオリジナルのIPパケットを送信する。これは純粋なルーティング処理。これでPC1からPC2へ通信できた。
- ICMP（Internet Control Message Protocol）
    - ICMPとは
        - IPレベルの通信状態を確認したり、いろいろなエラーを通知したりできる
            - pingはICMPパケットを送信するときに使用するネットワーク診断コマンド
    - ICMPプロトコルの詳細
        - どんなネットワークでもIPとICMPは必ずセットで実装されていなければならない（RFC792)
        - ICMPのパケットフォーマット
            - ICMPは、IPにICMPメッセージを直接詰め込んだ、プロトコル番号「1」のIPパケット
            - メッセージの最初にある「タイプ」と「コード」が重要
    - ICMPパケットの解析
        - タイプとコードに着目する
        - 通信状態を確認するときはEcho RequestとEchoReply
            - pingコマンドを打つと、ICMPパケットが送信される
                - ネットワーク層レベルの疎通が確認できる
            - Echo Requestのパケットフォーマット
                - タイプが「8」、コードが「0」のICMPパケット
            - Echo Replyのパケットフォーマット
                - タイプが「0」、コードが「0」のICMPパケット
        - ルーティングできなかったときはDestination Unreachableを返す
            - Destination Unreachableの挙動はメーカーによってまちまち
        - 別のゲートウェイを伝えるときはRedirectを返す
            - 送信元端末に対して、適切なゲートウェイアドレスを通知する
            - コードはRFC792やRFC1812でも詳細に定義されていない
                - メーカーによってまちまち
        - TTLがゼロになったらTTL Exceededを返す
            - これを利用して通信経路を確認するプログラムが「traceroute」



## chapter: 5 レイヤー4プロトコル

- トランスポート層（レイヤー4、L4、第４層）はネットワークとアプリケーションをつなぐ架け橋
- UDP（User Datagram Protocol）
    - 即時性を求めるアプリケーションで使用する
    - UDPプロトコルの詳細
        - UDPのパケットフォーマット
            - シンプルなデータグラムをどんどん送るだけ
                - サーバーは、ヘッダー長とチェックサムでデータが壊れていないかチェックする
            - 送信元/宛先ポート番号
                - 送信元ポート番号はOSがランダムに割り当てた値
            - UDPデータグラム長
                - UDPヘッダー（8バイト）とアプリケーションデータを合わせたサイズ
            - チェックサム
                - IPヘッダーと同じ、「1の補数演算」が採用されている
        - ポート番号
            - レイヤー4プロトコルで最も重要なフィールドが、「送信元ポート番号」と「宛先ポート番号」
                - UDPもTCPも、まずはポート番号ありき
                - ポート番号とアプリケーションは一意に紐づいていて、ポート番号さえ見れば、どのアプリケーションにデータを渡せばよいかわかるようになっている
            - 「0〜65535」（16ビット分）までの数字
            - System Ports
                - 「0〜1023」はSystem Ports
                - 「Well-known Ports」として知られる
                    - ICANNの一部であるIANA（Internet Assigned Numbers Authority）によって管理されている
                - 一般的なサーバーアプリケーションが提供するサービスに一意に紐づいている
                    - UDPの123番なら、ntpdやxngpdなど時刻同期の「NTP」のサーバーアプリケーションに紐づく
                    - TCPの80番は「HTTP」
            - User Ports
                - 「1024〜49151」はUser Ports
                - メーカーが開発した独自のサーバーアプリケーションが提供するサービスに一意に紐づいている
                    - TCPの3306番ならオラクルのMySQL
            - Dynamic and/or Private Ports
                - 「49152〜65535」はDynamic and/or Private Ports
                - 送信元ポート番号に、OSがこの範囲のポート番号をランダムに割り当てる
                - Linux OSが使用するランダムポートの範囲はIANAの指定と微妙に外れている
    - UDPパケットの解析
        - トランスポート層（レイヤー4）のパケット解析は「IPアドレス+ポート番号」ありき
            - IPアドレスとポート番号の組み合わせを「ソケット」という
        - ファイアウォールの動作はどう見えるか
            - フィルタリングルール
                - 「送信元IPアドレス」「宛先IPアドレス」「プロトコル」「送信元ポート」「宛先ポート」「通信制御（アクション）」などを設定する
            - コネクションテーブル
                - フィルタリングルールを、コネクションの情報をもとに動的に書き換えることで、セキュリティ強度を高めている
                - 「コネクションの状態」「アイドルタイムアウト」なども含まれる
            - ステートフルインスペクションの動作
                - 拒否（Reject）
                - ドロップ（Drop）
                    - こっそり破棄する
- TCP（Transmission Control Protocol）
    - TCPとは
        - メールやファイル転送、Webブラウザなどの信頼性を求めたいアプリケーションで使われる
        - 「TCPコネクション」という仮想的な通信路を作る
            - 「送信パイプ」と「受信パイプ」の2本の論理パイプを全二重に使用する
                - 「送りまーす！」「受け取りました！」と確認しあいながらデータを送る
    - TCPプロトコルの詳細
        - TCPのパケットフォーマット
            - 送信元/宛先ポート番号
                - アプリケーション（プロセス）の識別に使用される
                    - 受け取ったサーバーは、宛先ポート番号を見て、どのアプリケーションのデータか判断して渡す
            - シーケンス番号
                - TCPセグメントを正しい順序に並べるために使われる
                - 送信側は「初期シーケンス番号（ISN、Initial Sequesnce Number）」から順に、通し番号をつける
            - 確認応答番号（ACK番号、Acknowledge番号）
                - 「次はここからのデータをくださーい」と相手に伝えるフィールド
                    - ACKフラグが「1」のときだけ有効になる
            - データオフセット
                - TCPヘッダーの長さを表す
                - どこまでがTCPヘッダーかわかる
                - 最も小さいTCPヘッダーは20バイト（160ビット = 32ビットx5）なので、「５」が入る
            - コントロールビット
                - 6ビットのフラグで構成されている
            - ウィンドウサイズ
                - TCPを使用する端末は、「送信バッファ」と「受信バッファ」を持っている
                - 送信側端末は、アプリケーションから受け取ったデータをいったん送信バッファに入れて、分割したうえで、ネットワーク層に渡す
                - 受信側の端末は、受け取ったTCPセグメントを受信バッファに入れて、正しい順序に並べ替えてからアプリケーションに渡す
                - 「これくらいまでだったら受け取れますよ」
                    - 確認応答を待たずに受け取り切れるデータサイズを、ウィンドウサイズとして通知する
            - チェックサム
                - 受け取ったTCPが壊れていないかチェックする
                - 計算方法はUDPと同じ
            - 緊急ポインタ
                - コントロールビットのURGフラグが「1」になっているときだけ有効な16ビットのフィールド
                - 緊急データがあったときに、緊急データを示す最後のバイトのシーケンス番号がセットされる
            - オプション
                - TCPに関する拡張機能を通知しあうために使われる
                - 「種別（Kind）」「オプション長」「オプションデータ」という3つのサブフィールドで構成される
                - オプションの組み合わせと順序はOSによって異なる
        - 接続開始フェーズでは3ウェイハンドシェイクを行う
            - 3ウェイハンドシェイクのフラグ
                - 必ずクライアント側から始まり、必ず「SYN」→「SYN/ACK」→「ACK」の順番でフラグをやりとりする
                1. 3ウェイハンドシェイク開始前は、クライアントは「CLOSED」、サーバーは「LISTEN」の状態
                1. クライアントはSYNフラグを「1」にしたSYNパケットを送信して、「SYN-SENT」に移行し、SYN/ACKパケットを待つ
                1. SYNパケットを受け取ったサーバーは、パッシブオープン処理に入る。SYNとACKを「1」にしたSYN/ACKパケットを返し、「SYN-RECIEVED」に移行する
                1. SYN/ACKパケットを受け取ったクライアントは、ACKを「1」にしたACKパケットを返し、「ESTABLISHED」に移行する。これでアプリケーションデータを送受信できるようになる
                1. ACKパケットを受け取ったサーバーは「ESTABLISHED」に移行する
            - 3ウェイハンドシェイクにおけるシーケンス番号
                - 3ウェイハンドシェイクでESTABLISHED状態で行うアプリケーションデータのシーケンス番号を決定する
                - クライアントは初期シーケンス番号を選択してSYNパケットを送信し、サーバーも初期シーケンス番号を選択してSYN/ACKパケットを送信する
            - 3ウェイハンドシェイクで交換されるオプション
                - 3ウェイハンドシェイクでお互いがサポートしている拡張機能や、合わせておかなくてはいけない値を交換する
                - End Of Option List
                    - 種別は「0」
                    - オプションリストの終わりとデータオフセットで示すTCPヘッダーの終わりが一致しない場合に使われる
                - No-Operation(NOP）
                    - 種別は「1」
                    - オプション間の区切り文字や、オプションリストの長さを32ビット単位に調整するためにも使用される
                - Maximum Segment Size(MSS)
                    - 種別は「2」
                    - Maximum Transmission Unit（MTU)との比較
                        - MTUはIPパケットの最大サイズ
                            - Ethernetのデフォルトで1500バイト
                        - MSSはTCPセグメントに詰め込めるアプリケーションデータの最大サイズ
                            - 「MTUから40バイト（IPヘッダー + TCPヘッダー）を引いたもの」 = 1460バイト
                            - トランスポート層は、アプリケーションデータをMSSに区切って、TCPにカプセル化する
                    - 「このMSSのアプリケーションデータだったら受け取れますよー」と、サポートしているMSSの値を教えあう
                - Window Scale
                    - 種別は「3」
                    - ウィンドウサイズには16ビットしか割り当てられていないので、65535バイトより大きい値を表現できない
                        - 新しく作られたのがWindow Scale
                    - 「シフトカウント」をセットして、ウィンドウサイズ（2進数）をシフトカウントのビット数だけ、左にシフトする
                        - 「ウィンドウサイズx2のシフトカウント乗」だけ大きくなる
                            - ウィンドウサイズ65535バイトでシフトカウント「3」なら、524280(65535x2*3)バイトとなる
                - SACK Permitted
                    - 種別は「4」
                    - SACK（Selective ACK、選択的確認応答）に対応していることを表す
                    - 部分的にTCPセグメントが喪失すると、喪失したTCPセグメントから先の、すべてのTCPセグメントを再送してしまうという非効率さを解消する　
                - SACK
                    - 種別は「５」
                    - SACKに関連する情報を通知するために使われる
                    - 受信側端末はTCPセグメントの喪失を判断して、すでに受け取れているTCPセグメントのシーケンス番号の範囲を、最初の「SLE(Selective Left Edge)」と最後の「SRE(Selective Right Edge)」として提示する
        - 接続確立フェーズでは3つの制御を組み合わせてデータを転送
            - フロー制御（ウィンドウ制御）
                - フロー制御は受信側の端末が行う流量調整
                    - スライディングウィンドウ
            - 輻輳制御
                - 輻輳制御は送信側が行う流量調整
                - 送信側のウィンドウサイズは、ACKに含まれる受信ウィンドウと自分自身が持つ輻輳ウィンドウのうち、小さいほうの値となる
                - スロースタートフェーズ
                    - 最初は少なく送信し、ACK受信のたびに輻輳ウィンドウを増やしていく
                - 輻輳回避フェーズ
                    - おそるおそる輻輳ウィンドウを増加させる
                        - OSごとの輻輳制御アルゴリズムによる
                    - ロスベース
                        - パケットロスが増えてきたら輻輳と判断する
                        - パケットがロスするまで加算的に輻輳ウィンドウを上げていくTahoe
                        - 輻輳の度合い（RTO: 再送タイムアウト）
によって輻輳制御の下げ幅を変える機能があるのがReno
                        - 以前輻輳があったときの輻輳ウィンドウを覚えておいて、そこまでは一気に輻輳ウィンドウを上げ、そこから少しずつ試みるのがCUBIC
                            - LinuxOSやmacOSが採用
                    - 遅延ベース
                        - 遅延ベースはRTT（パケットの往復遅延時間）が予想を超えると輻輳と判断して、転送料を抑える
                    - ハイブリッドベース
                        - パケットロスとRTTの両方を組み合わせて輻輳判断し、転送量を調整する
            - 再送制御
                - TCPはACKパケットによってパケットロスを検知し、データの再送をする
                - 重複ACK（Duplicate ACK）
                    - 受信側は、受け取ったTCPセグメントのシーケンス番号が飛び飛びになるとパケットロスが発生したと判断する
                        - 確認応答が同じACKパケットを連続送出する
                        - 「重複ACK」という
                    - 送信側は、一定回数以上の重複ACKを受け取ると、対象のTCPセグメントを再送する
                        - 「Fast Retransmit（高速再送）」という
                - 再送タイムアウト（Retransmission Timeout、RTO）
                    - 送信側は、TCPセグメントを送信した後、ACKパケットを待つまでの時間を「再送タイマー（Retransmission Timer）」として保持している
                        - このリミットが再送タイムアウト（RTO）
                    - 再送タイマーは、RTT（パケットの往復遅延時間）から算出される
                        - RTTが短いほど再送タイマーも短くなる
                    - 昼休みのネットが重いのはほとんどこの再送タイムアウト状態にある
        - 接続終了フェーズではFINでしっかり終わる
            - 不要なコネクションを溜めないように、コネクションの終了処理はオープンよりもしっかり慎重に進める
                - 4ウェイハンドシェイク
            - クローズするときのフラグ遷移
                - コントロールビットの6つのフラグを「1」にしたり「0」にしたりで制御している
                    - お互いに「終わりたいんですけど…」的な終了確認をする
                    1. クライアントはFINフラグとACKフラグを「1」にしたFIN/ACKパケットを送信して、「FIN-WAIT1」に移行する
                    1. FIN/ACKパケットを受け取ったサーバーは、パッシブクローズの処理を開始する。ACKパケットを送信し、アプリケーションにクローズ依頼をして、アプリケーションからのクローズ要求を待つ、「CLOSE-WAIT」に移行する
                    1. ACKを受け取ったクライアントは、「FIN-WAIT2」に移行する
                    1. サーバーはアプリケーションからクローズ処理の要求があると、FIN/ACKパケットを送り、クライアントからのACKパケットを待つ「LAST-ACK」に移行する
                    1. クライアントはACKパケットを送信し、「TIME-WAIT」に移行する。もしかしたら遅れて届くかもしれないACKパケットを待つ保険のような状態
                    1. ACKパケットを受け取ったサーバーは「CLOSED」に移行し、コネクションを削除して、リソースを開放する。パッシブクローズは終了。
                    1. クライアントはタイムアウトを待って「CLOSED」に移行し、コネクションを削除して、リソースを開放する。アクティブクローズは終了。
            - クローズするときのシーケンス番号と確認応答番号
                - 2ウェイハンドシェイクを2回実行するようなイメージ
    - TCPの解析に役立つWiresharkの機能
        - ちょうどよいくらいのデータ量とは、帯域幅と往復遅延時間（RTT）を掛け算した「帯域幅遅延積（Bandwidth Delay Product、BDP）で算出できる
            - RTTの平均値を求め、帯域幅遅延積を求めることで、最適な送受信バッファサイズを設定できる
    - TCPパケットの解析
        - TCPでもUDPでもまずは「IPアドレス+ポート番号」ありき
            - どのアプリケーションがどのIPアドレスとどのポート番号をどのように使用しているか
        - ファイアウォールの動作はどう見えるか
            - ステートフルインスペクションの動作
                - 通信の可否を定義する「フィルタリングルール」と、通信を管理する「コネクションテーブル」を使用する
            1. ファイアウォールはクライアント側のOutsideインターフェースでSYNパケットを受け取り、フィルタリングルールと照合する
            1. 「許可」ならコネクションテーブルにコネクションエントリを追加してから、反転して戻り通信の許可ルールを動的に追加する
                - 「拒否（Reject）」ならRSTパケットを返す
                - 「ドロップ(Drop)」ならこっそり破棄する（Silently Discard)
            1. ファイアウォールは戻り通信を受け取ると許可制御を実行して、クライアントに転送する。コネクションのエントリを「SYN-SENT」→「ESTABLISHED」にして、アイドルタイム（無通信時間）を「0秒」にリセットする
            1. クローズ処理は4ウェイハンドシェイクの流れをファイアウォールが見てコネクションエントリと戻り通信用のルールを削除する
                - 途中で端末がダウンしたりするとデータがメモリ上に残り続けるので、アイドルタイムがタイムアウトしたらコネクションエントリと戻り通信用のフィルタリングルールを削除して、メモリを開放する
        - その他の拡張機能はどう見えるか
            - 「フロー制御」「輻輳制御」「再送制御」にプラスして、たくさんのオプションで拡張されている
            - TCP Fast Open(TFO)
                - 「TCP Fast Open」は3ウェイハンドシェイクを使ってアプリケーションのリクエストを送信する機能
                - SYN、SYN/ACKにアプリケーションデータを載せることで、3ウェイハンドシェイクを有効活用する
                    - 1回目でTFO Cookieをやりとりして、2回目の通信では3ウェイハンドシェイクの時点からアプリケーションデータを載せるようにする
            - Nagleアルゴリズム
                - 「Nagleアルゴリズム」は、データサイズが小さいTCPセグメントをまとめて送信する機能
                - MSSに満たない小さいTCPセグメントをまとめて送って、パケットの往復を減らす
                    - リアルタイム性を阻害することもある
            - 遅延ACK(Delayed ACK)
                - 「遅延ACK」はデータサイズが小さいTCPセグメントに対する確認応答を少しだけ遅らせる機能
                    - 複数のACKを1つにまとめて返すことによって、通信の効率化を図る
                - Nagleアルゴリズムとの相性で、お互いお見合い状態が頻発してしまう
            - Early Retransmit
                - 「Early Retransimit」は、Fast Retransmitが発動しきれない特定のTCP環境において、重複ACKのしきい値を下げ、Fast Retransmitを強制発動させる機能
                    - 3回以上重複ACKを生み出せないTCP状態で、重複ACKのしきい値を「未処理のTCPセグメント数-1」まで下げ、Fast Retransmiを強制発動させる
            - Tail Loss Probe
                - 「Tail Loss Probe」は送信した一連のTCPセグメントのうち、最後のほうが失われてしまった場合に、Fast Retransmitを強制発動させる機能
                - 最後のパケットロスだけなく、Early Retransmitとの連携で幅広いパケットを救える



## chapter: 6 アプリケーションプロトコル

- HTTP（Hyper Text Transfer Protocol）
    - HTTPとは
        - クライアントのリクエスト（要求）に対して、サーバーがレスポンス（応答）する典型的なリクエスト-レスポンス型のプロトコル
        - 最初はテキストファイルをダウンロードするためだけのプロトコルだった
    - HTTPプロトコルの詳細
        - HTTPプロトコルの歴史
            - HTTP/0.9
                - HTML形式のテキストファイルをサーバーからダウンロードするだけ
            - HTTP/1.0
                - テキストファイル以外も扱えるようになり、アップロードや削除もできるようになった
                - 1996年にRFC1945で規格化されたHTTPの礎
            - HTTP/1.1
                - パフォーマンス最適化への機能追加
                    - レスポンスを待たずに次のリクエストを送信できる「パイプライン」
                    - TCPコネクションを維持し続けたまま複数のリクエストを送信する「キープアライブ」
                - 2017年現在の標準バージョン
            - HTTP/2
                - アプリケーションレベルでもパフォーマンス向上させる機能が追加
                    - 1本のTCPコネクションでリクエストとレスポンスを並列に処理する「マルチプレキシング」
                    - 次のリクエストが来る前に必要なコンテンツをレスポンスする「サーバープッシュ」
        - メッセージフォーマット
            - シンプルさがHTTPの進化をもたらした
            - HTTPメッセージという
                - リクエストメッセージとレスポンスメッセージの2種類がある
                    1. HTTPメッセージの種類を表す「スタートライン」
                    1. 制御情報の「メッセージヘッダー」
                    1. 空行
                    1. HTTPペイロードを表す「メッセージボディ」
        - リクエストメッセージのフォーマット
            1. 「リクエストライン」
                - リクエストラインは、クライアントがサーバーに「〇〇してください！」と処理をお願いするための行
                    - リクエストメッセージにしか存在しない
                    - 「メソッド」、「リクエストURI」、「HTTPバージョン」の3つで構成されている
                        - `GET /8K HTTP/1.1`
                        - リクエストURI
                            - 絶対URI
                            - 相対URI
                            - URLはネットワーク上のサーバーの場所
            1. 複数の「HTTPヘッダー」で構成されている「メッセージヘッダー」
            1. 「メッセージボディ」
        - レスポンスメッセージのフォーマット
            1. 「ステータスライン」
                - 「HTTPバージョン」、「ステータスコード」、「リーズンフレーズ」
                    - `HTTP/1.1 200 OK`
            1. 複数の「HTTPヘッダー」で構成されている「メッセージヘッダー」
            1. 「メッセージボディ」
        - HTTPヘッダー
            - メッセージヘッダーは、「リクエストヘッダー」「レスポンスヘッダー」「一般ヘッダー」「エンティティヘッダー」「その他のヘッダー」という5種類の組み合わせで構成されている
            - リクエストヘッダー
                - 「Accept」「Authorization」「Host」「Referer」「User-Agent」など
                - Acceptヘッダー
                    - 「Acceptヘッダー」は、ブラウザが処理できるファイルの種類と、その相対的な優先度をサーバーに伝えるヘッダー
                        - 「〇〇のファイルだったら処理できます！」と伝える
                        - `Accept: image/png, */*; q=0.5`
                        - `*/*`はすべてのファイルを表す
                - Hostヘッダー
                    - HTTP/1.1で唯一必須となっている
                    - インターネットホスト（FQDNやIPアドレス）とポート番号がセットされる
                        - `http://www.example.com:8080/html/hogehoge.txt`であれば、`www.example.com:8080`がHostヘッダーとなる
                    - 1つのIPアドレスで複数のドメインを運用する「Virtual Host」を使用するとき有用になる
                - Refererヘッダー
                    - 「Refererヘッダー」は、直前のリンク元のURIを示すヘッダー
                    - セキュリティで役立つ場合
                        - サイトをまたいで（クロスサイト）、偽（フォージェリ）のリクエストを送信する「CSRF」の対策として有効
                        - ただ簡単に改変できる
                    - セキュリティ的に問題になる場合
                        - WebブラウザにセッションIDを渡す方法には、「URI埋め込み方式」「Cookie方式」「Hiddenフィールド方式」の3種類がある
                            - URI埋め込み方式の場合、RefererヘッダーにセッションIDが含まれてしまう
                - User-Agentヘッダー
                    - ユーザーの環境を表すヘッダー
                    - `Mozilla/5.0 (WindowsNT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.01
                        - Mozzila互換ブラウザ Windows10 64bitOS上で32bitアプリを実行 Geckoのリリースバージョン GeckoベースのWebブラウザ Firefox50.0
                - 一般ヘッダー
                    - リクエストメッセージ、レスポンスメッセージのどちらのHTTPメッセージでも汎用的に使用されるのが「一般ヘッダー」
                    - Cache-Controlヘッダー
                        - HTTP/1.1から利用できるようになった
                        - 「ディレクティブ」というコマンドをセットすることでキャッシュを制御する
                        - no-store
                            - 機密情報をキャッシュさせないようにする
                            - no-cacheディレクティブは、キャッシュしたコンテンツが最新かどうか聞いて、最新だったら利用する
                        - max-age
                            - キャッシュの寿命を定義する
                        - Connectionヘッダー/Keep-Aliveヘッダー
                            - キープアライブ（持続的接続）を制御するヘッダー
                            - 「キープアライブをサポートしているよー」とWebサーバーへ伝える
                - エンティティヘッダー
                    - リクエストメッセージとレスポンスメッセージボディに関連する制御情報を含むヘッダーが「エンティティヘッダー」
                    - Content-Encodingヘッダー/Accept-Encodingヘッダー
                        - Webブラウザが処理できるメッセージボディの圧縮方式を指定するヘッダー
                    - Content-Lengthヘッダー
                        - HTTP1.1ではキープアライブによって1つのコネクションを使い回すことがある
                            - Content-Lenghtヘッダーでメッセージの境界をTCPに伝えて、適切にクローズされるようにする
            - レスポンスヘッダー
                - レスポンスメッセージを制御するためのヘッダーを「レスポンスヘッダー」という
                - ETagヘッダー
                    - Webサーバーのもつリソースを一意に識別するためのヘッダー
                        - ファイルを更新するとエンティティタグも更新される
                    - 「If-Matchヘッダー」「If-None-Matchヘッダー」などと組み合わせて使用される
                - Locationヘッダー
                    - リダイレクト先を通知するヘッダー
                - Serverヘッダー
                    - サーバーの情報がセットされるヘッダー
                    - セキュリティ上の問題があるため無効にしておく
            - その他のHTTPヘッダー
                - Cookieヘッダー/Set-Cookieヘッダー
                    - サーバーはセッションIDを「Set-Cookieヘッダー」にセットしてレスポンスする
                    - その後のリクエストは「Cookieヘッダー」にセッションIDをセットして行う
        - メッセージボディ
            - 実際に送りたいアプリケーションデータそのものが入る
    - HTTPパケットの解析
        - HTTP/0.9とHTTP/1.0のコネクション動作はどう見えるか
            - 1リクエストごとにTCPコネクション作っては壊すという手順繰り返す
            - 最大で6本のTCPコネクションをどんどん作っていく
        - HTTP/1.1のコネクション動作はどう見えるか
            - パイプライン
                - リクエストに対するレスポンスを待たずに、次のリクエストを送信する機能
                - 最初のリクエスト処理に時間がかかって続くレスポンスも止まってしまう、「HoL(Head of Lock）ブロッキング」が起こる
                    - ChromeもFirefoxもパイプラインをデフォルトで無効にしている
            - キープアライブ
                - 一度作ったTCPコネクションを使いまわす機能
        - HTTP/2のコネクション動作はどう見えるか
            - HoLブロッキングの反省を踏まえて、「マルチプレキシング」機能が追加された
                - 「ストリーム」という仮想チャンネルを作って並列処理を実現する
- SSL(Secure Socket Layer)/TLS(Transport Layer Security)
    - SSLとは
        - SSL/TLSは、アプリケーションデータを暗号化したり通信相手を認証したりしてデータを守るプロトコル
            - `https://~`は「HTTP over SSL」
    - SSLプロトコルの詳細
        - SSLで守ることができる脅威
            - 暗号化
                - 盗聴から守る
            - ハッシュ化
                - 改ざんから守る
                - データが変わるとハッシュ値も変わる
            - デジタル証明書
                - なりすましから守る
                - 「認証局(CA局）」のお墨付きである「デジタル署名」によって判断する
        - SSLはハイブリッド暗号化方式で暗号化
            - 暗号化には「暗号化鍵」と「復号鍵」が必要
            - 共通鍵暗号方式で高速に処理する
                - 暗号化鍵と復号かぎに同じ鍵（共通鍵）を使う
                - あらかじめ同じ鍵を共有しておく
                - 鍵を送るときに盗まれたらアウト
                - 1ビット1バイトごとに暗号化処理するRC4のような「ストリーム暗号」と、ブロックに区切って暗号化処理するAESのような「ブロック暗号」がある
            - 公開鍵暗号化方式で鍵配送問題を解決する
                - 異なる鍵を非対称に使用するので、「非対称鍵暗号化方式」とも呼ばれる
                    - RSA、DH/DHE（ディフィー・ヘルマン鍵共有）、ECDH/EDCHE（楕円曲線ディフィー・ヘルマン鍵共有）
                - 「公開鍵」と「秘密鍵」の「鍵ペア」
                    - 片方の鍵で暗号化したデータは、もう片方の鍵でしか複合できない
                    - 処理が複雑だし負荷もかかる
            - SSLはハイブリッド暗号化方式でいいとこ取りする
                - 公開鍵暗号化方式で鍵配送問題を解決し、共通鍵暗号化方式で処理負荷問題を解決する
                1. サーバーは公開鍵と秘密鍵を作る
                1. サーバーは公開鍵をみんなに配布する
                1. ブラウザは共通鍵の素を公開鍵で暗号化して送る
                1. サーバーは共通鍵の素を秘密鍵で復号する
                1. サーバーとブラウザは共通鍵の素から共通鍵を生成する
                1. ブラウザはアプリケーションデータを共通鍵で暗号化する
                1. サーバーはアプリケーションデータを共通鍵で復号する
        - ハッシュ値を比較する
            - ハッシュ化は、アプリケーションデータをハッシュドポテトのように細切れにして、同じサイズのデータをまとめる技術
                - メッセージの要約のイメージで「メッセージダイジェスト」や、メッセージの指紋を採るイメージで「フィンガープリント」とも呼ばれる
            - ハッシュ値を比較した方が効率的
                - 「一方向ハッシュ関数」という特殊の計算で、データをめった切りにして、同じサイズの「ハッシュ値」にギュッとまとめる
                - データが異なるとハッシュ値も異なる
                - データが同じだと、ハッシュ値も同じ
                - ハッシュ値から元データには戻せない
                    - 本の要約だけでは本文には戻せない
                - データのサイズが異なっても、ハッシュ値のサイズは固定
                    - データが1ビットでも、1メガでも、1ギガでも同じ
                        - SHA-256は絶対に256ビット
                            - だいたい宇宙にある陽子の数くらい
            - アプリケーションデータの検証
                - 一致しなかったら改ざんされている
                - SSLではこれに加えて「メッセージ認証コード（MAC、Message Authentication Code）」という、相手を認証するセキュリティ要素を入れている
            - デジタル証明書の検証
                - SSLではデジタル証明書を使用して、自分が自分であること、相手が相手であることを証明する
                    - 「認証局（CA局）」に認めてもらう
                    - デジタル証明書は「署名前証明書」「デジタル署名のアルゴリズム」「デジタル署名」で構成されている
                    - 署名前証明書は、サーバーやサーバー所有者の情報
                        - 「コモンネーム（Common Name）」や有効期限、公開鍵もここに含まれる
                    - デジタル署名は、署名前証明書を、デジタル署名のアルゴリズムで指定されたハッシュ関数でハッシュ化し、認証局の秘密鍵で暗号化したもの
                    - デジタル証明書を受け取った受信者は、デジタル署名を認証局の公開鍵（CA証明書）で復号し、署名前証明書のハッシュ値と比較する
                        - サーバーが本物かどうかわかる
        - SSLのレコードフォーマット
            - SSLレコードとは
                - SSLによって運ばれるメッセージのことを「SSLレコード」という
                - 制御情報の「SSLヘッダー」と、その後の「SSLペイロード」で構成される
            - コンテンツタイプ
                - 「ハンドシェイクレコード（22）」「暗号仕様変更レコード（20）」「アラートレコード（21）」「アプリケーションデータレコード（23）」の4つがある
                - ハンドシェイクレコード
                    - 「SSLハンドシェイク」で使用する
                        - `Client Hello`など
                - 暗号仕様変更レコード（Change Cipher Specレコード）
                    - SSLハンドシェイクによって決まった暗号化方式やハッシュ化方式などを確定したり変更したりする
                - アラートレコード
                    - 相手に対してSSL的なエラーがあったことを伝えるレコード
                - アプリケーションデータレコード
            - プロトコルバージョン
                - もっとも多いのはTSLv1.2
            - レコード長
                - レコードの長さをバイト単位で定義する16ビットのフィールド
    - SSLパケットの解析
        - サーバー証明書を用意して、インストールする
            - サーバーは起動して「はい、公開！」とはいかない
            1. HTTPSサーバーで秘密鍵を作る
                - 「-----BEGIN RSA PRIVATE KEY-----」から始まるファイル
            1. [1]の秘密鍵をもとに「CSR（Certificate Signing Request）」を作って、認証局に送る
                - CSRはサーバーの証明書を取得するために認証局に提出する申請書のようなもの
            1. 認証局が申請元の身元を審査する。審査が通れば、CSRをハッシュ化、認証局の秘密鍵で暗号化して、デジタル署名としてくっつけて、サーバー証明書を発行する
                - 「-----BEGIN CERTIFICATE-----」から始まるファイル
            1. 認証局から受け取ったサーバー証明書をインストールする
                - 下位認証局の「中間証明書（中間CA証明書、チェーン証明書）」も一緒にインストールする
        - SSLハンドシェイクで事前準備
            - TCPの3ウェイハンドシェイクなどとはまったく別物
            1. 対応している暗号化方式とハッシュ関数の提示
                - 「Client Hello(1)」
                    - 「こんな暗号化方式やハッシュ化方式が使えます」
                - 利用可能な暗号化方式や一方向ハッシュ関数の組み合わせを「暗号スイート（Cipher Suite）」という
            1. 通信相手の証明
                - 本物のサーバーと通信しているかどうかをサーバー証明書で確認する
                - 「Server Hello(2)」「Certificate(11)」「Server Hello Done(14)」という3つのプロセス
                1. サーバーは、受け取った暗号スイートリストの中から最優先の暗号スイートを選択し、合わせておかないといけないパラメータを含めて「Server Hello(2)」として返す
                1. 「Certificate(11)」で自分自身のサーバー証明書を送る
                1. 「Server Hello Done(14)」で送り終わったことを通知する。ブラウザはサーバー証明書を検証（ルート証明書で復号→ハッシュ値を比較）し、チェックする
            1. 共通鍵の交換
                - ブラウザは、通信相手が本物のサーバーだと確認すると、「プリマスターシークレット」という共通鍵の素を送る
                - 「Client Key Exchange(16)」
                - ブラウザとサーバーは、プリマスターシークレットとClient Helloで得た「client random」と、Server Helloで得た「server random」を混ぜこぜにして、「マスターシークレット」を作り出す
                - マスターシークレットから、暗号化に使う共通鍵「セッション鍵」と、ハッシュ化に使う共通鍵「MAC鍵」を作る
            1. 最終確認作業
                - 最後の確認作業は、お互いに「Change Cipher Spec」と「Finished」を交換しあってSSLハンドシェイクを終了する
                - FinishedのVerify Dataは、マスターシークレットやこれまでのやりとりをハッシュ化した値をまぜこぜにした12バイトのデータ
        - 暗号化通信
            - アプリケーションデータをMAC鍵でハッシュ化した後、セッション鍵で暗号化して転送する
        - SSLセッション再利用
            - SSLは処理にやたら時間がかかるので、2回目以降使いまわせる機能がある
        - SSLクローズ
            - ブラウザかサーバーかを問わず、クローズしたい側から「close_notify」が送られる
            - アラートレコードだがSSLセッションをクローズしているだけ
        - クライアント証明書でクライアントを認証する
            - SSLには「クライアント認証」もある
            1. クライアント証明書を要求
            1. クライアント証明書を送付
            1. これまでのハッシュ値を送付
                - 「Certificate Verify」でこれまでのやりとり（Client HelloからClient Key Exchangeまで）をハッシュ化+暗号化して送る
- DNS(Domain Name System）
    - DNSは、IPアドレスとドメイン名を相互に変換するプロトコル
        - 「10.1.1.1」は見てもわからないので「ドメイン名」という名前をつけてわかりやすくする
        - インターネットの爆発的普及を縁の下の力持ち的に支えたプロトコル
    - DNSプロトコルの詳細
        - RFC1034とRFC1035で規格化されている
        - ドメイン名の構文
            - 「www.example.co.jp」のようなドットで区切られたひとつひとつの文字列のことを「ラベル」という
            - ドメイン名は別名「FQDN（Fully Qualified Domain Name、完全修飾ドメイン名）」と呼ばれる
                - 「ホスト部」と「ドメイン部」で構成されている
        - 名前解決とゾーン転送
            - 名前解決
                - DNSクライアント（スタブリゾルバ、リゾルバ）
                    - 名前解決をDNSサーバーに要求する端末・ソフトウェア
                        - 「nslookupコマンド」「digコマンド」の名前解決コマンド
                    - キャッシュサーバー（フルサービスリゾルバ、参照リゾルバ）
                        - DNSクライアントからの問い合わせ（再帰クエリ）を受付、インターネットに問い合わせるDNSサーバー
                    - コンテンツサーバー（権威サーバー、ゾーンサーバー）
                        - キャッシュサーバーからの問い合わせ（反復クエリ、非再帰クエリ）を受け付けるDNSサーバー
            - ゾーン転送
                - DNSはWebアクセスやメール送信に先立って行われる重要な処理なので、　失敗すると困る
                    - DNSサーバーはシングル構成ではなく、「プライマリDNSサーバー」と「セカンダリDNSサーバー」の冗長構成にするのが基本
                    - キャッシュサーバーの冗長化
                        - サーバーの機能で冗長化する必要はないので、OSの処理で冗長化する
                    - コンテンツサーバーの冗長化
                        - DNSサーバー間でゾーンファイルを同期しておく
                            - 「ゾーン転送」という
        - ゾーンファイルとリソースレコード
            - 1つのゾーンファイルで管理するドメイン名の範囲を「ゾーン」という
        - DNSのメッセージフォーマット
            - 名前解決とゾーン転送で異なるレイヤー4プロトコルを使用する
                - 名前解決はUDP（ポート53）
                - ゾーン転送はTCP（ポート53）
            - Headerセクション
                - いろいろな制御情報がセットされている
            - Questionセクション
                - DNSサーバーに対する質問がセットされる
                    - ドメイン名の「QNAME」、リソースレコードの種類の「QTYPE」、問い合わせのクラスの「QCLASS」など
            - Answer/Authority/Additionalセクション
                - ゾーンファイルを構成するリソースレコードの情報がセットされる
    - DNSパケットの解析
        - 名前解決はどう見えるか
            1. DNSクライアントはキャッシュサーバーに対して「www.google.com」のAレコードを問い合わせる
            1. 再帰クエリを受け取ったキャッシュサーバーは、キャッシュを検索して無かったら、親分サーバーのルートサーバーに反復クエリを実施する
            1. ルートサーバーは、ルートサーバーのNSレコードと、それに対応するAレコード・AAAAレコードを返す
                - 2017年現在、ルートサーバーは世界に13クラスタ存在する
            1. キャッシュサーバーは、ルートサーバーのひとつに対して、「www.google.com」のAレコードを問い合わせる
            1. ルートサーバーは、「com」を管理しているコンテンツサーバーのNSレコードと、それに対応するAレコード・AAAAレコードを返す
                - 「comのことはわからないから、comのコンテンツサーバーに聞いて！」
            1. キャッシュサーバーは「com」を管理しているコンテンツサーバーのひとつに対して、「www.google.com」のAレコードを問い合わせる
            1. comのコンテンツサーバーが「google」に対応するコンテンツサーバーのAレコードを返す
            1. キャッシュサーバーが「www.google.com」のAレコードを問い合わせる
            1. googleのコンテンツサーバーは、「www」のAレコード、つまりwww.google.comのIPアドレスを返す
            1. キャッシュサーバーはDNSクライアントに対して、IPアドレスの情報を再帰クエリとして返す
        - ゾーン転送はどう見えるか
            - 「バージョン確認」と「ゾーン転送」という2段階の処理によって成り立っている
            1. セカンダリDNSサーバーがUDPの53番でSOAレコードの情報を問い合わせる
            1. プライマリDNSサーバーがSOAレコードを返す
            1. セカンダリDNSサーバーは、ゾーンファイルのバージョン情報のようなものであるSOAレコードのシリアル番号を確認する
                - 自分が保持するゾーンファイルよりも新しければ、QTYPEに「AXFR」をセットして、TCPの53番でゾーン転送をリクエストする
            1. プライマリDNSサーバーがゾーン情報を返す