3ウェイハンドシェイクの全体像と実務ポイント|TCPの接続確立・シーケンス番号・セキュリティ対策を詳解

3ウェイハンドシェイクとは

3ウェイハンドシェイク(three-way handshake)は、TCP(Transmission Control Protocol)におけるコネクション確立の手順を指します。クライアントとサーバーが双方向の通信を始める前に、双方で初期シーケンス番号(ISN)やオプション(MSS、ウィンドウスケールなど)を交換・同期し、パケットの順序や信頼性を保証するために行われます。手順は「SYN → SYN+ACK → ACK」の3ステップで完了するため、3ウェイ(3往復)と呼ばれます。

基本的な流れ(シーケンス番号の例付き)

  • 1) クライアント → サーバー : SYN
    クライアントは接続要求を示すTCPヘッダのSYNフラグを立て、初期シーケンス番号(ISN)xをセットしてサーバーに送信します。オプション(最大セグメントサイズMSS、ウィンドウスケール、SACK許可、タイムスタンプなど)を含めることができます。

  • 2) サーバー → クライアント : SYN+ACK
    サーバーは受け取ったSYNに応答して、自身のISN y を含むSYNを送り、同時にクライアントのISNに対する確認応答(ACK = x + 1)を返します。これがSYN+ACKパケットです。

  • 3) クライアント → サーバー : ACK
    クライアントはサーバーのISN y に対してACK = y + 1 を送り、これで両端の初期シーケンス番号と受信確認が行われ、コネクションが確立します。以後データ転送が開始されます。

重要な点として、SYN(およびFIN)フラグは1つのシーケンス番号を「消費」します。つまり、サーバーがACKに「x+1」を返すのは、SYNが1バイトの占有を意味するためです。

TCPヘッダで使われる主なフィールド

  • Sequence Number(シーケンス番号):送信するバイト列の位置を示す。ISNはここに入る。

  • Acknowledgment Number(確認応答番号):相手から受け取った次に期待するシーケンス番号。

  • Flags(SYN/ACK/FIN/RSTなど):制御フラグ。コネクション確立/終了/リセット等を指示する。

  • Window(受信ウィンドウ):フロー制御のために相手が受け取れるバイト数。

  • Options(MSS, Window Scale, SACK Permitted, Timestamps 等):接続時に交渉される性能・拡張情報。

なぜ3回のやり取りが必要か(設計意図)

3ウェイハンドシェイクは、次の目的を果たします。

  • 相互のシーケンス番号の同期:双方が送受信するデータの位置(シーケンス番号)を合意することで、後のデータの順序確認や再送制御を可能にします。

  • 古い遅延パケットの誤認防止:古いSYNやACKが新しい接続と混ざらないよう、ISNなどを用いて識別します。

  • オプション交渉:MSS(最大セグメントサイズ)やウィンドウスケール等、性能に関するパラメータを安全に交換します(オプションはSYNパケットで交渉される)。

特殊ケースとバリエーション

  • 同時オープン(Simultaneous Open)
    両端が同時にアクティブオープン(connect)を行った場合、双方がSYNを送信し合い、SYNを受け取ったらSYN+ACKで応答し、最終的にACKで確立されます。TCPの仕様上は想定されていますが、実運用では稀です。

  • TCP Fast Open(TFO)
    RFC 7413で定められた拡張で、過去に接続した相手に対してはSYNにデータを載せて送ることで、ラウンドトリップ遅延の削減を図ります。サーバー側のクッキー(TFO cookie)を事前に取得する必要があります。

  • オプションの交渉失敗や無視
    一方がオプションをサポートしない場合、そのオプションは無効となり、互換性を維持しつつ接続が進行します。

セキュリティ上の注意点(攻撃と対策)

3ウェイハンドシェイクは、攻撃者による悪用の対象になりやすい部分でもあります。

  • SYN Flood(SYNフラッド)
    攻撃者が大量の偽造したSYNを送り、サーバーの「半開(SYN_RECEIVED)」状態のキュー(backlog)を枯渇させることで正規接続を拒否させる攻撃です。IPアドレスを詐称(spoof)することが多く、サーバーはACKを受け取らずにメモリ・リソースを消費します。詳しくは下記参考リンク参照。

  • SYN Cookie
    サーバー側で半開接続の状態をメモリに保存せず、ISNに接続情報を暗号的に埋め込むことでACK受領時にのみ状態を復元する技術です。SYNフラッド耐性のある手法として広く使われています(実装や互換性に注意が必要)。

  • ISNの予測とセッション乗っ取り
    初期シーケンス番号が予測可能だと、攻撃者が接続を乗っ取れる恐れがあります。現在はISNのランダム化(RFC 6528など)や時間ベースでの生成が推奨され、実装上の改善が進みました。

  • RST/ACK偽造やリセット攻撃
    RSTパケットや不正なACKを送り、既存の接続を切断する攻撃もあり得ます。TCPの脆弱性対応(RFC 5961など)やIPレベルのフィルタリングが対策に用いられます。

実装上・運用上のポイント

  • ソケットのbacklog
    サーバーがlisten()で指定するbacklogは半開接続を待つキューの長さに影響します。高負荷環境では適切な値に調整し、SYNフラッド対策と組み合わせる必要があります。

  • タイムアウトと再送
    SYNに対するSYN+ACKが届かない場合、送信側は再送を行います。再送回数や間隔はOSやTCP実装で制御されます。

  • 状態遷移(TCPステートマシン)
    コネクション確立に関連する主な状態は、クライアント側のSYN_SENT、サーバー側のSYN_RECEIVED、確立後のESTABLISHEDです。トラブル時にはnetstatやssでこれらの状態が確認できます。

  • TIME-WAIT状態
    コネクション終了後に片側がTIME-WAIT状態に入るのは、遅延到着したパケットの誤処理を防ぐためです。TIME-WAITは2×MSL(Maximum Segment Lifetime)に相当する時間保たれるのが伝統的な仕様ですが、実装や設定により短縮されることもあります(注意して調整すること)。

診断と観察(実務的なチェック)

3ウェイハンドシェイクの問題を調べるにはパケットキャプチャ(tcpdump, Wireshark)でSYN / SYN+ACK / ACK を追うのが基本です。観察ポイント:

  • SYNが送られているか、SYN+ACKが返ってきているか、最終ACKが来ているか。

  • オプション(MSS, Window Scale, Timestampなど)がSYNに含まれているか。

  • 同一IPから大量のSYNが来ていないか(SYNフラッドの疑い)。

  • サーバー側のSYN_RECEIVEDが多く滞留していないか(netstat/ssで確認)。

まとめ

3ウェイハンドシェイクはTCP接続の安全で信頼性の高い確立を実現する基本機構です。シーケンス番号や確認応答によってデータの順序性と再送制御を保証し、オプションの交渉を可能にします。一方で、SYNフラッド等の攻撃に対する脆弱性も持つため、実運用ではSYN cookie、適切なbacklog設定、ISNランダマイズなどの対策が重要になります。実務ではパケットキャプチャを使ってハンドシェイクの各ステップを確認し、異常があればOSのTCP設定やネットワーク機器のフィルタを調整して対処します。

参考文献