基本#
TCP/IP ネットワークモデル#
-
アプリケーション層:ユーザーに一連のアプリケーションを提供する役割を担う。
HTTP、FTP、Telnet、DNS、SMTP など。アプリケーション層はユーザーモードで動作します。
-
トランスポート層:エンドツーエンドの通信を担当する。
TCP:フロー制御、タイムアウト再送、輻輳制御など。/UDP
MSS(最大セグメントサイズ) -> TCP セグメント(TCP Segment)
-
ネットワーク層:ネットワークパケットのカプセル化、分割、ルーティング、転送を担当する。
IP プロトコル:アドレス指定、ルーティング。/ICMP
MTU(最大伝送単位) -> 分割
-
リンク層:物理ネットワーク内でのネットワークパケットの転送を担当し、パケットのフレーミング、MAC アドレス指定、エラーチェック、ネットワークフレームの NIC を介した転送などを行う。/ARP
OSI 七層ネットワークモデル#
- アプリケーション層:アプリケーションに統一インターフェースを提供する。
- 表現層:データを別のシステムが認識できる形式に変換する。
- セッション層:表現層エンティティ間の通信セッションを確立、管理、終了する。
- トランスポート層:エンドツーエンドのデータ転送を担当する。
- ネットワーク層:データのルーティング、転送、分割を担当する。
- データリンク層:データのフレーミングとエラーチェック、MAC アドレス指定を担当する。
- 物理層:物理ネットワーク内でデータフレームを転送する。
URL からウェブページ表示まで#
- URL を解析 -> Web サーバーとファイル名
- HTTP リクエストを生成
- DNS ドメイン名解決
- TCP 三回のハンドシェイクで接続を確立
- TCP メッセージ生成
- IP メッセージ生成 -> IP アドレスはリモートロケーションを担当
- MAC メッセージ生成(ARP を使用して MAC アドレスを照会) -> MAC アドレスはポイントツーポイントの転送を担当
- NIC は、先頭にヘッダーと開始フレームの区切りを追加し、末尾にエラーチェック用のフレームチェックシーケンス(FCS)を追加し、デジタル情報 -> 電気信号
- スイッチ(二層ネットワークデバイス)は、スイッチの MAC アドレステーブル(MAC - ポート)を確認し、存在しない場合はすべてのポートに転送
- ルーター(三層ネットワークデバイス)は、ルーティングテーブルで IP を確認(ルーティングマッチ)、ARP で MAC を確認。
- サーバーに到達し、データパケットを解析し、HTTP 応答を送信
- クライアントは HTTP 応答を受け取り、ページをレンダリング
- TCP 四回のハンドシェイクで接続を切断
転送プロセス中、送信元 IP アドレスと宛先 IP アドレスは変わらず、送信元 MAC と宛先 MAC は変化します。
全体として、以下のステップに分かれます:
- ブラウザに指定されたウェブページの URL を入力します。
- ブラウザは DNS プロトコルを介して、ドメイン名に対応する IP アドレスを取得します。
- ブラウザは IP アドレスとポート番号に基づいて、ターゲットサーバーに TCP 接続リクエストを送信します。
- ブラウザは TCP 接続上で、サーバーに HTTP リクエストメッセージを送信し、ウェブページの内容を取得します。
- サーバーは HTTP リクエストメッセージを受け取り、リクエストを処理し、HTTP 応答メッセージをブラウザに返します。
- ブラウザは HTTP 応答メッセージを受け取り、応答ボディ内の HTML コードを解析し、ウェブページの構造とスタイルをレンダリングします。同時に、HTML 内の他のリソースの URL(画像、CSS、JS など)に基づいて、再度 HTTP リクエストを発起し、これらのリソースの内容を取得し、ウェブページが完全に読み込まれるまで続けます。
- ブラウザはサーバーとの通信が不要な場合、TCP 接続を積極的に切断するか、サーバーの切断リクエストを待機します。
HTTP_インタビュー#
HTTP はハイパーテキスト転送プロトコル、すなわちHyperText Transfer Protocol です。
プロトコルとは何か#
プロトコル(protocol)は、二つ以上の通信エンティティ間で交換されるメッセージの形式と順序、およびメッセージの送信や受信、または他のイベントに対して取られるアクションを定義します。
それは、コンピュータが理解できる言語を使用して、コンピュータ間の通信の規範(2 つ以上の参加者)を確立し、関連するさまざまな制御とエラーハンドリングの方法(行動規約と規範)を定義します。
HTTP のステータスコード#
- 1xx:ヒント応答を示す
- 101 はプロトコルの切り替えを示し、WebSocket 接続でよく見られる;
- 2xx:成功応答を示す
- 「200 OK」は成功を示す
- 「204 No Content」は応答にボディデータがないことを示す
- 「206 Partial Content」は部分的な内容のみが送信されたことを示す;
- 3xx:リダイレクト応答を示す
- 「301 Moved Permanently」は永久リダイレクトを示す
- 「302 Found」は一時的なリダイレクトを示す
- 303 はクライアントが指定されたパスでリクエストを再送信すべきことを示す
- 「304 Not Modified」はリソースが変更されていないことを示し、キャッシュにリダイレクトされる(キャッシュリダイレクト);
- 4xx:クライアントの問題によるエラー応答を示す
- 「400 Bad Request」はクライアントのリクエストメッセージにエラーがあることを示す
- 「403 Forbidden」はサーバーがリソースへのアクセスを禁止していることを示す
- 「404 Not Found」は指定されたパスが存在しないことを示す;
- 5xx:サーバーの問題によるエラー応答を示す:
- 「500 Internal Server Error」はサーバー内部の故障を示す
- 「501 Not Implemented」はクライアントのリクエスト機能がまだサポートされていないことを示す
- 「502 Bad Gateway」はサーバー自体は正常に動作しているが、バックエンドサーバーへのアクセスでエラーが発生したことを示す
- 「503 Service Unavailable」はサーバーが忙しく、一時的に応答できないことを示す。
HTTP の一般的なフィールド#
HTTP リクエストの形式は固定されており、HTTP ヘッダーと HTTP ボディの 2 つの部分で構成されています。最初の行は常にリクエストメソッド パス HTTPバージョン
であり、例えば、GET / HTTP/1.1
はGET
リクエストを使用し、パスは/
、バージョンはHTTP/1.1
を示します。
その後の各行は固定のHeader: Value
形式であり、これを HTTP ヘッダーと呼びます。サーバーは特定のヘッダーに依存してクライアントのリクエストを識別します。例えば:
- Host:リクエストのドメイン名を示します。1 台のサーバー上に複数のウェブサイトが存在する可能性があるため、Host に依存してリクエストがどのウェブサイトに送信されたかを識別する必要があります;
- User-Agent:クライアント自身の識別情報を示します。異なるブラウザには異なる識別があり、サーバーは User-Agent に基づいてクライアントのタイプが IE か Chrome か、Firefox か Python のクローラーかを判断します;
- Accept:クライアントが処理できる HTTP 応答形式を示します。
*/*
は任意の形式、text/*
は任意のテキスト、image/png
は PNG 形式の画像を示します; - Accept-Language:クライアントが受け入れる言語を示します。複数の言語が優先順位に従って並べられ、サーバーはこのフィールドに基づいてユーザーに特定の言語のウェブページバージョンを返します。
GET
リクエストの場合、この HTTP リクエストには HTTP ヘッダーのみが含まれ、HTTP ボディはありません。POST
リクエストの場合、この HTTP リクエストにはボディが含まれ、空行で区切られます。
POST
リクエストでは通常、Content-Typeを設定してボディのタイプを示し、Content-Lengthを設定してボディの長さを示します。これにより、サーバーはリクエストのヘッダーとボディに基づいて正しい応答を行うことができます。
HTTP 応答もヘッダーとボディの 2 つの部分で構成されています。応答の最初の行は常にHTTPバージョン 応答コード 応答説明
であり、例えば、HTTP/1.1 200 OK
はバージョンがHTTP/1.1
、応答コードが200
、応答説明がOK
であることを示します。クライアントは応答コードに依存して HTTP 応答が成功したかどうかを判断します。HTTP には固定の応答コードがあります。
HTTP プロトコルは、改行文字と改行文字を HTTP ヘッダーの境界として設定し、Content-Length フィールドを HTTP ボディの境界として使用します。この 2 つの方法は「バッファリング」の問題を解決するためのものです。
その他のフィールド:
- Connection:クライアントがサーバーに「HTTP 持続接続」メカニズムを使用するよう要求するために最も一般的に使用されます。
- Content-Encoding:データの圧縮方法を示します。サーバーが返すデータがどの圧縮形式を使用しているかを示します。
GET と POST#
GET の意味は、サーバーから指定されたリソースを取得することです。GET リクエストのパラメータ位置は一般に URL に書かれ、URL は ASCII のみをサポートするため、GET リクエストのパラメータは ASCII 文字のみが許可され、ブラウザは URL の長さに制限を設けます(HTTP プロトコル自体は URL の長さに関して何の規定もしていません)。
POST の意味は、リクエストペイロード(メッセージボディ)に基づいて指定されたリソースに対して処理を行うことです。POST リクエストがデータを持つ位置は一般にメッセージボディに書かれ、ボディ内のデータは任意の形式であり、クライアントとサーバーが合意すればよく、ブラウザはボディのサイズに制限を設けません。
- HTTP プロトコルにおいて、「安全」とはリクエストメソッドがサーバー上のリソースを「破壊」しないことを指します。
- 「冪等」とは、同じ操作を何度も実行しても結果が「同じ」であることを意味します。
したがって、GET メソッドは安全かつ冪等であり、これは「読み取り専用」操作であり、キャッシュ可能です;POST メソッドは安全ではなく冪等でもないため、サーバー上のリソースを変更し、大部分はキャッシュできません。
HTTP キャッシュ#
強制キャッシュ:ブラウザがキャッシュが期限切れでないと判断した場合、ブラウザのローカルキャッシュを直接使用します。キャッシュを使用するかどうかの決定はブラウザ側にあります。
Cache-Control
は相対的な時間です;Expires
は絶対的な時間です;
協議キャッシュ:サーバーと協議した後、協議結果に基づいてローカルキャッシュを使用するかどうかを判断します。HTTP 200 OK/ HTTP 304
- 一意の識別子に基づく実装:応答ヘッダーの
Etag
(応答リソースの一意の識別子)とリクエストヘッダーのIf-None-Match
; - 時間に基づく実装:応答ヘッダーの
Last-Modified
とリクエストヘッダーのIf-Modified-Since
;
注意、協議キャッシュのこれら 2 つのフィールドは、強制キャッシュの Cache-Control フィールドと組み合わせて使用する必要があります。強制キャッシュがヒットしなかった場合にのみ、協議キャッシュフィールドを持つリクエストを発起できます。
HTTP の特性(HTTP/1.1)#
HTTP の利点と欠点#
HTTP の利点は「シンプルで柔軟、拡張が容易、広く適用され、クロスプラットフォームである」ことです。
HTTP の欠点は「ステートレスであり、平文で伝送される」(平文伝送 + メッセージの完全性を検証できない) -> 「安全でない」。
HTTP の性能#
HTTP プロトコルはTCP/IPに基づいており、「リクエスト - 応答」の通信モードを使用しています:
- 長接続:いずれかの端が明示的に接続を切断しない限り、TCP 接続状態を維持し、TCP 接続の再確立と切断による追加のオーバーヘッドを減少させ、サーバー側の負荷を軽減します。
- パイプライン(pipeline)ネットワーク伝送:同じ TCP 接続で、クライアントがリクエストを送信した後、応答を受け取るのを待たずに次のリクエストを送信でき、全体の応答時間を短縮します。ただし、サーバーは受信したリクエストの順序に従って、これらのパイプライン化されたリクエストに対する応答を送信する必要があります。
- ヘッダー阻塞:サーバーが A リクエストの処理に長い時間を要する場合、後続のリクエストの処理もブロックされます。これを「ヘッダーの詰まり」と呼びます。HTTP/1.1 のパイプラインはリクエストのヘッダー阻塞を解決しましたが、応答のヘッダー阻塞は解決していません。
HTTP/1.1 の性能は一般的であり、後続の HTTP/2 および HTTP/3 は HTTP の性能を最適化しています。
HTTP と HTTPS#
- 接続を確立する際、https は http よりも TLS のハンドシェイクプロセスが多い;
- コンテンツを転送する際、https はデータを暗号化し、通常は対称暗号化データを使用します;
HTTP と HTTPS の違い#
- セキュリティ
- 接続の確立
- デフォルトポート
- URL プレフィックス
- 証明書
HTTPS が解決する HTTP のセキュリティ問題#
HTTPSは HTTP と TCP 層の間にSSL/TLS
プロトコルを追加します。
-
盗聴リスク -> 情報暗号化 -> 混合暗号化
-
改ざんリスク -> チェックメカニズム -> ハッシュアルゴリズム
+ デジタル署名- ハッシュアルゴリズムを使用してメッセージの完全性を保証できます;
デジタル署名を使用してメッセージの出所の信頼性を保証できます(メッセージが秘密鍵を持つ一方から送信されたことを確認できます);
-
なりすましリスク -> 身分証明書 -> サーバーの公開鍵をデジタル証明書に格納します。
CA はデジタル証明書に署名し、その証明書が信頼できることを保証します。(証明書の信頼チェーンの問題)
本質:クライアントがサーバーを信頼する問題
HTTPS 接続の確立#
SSL/TLS プロトコルの基本的な流れ:
- クライアントはサーバーの公開鍵を要求し、検証します。
- 双方は「セッションキー」を生成するために協議します。
- 双方は「セッションキー」を使用して暗号化通信を行います。
最初の 2 つのステップが SSL/TLS の確立プロセスであり、これが TLS ハンドシェイク段階で、4 回の通信が関与します(SSL/TLS 1.2)。
異なる鍵交換アルゴリズムを使用すると、TLS ハンドシェイクの流れも異なります。現在一般的に使用される鍵交換アルゴリズムは 2 つ:RSA アルゴリズムと ECDHE アルゴリズムです。
-
ClientHello
、クライアントがサーバーに暗号化通信のリクエストを開始しますクライアントランダム数(Client Random) ...
-
ServerHello
、サーバーはクライアントのリクエストを受け取った後、クライアントに応答を発しますサーバーランダム数(Server Random) + サーバーのデジタル証明書 ...
-
クライアントが応答します
公開鍵で暗号化されたランダム数プレマスターキー + クライアントハンドシェイク終了通知 ...
-
サーバーの最終応答
サーバーハンドシェイク終了通知 + ハンドシェイクサマリー
これで、TLS のハンドシェイク段階が終了し、クライアントとサーバーは暗号化通信に入ります。これは完全に通常の HTTP プロトコルを使用しており、「セッションキー」で内容が暗号化されています。
HTTPS がデータの完全性を保証する#
TLS は実装上、ハンドシェイクプロトコルとレコードプロトコルの 2 層に分かれています:
- TLS ハンドシェイクプロトコルは TLS の 4 回のハンドシェイクプロセスであり、暗号化アルゴリズムの協議と対称鍵の生成を担当します;
- TLS レコードプロトコルはアプリケーションデータを保護し、その完全性と出所を検証します。HTTP データを暗号化するためにレコードプロトコルを使用します;
TLS レコードプロトコルは主にメッセージ(HTTP データ)の圧縮、暗号化、およびデータの認証を担当します:
- メッセージを複数の短いセグメントに分割し、それぞれのセグメントを圧縮します
- 圧縮されたセグメントにメッセージ認証コード(MAC、ハッシュアルゴリズムを使用して得られる)を付加します。これはデータの完全性を保証し、データの認証を行うためです。
- 対称鍵を使用して圧縮されたメッセージセグメント + メッセージ認証コードを暗号化します
- 暗号化されたデータにデータタイプ、バージョン番号、圧縮された長さから構成されるヘッダーを追加したものが最終的なメッセージデータです。
レコードプロトコルが完了した後、最終的なメッセージデータはトランスポート制御プロトコル(TCP)層に渡されて転送されます。
HTTP の進化#
HTTP/1.1 と HTTP/1.0 の違い#
- 長接続
- パイプライン(pipeline)ネットワーク伝送をサポートし、応答を待たずに次のリクエストを送信できる
HTTP/2.0 と HTTP/1.1 の違い#
- HTTP/2.0 は HTTPS に基づいており、安全性が高い
- ヘッダー圧縮、HPACK アルゴリズム
- バイナリ形式
- 同時伝送、ストリーム、複数のリクエストが 1 つの TCP 接続を再利用
- サーバープッシュ
HTTP/2.0 でもヘッダーの詰まり問題は依然として存在し、TCP 層で発生します。TCP データが連続している場合にのみ、アプリケーション層はカーネルからデータを読み取ることができます。パケットが失われると、すべての HTTP リクエストがブロックされます。
HTTP/3#
HTTP/3 は下層で UDP プロトコルを使用してヘッダーの詰まり問題を解決します。
UDP に基づく QUIC プロトコルは、TCP の信頼性のある伝送を実現できます。QUIC プロトコルには以下の特徴があります:
- ヘッダーの詰まりがない:特定のストリームでパケットが失われた場合、そのストリームのみがブロックされ、他のストリームには影響しません。複数のストリームは依存関係がなく、独立しています。
- より迅速な接続確立:QUIC は内部に TLS を含んでおり、1 回の RTT で「同時に」接続の確立と鍵の協議を完了できます。
- 接続の移行:QUIC プロトコルは接続を「バインド」するために四元組の方法を使用せず、接続 IDを使用して通信の 2 つのエンドポイントをマークします。
- セキュリティ:HTTP/2.0 では、TLS が全 HTTP セッションを暗号化および認証するために使用され、すべての HTTP ヘッダーとデータペイロードを含みます。TLS の作業は TCP 層の上にあり、TCP 接続内で転送されるアプリケーション層のデータを暗号化しますが、TCP ヘッダーや TLS レコード層のヘッダーは暗号化されません。したがって、通信中に TCP ヘッダーが攻撃者によって改ざんされる可能性があります。HTTP/3.0 の QUIC は、データパケット全体(ヘッダーとボディを含む)を暗号化および認証処理し、安全性を保証します。
したがって、QUIC は UDP の上にある擬似TCP + TLS + HTTP/2 のマルチプレクスプロトコルです。
TCP_インタビュー#
TCP ヘッダー形式#
TCP ヘッダーはオプションを使用しない場合、20 バイトを占めます:
- ソースポート番号(16 ビット) + 宛先ポート番号(16 ビット)
- シーケンス番号(32 ビット):順序の乱れ問題を解決する
- 確認応答番号(32 ビット):パケットの損失問題を解決する
- ヘッダー長(4 ビット) + 予約(6 ビット) + 制御ビット(6 ビット) + ウィンドウサイズ(16 ビット)
- チェックサム(16 ビット) + 緊急ポインタ(16 ビット)
TCP の存在意義#
ネットワーク層の IP プロトコルは信頼性のある配信を保証しないため、ネットワークデータパケットの信頼性を保証する必要がある場合は、上層(トランスポート層)の TCP プロトコルに任せる必要があります。
TCP プロトコルはトランスポート層で動作する信頼性のあるデータ転送サービスであり、受信したネットワークデータパケットが損傷なく、間隔なく、冗長なく、順序通りであることを保証します。
TCP とは何か#
TCP は接続指向、信頼性のある、バイトストリームベースのトランスポート層通信プロトコルです。
TCP 接続とは何か#
接続:信頼性とフロー制御を維持するためのいくつかの状態情報の組み合わせであり、ソケット、シーケンス番号、ウィンドウサイズを含みます。
TCP 接続を確立するには、クライアントとサーバーが以下の情報に関して合意する必要があります:
- ソケット:TCP 四元組
- シーケンス番号:順序の乱れ問題を解決するために使用
- ウィンドウサイズ:フロー制御に使用
TCP と UDP の違い#
UDP ヘッダーは固定で 8 バイトです:
- ソースポート番号(16 ビット) + 宛先ポート番号(16 ビット)
- パケット長(16 ビット) + チェックサム(16 ビット)
UDP は IP が提供する非接続型の通信サービスのみを使用します。
TCP と UDP の違いは以下の点にあります(論理を把握して記憶する):
- 接続:TCP は接続指向、UDP は非接続指向
- サービス対象:TCP はエンドツーエンドの 2 点サービス、UDP は一対多が可能
- 信頼性:TCP はデータの信頼性のある配信を提供し、UDP は最大限の努力で配信し、信頼性のある配信を保証しない
- TCP は輻輳制御とフロー制御メカニズムを提供し、データ転送の安全性を保証しますが、UDP は提供しません
- ヘッダーオーバーヘッド:TCP はオプションを使用しない場合、ヘッダーは 20 バイト、UDP のヘッダーは固定で 8 バイトです
- 転送方法:TCP はバイトストリームベースのストリーミング転送であり、UDP はパケット単位で送信され、境界があります
- 分割:TCP データサイズが MSS を超える場合、トランスポート層で分割され、UDP はネットワーク層 IP プロトコルの分割のみを使用します(MTU を超える場合)。
TCP の適用シーン:
- FTP ファイル転送
- HTTP/HTTPS
UDP の適用シーン:
- マルチメディア通信
- ブロードキャスト通信
- パケット総量が小さい通信:DNS、SNMP など
TCP 接続の確立#
TCP 接続は三回のハンドシェイクによって確立されます。
なぜ三回のハンドシェイクなのか、二回や四回ではないのか?#
-
過去の接続の初期化を防ぐ
「古い SYN メッセージ」は過去の接続と呼ばれ、TCP が三回のハンドシェイクで接続を確立する最も重要な理由は「過去の接続」の初期化を防ぐためです。
-
双方の初期シーケンス番号を同期させる
クライアントが「初期シーケンス番号」を含む
SYN
メッセージを送信する際、サーバーはクライアントの SYN メッセージが正常に受信されたことを示すACK
応答メッセージを返す必要があります。サーバーがクライアントに「初期シーケンス番号」を送信する際も、クライアントの応答を受け取る必要があります。このように、往復することで、双方の初期シーケンス番号が確実に同期されます。 -
リソースの無駄を避ける
「二回のハンドシェイク」の場合、クライアントが送信した
SYN
メッセージがネットワークでブロックされた場合、クライアントが複数回SYN
メッセージを再送信すると、サーバーはリクエストを受け取った後、複数の冗長な無効接続を確立し、不要なリソースの無駄を引き起こします。
TCP 接続を確立する際に初期シーケンス番号が異なる必要があるのはなぜですか?#
- 同じ四元組の接続が過去のメッセージを誤って受信するのを防ぐ(主な側面)
- ハッカーが同じシーケンス番号の TCP メッセージを偽造するのを防ぐ
初期シーケンス番号 ISN のランダム生成アルゴリズム:ISN = M + F(localhost、localport、remotehost、remoteport)。
M
はタイマーであり、このタイマーは 4 マイクロ秒ごとに 1 増加します。F
はハッシュアルゴリズムであり、ソース IP、宛先 IP、ソースポート、宛先ポートに基づいてランダムな数値を生成します。ハッシュアルゴリズムが外部から簡単に推測されないようにする必要があります。MD5 アルゴリズムを使用するのは比較的良い選択です。
ランダム数は時計タイマーに基づいて増加し、基本的に同じ初期シーケンス番号がランダムに生成されることはありません。
SYN 攻撃について#
攻撃者が短時間で異なる IP アドレスのSYN
メッセージを偽造したと仮定します。サーバーは受信するたびにSYN_RCVD
状態に入り、サーバーが送信するACK + SYN
メッセージは未知の IP ホストのACK
応答を受け取ることができません。次第に、サーバーの半接続キューが満杯になります。これにより、サーバーは正常なユーザーにサービスを提供できなくなります。
SYN 攻撃の最も直接的な影響は、TCP の半接続キューが満杯になることです。TCP の半接続キューが満杯になると、以降に受信した SYN メッセージは破棄され、クライアントはサーバーとの接続を確立できなくなります。
SYN 攻撃を回避する方法は以下の 4 つです:
- netdev_max_backlog を増やす;
- TCP の半接続キューを増やす;
- tcp_syncookies を有効にする;
- SYN + ACK の再送信回数を減らす
TCP 接続の切断#
TCP 接続の切断は四回のハンドシェイクによって行われ、各方向で1 つの FIN と 1 つの ACKが必要です。
TIME_WAIT 状態について#
TIME_WAIT 状態が必要な主な理由は 2 つあります:
-
過去の接続のデータが、後の同じ四元組の接続によって誤って受信されるのを防ぐ;
TIME_WAIT 状態は、状態が
2MSL
の期間持続します。この時間は両方向のデータパケットがすべて破棄されるのに十分であり、元の接続のデータパケットがネットワーク内で自然に消失し、再発生するデータパケットは新しく確立された接続から生成されたものであることを保証します。(MSL
は Maximum Segment Lifetime、メッセージの最大生存時間です。) -
「受動的に接続を切断する」側が正しく切断されることを保証する;
TIME_WAIT の役割は最後の ACK が受動的に切断された側に届くのを確実にするために十分な時間を待つことです。これにより、正常に切断を助けます。
クライアントが TIME_WAIT 状態を持たず、最後の ACK メッセージを送信した後に直接 CLOSE 状態に入った場合、その ACK メッセージが失われ、サーバーは再送信の FIN メッセージを送信します。この時、クライアントはすでに切断状態に入っているため、サーバーから再送信された FIN メッセージを受け取ると RST メッセージを返します。
このような状況を防ぐために、クライアントは十分な時間を待機し、サーバーが ACK を受け取れることを確認する必要があります。サーバーが ACK を受け取れなかった場合、TCP 再送信メカニズムがトリガーされ、サーバーは再度 FIN を送信します。このように往復することで、ちょうど 2 つの MSL の時間がかかります。
クライアントがサーバーから再送信された FIN メッセージを受け取ると、TIME_WAIT 状態の待機時間は 2MSL にリセットされます。
過剰な TIME_WAIT 状態の主な危害は 2 つあります:
- 第一はシステムリソースを占有することです。たとえば、ファイルディスクリプタ、メモリリソース、CPU リソース、スレッドリソースなど;
- 第二はポートリソースを占有することです。ポートリソースも限られており、一般的に開くことができるポートは
32768~61000
であり、net.ipv4.ip_local_port_range
パラメータを使用して範囲を指定できます。
TIME_WAIT は私たちの友人であり、私たちに役立つものであり、この状態を回避しようとするのではなく、理解するべきです。
サーバーが過剰な TIME_WAIT 状態の接続を回避したい場合は、決して接続を積極的に切断せず、クライアントに切断させ、各地に分散したクライアントに TIME_WAIT を負担させるべきです。
サーバーに大量の TIME_WAIT 状態の TCP 接続が発生している場合、それはサーバーが多くの TCP 接続を積極的に切断したことを示しています。以下のようなシーンがあります:
- 第一のシーン:HTTP が長接続(Keep-Alive)を使用していない
- 第二のシーン:HTTP 長接続がタイムアウトした
- 第三のシーン:HTTP 長接続のリクエスト数が上限に達した
TCP のキープアライブメカニズム#
一定の時間を定義し、その時間内に接続関連の活動がない場合、TCP キープアライブメカニズムが作動し、一定の時間間隔で探査メッセージを送信します。この探査メッセージに含まれるデータは非常に少なく、連続して数回探査メッセージに応答がない場合、現在の TCP 接続は死亡したと見なされ、システムカーネルはエラー情報を上層のアプリケーションに通知します。
TCP キープアライブのこのメカニズムは検出時間が長いため、アプリケーション層で独自のハートビートメカニズムを実装できます。
ソケットプログラミング#
TCP に対するソケットプログラミング:
- サーバーとクライアントは
socket
を初期化し、ファイルディスクリプタを取得します; - サーバーは
bind
を呼び出し、指定された IP アドレスとポートにソケットをバインドします; - サーバーは
listen
を呼び出し、リスニングを行います; - サーバーは
accept
を呼び出し、クライアント接続を待ちます; - クライアントは
connect
を呼び出し、サーバーのアドレスとポートに接続リクエストを送信します; - サーバーの
accept
は、データ転送用のソケットのファイルディスクリプタを返します; - クライアントは
write
を呼び出してデータを書き込み、サーバーはread
を呼び出してデータを読み取ります; - クライアントが接続を切断する際、
close
を呼び出します。サーバーはread
でデータを読み取るとEOF
を読み取り、データ処理が完了した後、サーバーはclose
を呼び出して接続を閉じます。
サーバーがaccept
を呼び出すと、接続が成功し、データ転送に使用されるソケットが返されます。リスニングソケットと実際にデータを転送するソケットは「2 つ」のソケットであり、1 つはリスニングソケット、もう 1 つは完了した接続ソケットです。
接続が成功裏に確立された後、双方は read および write 関数を使用してデータを読み書きし、ファイルストリームに書き込むように行います。
IP_基本#
IP は「直接接続されていない」2 つのネットワーク間で通信転送を担当します;
MAC の役割は「直接接続されている」2 つのデバイス間の通信を実現することです;
IP アドレスの分類#
分類アドレス:A クラス、B クラス、C クラス、D クラス、E クラス。
無分類アドレス CIDR:32 ビットの IP アドレスは 2 つの部分に分けられ、前半はネットワーク番号、後半はホスト番号です。
無クラス間ルーティング(英語:Classless Inter-Domain Routing、略称CIDR)
サブネットマスク、マスクの意味はホスト番号を隠すことで、残りがネットワーク番号です。サブネットマスクと IP アドレスをビットごとに AND 計算すると、ネットワーク番号が得られます。
サブネットマスクを使用してネットワーク番号とホスト番号を分割できますが、実際にはサブネットマスクにはサブネットの分割という別の役割もあります。
サブネット分割は実際にはホストアドレスを 2 つの部分に分けることです:サブネットネットワークアドレスとサブネットホストアドレス。
IP アドレスとルーティング制御#
IP アドレスのネットワークアドレス部分はルーティング制御に使用されます。
ルーティング制御テーブルには、ネットワークアドレスと次にルーターに送信すべきアドレスが記録されています。ホストとルーターにはそれぞれのルーター制御テーブルがあります。
IP パケットを送信する際、まず IP パケットのヘッダー内の宛先アドレスを確認し、その後ルーティング制御テーブルからそのアドレスと同じネットワークアドレスを持つレコードを見つけ、そのレコードに基づいて IP パケットを適切な次のルーターに転送します。ルーティング制御テーブルに同じネットワークアドレスのレコードが複数存在する場合、同じビット数が最も多いネットワークアドレス、つまり最長一致を選択します。
ループバックアドレスは、同一コンピュータ上のプログラム間でネットワーク通信を行う際に使用されるデフォルトアドレスです。
コンピュータは特別な IP アドレス127.0.0.1 をループバックアドレスとして使用します。このアドレスと同じ意味を持つのは、localhost
というホスト名です。この IP またはホスト名を使用すると、データパケットはネットワークに流れません。
IP の分割と再構成#
各種データリンクの最大伝送単位MTU
は異なります。例えば、FDDI データリンクの MTU は 4352、イーサネットの MTU は 1500 バイトなどです。
各種データリンクの MTU が異なるのは、異なるタイプのデータリンクの使用目的が異なるためです。使用目的が異なると、許容される MTU も異なります。
IP データパケットのサイズが MTU を超えると、IP データパケットは分割されます。
分割された IP データグラムは、再構成時にのみ宛先ホストによって行われ、ルーターは再構成を行いません。
分割転送中に、ある分割が失われると、全体の IP データグラムが無効になります。したがって、TCP はMSS
を導入し、TCP 層で分割を行い、IP 層での分割を行わないようにします。UDP の場合、できるだけMTU
を超えるデータグラムを送信しないようにします。
IPv6 の基本的な理解#
IPv4 アドレスの長さは 32 ビット(4 バイト)で、8 ビットごとにグループ化され、ドット区切りの 10 進数で表現されます。
IPv6 アドレスの長さは 128 ビット(16 バイト)で、16 ビットごとにグループ化され、各グループはコロン「:」で区切られます。
連続する 0 がある場合、これらの 0 を省略し、2 つのコロン「::」で区切ることができます。ただし、1 つの IP アドレス内で 2 つの連続したコロンが出現するのは 1 回のみ許可されます。
IPv6 は単に割り当て可能なアドレスが増えただけでなく、非常に多くの利点があります。
- IPv6 は自動構成が可能で、DHCP サーバーがなくても自動的に IP アドレスを割り当てることができ、プラグアンドプレイの便利さを提供します。
- IPv6 のパケットヘッダーの長さは固定値
40
バイトで、ヘッダーチェックサムが削除され、ヘッダー構造が簡素化され、ルーターの負荷が軽減され、伝送性能が大幅に向上します。 - IPv6 には、偽造 IP アドレスに対するネットワークセキュリティ機能や、回線盗聴を防ぐ機能があり、セキュリティが大幅に向上します。
- ...
IPv6 は IPv4 に比べてヘッダーが改善されています:
- ヘッダーチェックサムフィールドが削除されました。 データリンク層とトランスポート層でチェックが行われるため、IPv6 は IP のチェックを直接削除しました。
- 分割 / 再構成に関連するフィールドが削除されました。 分割と再構成は時間のかかるプロセスであり、IPv6 では中間ルーターでの分割と再構成が許可されておらず、この操作はソースと宛先ホストでのみ行うことができ、ルーターの転送速度が大幅に向上します。
- オプションフィールドが削除されました。 オプションフィールドは標準 IP ヘッダーの一部ではなくなりましたが、消えたわけではなく、IPv6 ヘッダー内の「次のヘッダー」で指摘された位置に現れる可能性があります。オプションフィールドを削除することで、IPv6 のヘッダーは固定長の
40
バイトになります。
IP プロトコル関連技術#
DNS ドメイン名解決#
DNS はドメイン名のウェブサイトを自動的に具体的な IP アドレスに変換できます。
ドメイン名の階層関係は木構造に似ています:
- ルート DNS サーバー
- トップレベルドメイン DNS サーバー(com)
- 権威 DNS サーバー(server.com)
ブラウザはまず自分のキャッシュにあるかどうかを確認し、なければオペレーティングシステムのキャッシュを確認し、まだなければローカルのドメイン名解決ファイルhosts
を確認し、それでもなければ DNS サーバーに問い合わせを行います。問い合わせのプロセスは以下の通りです:
- クライアントは最初に DNS リクエストを発信し、www.server.comの IP は何かを尋ね、本地 DNS サーバー(クライアントの TCP/IP 設定に記載された DNS サーバーのアドレス)に送信します。
- 本地 DNS サーバーはクライアントのリクエストを受け取った後、キャッシュ内の表にwww.server.comが見つかれば、直接 IP アドレスを返します。見つからなければ、本地 DNS はルート DNS サーバーに「おお、www.server.comの IP アドレスを教えてくれませんか?」と尋ねます。ルート DNS サーバーは最上位のもので、直接ドメイン名解決には使用されませんが、道を指し示すことができます。
- ルート DNS は本地 DNS からのリクエストを受け取ると、後置が.com であることを確認し、「www.server.comは.com エリアが管理している」と言い、.com トップレベルドメインサーバーのアドレスを教えてくれます。
- 本地 DNS はトップレベルドメインサーバーのアドレスを受け取った後、「おお、www.server.comの IP アドレスを教えてくれませんか?」と尋ねます。
- トップレベルドメインサーバーは、「www.server.comエリアの権威 DNS サーバーのアドレスを教えます。あなたはそれに聞いてみてください」と言います。
- 本地 DNS は権威 DNS サーバーに転向し、「おお、www.server.comの IP は何ですか?」と尋ねます。server.com の権威 DNS サーバーは、ドメイン名解決結果の元の出所です。なぜ権威と呼ばれるのか?それは私のドメイン名は私が主導権を握っているからです。
- 権威 DNS サーバーは照会後、対応する IP アドレス X.X.X.X を本地 DNS に伝えます。
- 本地 DNS は IP アドレスをクライアントに返し、クライアントはターゲットと接続を確立します。
DNS ドメイン名解決のプロセスは、日常生活で人に道を尋ねるプロセスに似ています。道を指し示すだけで、案内はしません。
ARP アドレス解決プロトコル#
ARP はネットワーク層アドレスを解析してデータリンク層アドレスを探すネットワーク伝送プロトコルです。
ARP はARP リクエストと ARP レスポンスの 2 種類のパケットを使用して MAC アドレスを特定します。
- ホストはブロードキャストで ARP リクエストを送信します。このパケットには、知りたい MAC アドレスのホスト IP アドレスが含まれています。
- 同じリンク内のすべてのデバイスが ARP リクエストを受信すると、ARP リクエストパケットの内容を確認します。もし ARP リクエストパケット内のターゲット IP アドレスが自分の IP アドレスと一致する場合、そのデバイスは自分の MAC アドレスをARP レスポンスパケットに入れてホストに返します。
オペレーティングシステムは通常、最初に ARP を介して取得した MAC アドレスをキャッシュしておき、次回はキャッシュから対応する IP アドレスの MAC アドレスを直接見つけることができます。
ARP プロトコルは、既知の IP アドレスから MAC アドレスを求めるものであり、RARP プロトコルはその逆で、既知の MAC アドレスから IP アドレスを求めます。
さらに、送信ホストと宛先ホストが同じローカルエリアネットワークにない場合、相手の MAC アドレスを知っていても、直接通信することはできず、ルーターを介して IP 層で転送する必要があります。ルーターはこのローカルエリアネットワークをデータリンク層で隔離しています(ネットワーク層での明示的な転送を行わない限り、ルーターは一つのローカルエリアネットワーク内のイーサネットフレームを自動的に別のローカルエリアネットワークや外部ネットワークに転送しません。自動転送が可能であれば、どれほど恐ろしいことか想像できます。無効なブロードキャストフレームが洪水のようにネットワーク全体を浸水させ、ネットワークが麻痺する可能性があります。これもルーターの基本機能の一つです。ネットワークを隔離します)。この場合、送信ホストはゲートウェイ IP アドレスを目的の IP アドレスとして使用します(これは IP 層で決定されます)。このため、ARP プロトコルを介して得られるのは目的ホストの真の MAC アドレスではなく、ローカルエリアネットワークの外に通じるルーターの MAC アドレスになります。その後、送信ホストが目的ホストに送信するすべてのフレームは、そのルーターに送信され、外部に送信されます。この状況は委託 ARP または **ARP プロキシ(ARP Proxy)** と呼ばれます。
DHCP 動的ホスト設定プロトコル#
DHCP はネットワーク管理者が IP ネットワークアドレスを集中管理し、自動的に割り当てることを可能にする通信プロトコルです。
DHCP クライアントプロセスは 68 ポート番号をリッスンし、DHCP サーバープロセスは 67 ポート番号をリッスンします。
- クライアントは最初にDHCP 発見メッセージ(DHCP DISCOVER)の IP データグラムを発信します。クライアントは IP アドレスを持っておらず、DHCP サーバーのアドレスも知らないため、UDP のブロードキャスト通信を使用し、ブロードキャストの宛先アドレスは 255.255.255.255(ポート 67)であり、ソース IP アドレスは 0.0.0.0(ポート 68)です。DHCP クライアントはこの IP データグラムをリンク層に渡し、リンク層はフレームをネットワーク内のすべてのデバイスにブロードキャストします。
- DHCP サーバーは DHCP 発見メッセージを受け取ると、DHCP 提供メッセージ(DHCP OFFER)でクライアントに応答します。このメッセージも IP ブロードキャストアドレス 255.255.255.255 を使用し、メッセージ情報にはサーバーが提供するリース可能な IP アドレス、サブネットマスク、デフォルトゲートウェイ、DNS サーバー、およびIP アドレスのリース期間が含まれています。
- クライアントは 1 つまたは複数のサーバーからの DHCP 提供メッセージを受け取った後、1 つのサーバーを選択し、選択したサーバーに **DHCP リクエストメッセージ(DHCP REQUEST)** を送信して応答します。設定されたパラメータをエコーします。
- 最後に、サーバーはDHCP ACK メッセージで DHCP リクエストメッセージに応答し、要求されたパラメータを確認します。
クライアントが DHCP ACK を受け取ると、インタラクションが完了し、クライアントはリース期間内に DHCP サーバーが割り当てた IP アドレスを使用できます。
リースされた DHCP IP アドレスが期限切れに近づくと、クライアントはサーバーに DHCP リクエストメッセージを送信します:
- サーバーがリースを継続することに同意すれば、DHCP ACK メッセージで応答し、クライアントはリース期間を延長します。
- サーバーがリースを継続しない場合、DHCP NACK メッセージで応答し、クライアントはリースされた IP アドレスの使用を停止します。
DHCP インタラクションでは、全過程で UDP ブロードキャスト通信が使用されます。
DHCP リレーエージェントがあれば、異なるサブネットの IP アドレスの割り当ても 1 つの DHCP サーバーで集中管理できます。
- DHCP クライアントは DHCP リレーエージェントに DHCP リクエストパケットを送信し、DHCP リレーエージェントはこのブロードキャストパケットを受け取った後、ユニキャストの形式で DHCP サーバーに送信します。
- サーバーはこのパケットを受け取った後、DHCP リレーエージェントに応答を返し、DHCP リレーエージェントはこのパケットを DHCP クライアントにブロードキャストします。
そのため、DHCP サーバーは同じリンク上にいなくても、IP アドレスの統一的な割り当てと管理を実現できます。
NAT ネットワークアドレス変換#
ネットワークアドレス変換(英語:Network Address Translation、略称:NAT)、または IP 動的擬装(英語:IP Masquerade)は、IP データパケットがルーターやファイアウォールを通過する際に、送信元または宛先の IP アドレスやポートを再書き込みする技術です。この技術は、複数のホストが 1 つの公有 IP アドレスを介してインターネットにアクセスするプライベートネットワークで広く使用されています。
簡単に言えば、NAT は同じ会社、家庭、教室内のホストが外部と通信する際に、プライベート IP アドレスを公有 IP アドレスに変換します。
IP アドレス + ポート番号を一緒に変換することもできます。これにより、1 つのグローバル IP アドレスを使用できます。この変換技術をネットワークアドレスとポート変換 NAPTと呼びます。
NAPT ルーターの変換テーブルは、アドレスとポートの組み合わせを正しく変換できます。
NAT/NAPT は自分の変換テーブルに依存しているため、以下の問題が発生します:
- 外部は NAT 内部のサーバーに対して積極的に接続を確立できません。なぜなら、NAPT 変換テーブルに変換記録がないからです。
- 変換テーブルの生成と変換操作は性能オーバーヘッドを生じます。
- 通信中に NAT ルーターが再起動すると、すべての TCP 接続がリセットされます。
解決策は主に 2 つの方法があります。
-
第一の方法は IPv6 に切り替えることです。
-
NAT トンネリング技術
NAT トンネリング技術では、NAT デバイスの後ろにあるアプリケーションプログラムが能動的な立場にあり、NAT デバイスが外向きのデータパケットを変更することを明確に理解しています。したがって、NAT デバイスの操作に積極的に協力し、マッピングを自ら確立します。これにより、以前のように NAT デバイスがマッピングを確立する必要がなくなります。
クライアントは NAT デバイスから公有 IP アドレスを取得し、自らポートマッピングエントリを確立し、そのエントリを使用して外部と通信します。これにより、NAT デバイスが変換を行う必要がなくなります。
ICMP#
ICMP の正式名称はInternet Control Message Protocol、すなわちインターネット制御メッセージプロトコルです。
ICMP
の主な機能には、IP パケットがターゲットアドレスに成功裏に送達されたかどうかを確認し、送信中に IP パケットが廃棄された理由を報告し、ネットワーク設定を改善することが含まれます。
ICMP は大きく 2 つのカテゴリに分けられます:
- 一つは診断用のクエリメッセージ、すなわち「クエリメッセージタイプ」
- もう一つはエラーの原因を通知するエラーメッセージ、すなわち「エラーメッセージタイプ」
IGMP#
IGMP はインターネットグループ管理プロトコルであり、ホスト(マルチキャストメンバー)と最後のホップルーター間で動作します。
- IGMP メッセージはルーターにマルチキャストグループへの参加と退出を要求します。デフォルトでは、ルーターは接続されたホストにマルチキャストパケットを転送しません。ホストが IGMP を介してマルチキャストグループに参加することを要求すると、ルーターは IGMP ルーターテーブルに記録します。ルーターはその後、マルチキャストパケットを対応するホストに転送します。
- IGMP メッセージは IP でカプセル化され、IP ヘッダーのプロトコル番号は 2 であり、TTL フィールドの値は通常 1 です。なぜなら、IGMP はホストと接続されたルーター間で動作するからです。
マルチキャストアドレスは機械の IP アドレスに使用されず、マルチキャストアドレスにはネットワーク番号とホスト番号がないため、DHCP とは関係ありません。マルチキャストアドレスは一般に UDP プロトコルに使用され、機械が UDP マルチキャストデータを送信する際、ターゲットアドレスにはマルチキャストアドレスが記入され、マルチキャストグループ内の機械はすべてデータパケットを受信できます。
マルチキャストグループに参加するか離れるかは、ソケットのインターフェースを介して実現され、ホスト IP は変更されません。
その他#
- OSPF(Open Shortest Path First、オープン最短経路優先):内部ゲートウェイプロトコル(Interior Gateway Protocol、IGP)の一種であり、広く使用されている動的ルーティングプロトコルで、リンク状態アルゴリズムに基づいており、リンクの帯域幅、遅延などの要因を考慮して最適な経路を選択します。
- RIP(Routing Information Protocol、ルーティング情報プロトコル):内部ゲートウェイプロトコル(Interior Gateway Protocol、IGP)の一種であり、距離ベクトルアルゴリズムに基づく動的ルーティングプロトコルで、固定のホップ数をメトリックとして使用し、ホップ数が最も少ない経路を最適な経路として選択します。
- BGP(Border Gateway Protocol、境界ゲートウェイプロトコル):ルーティング選択ドメイン間でネットワーク層の到達可能性情報(Network Layer Reachability Information、NLRI)を交換するためのルーティング選択プロトコルで、高度な柔軟性と拡張性を持っています。