SYN クッキー:接続テーブルを使わない SYN フラッド防御
なぜ偽の SYN を大量に浴びてもメモリが枯れないのかが原理から腑に落ちる。状態を持たずシーケンス番号にハッシュを埋め込む SYN クッキーの計算と検証、そして失われる機能まで押さえる。
- 1.SYN フラッドは偽の SYN で half-open 接続を量産し、サーバーの SYN キュー(接続テーブル)を枯渇させて正規接続を弾く攻撃。
- 2.SYN クッキーは SYN-ACK を返した時点で状態を一切保存せず、初期シーケンス番号 ISN にタイムスタンプとハッシュを符号化する。戻ってきた ACK の番号から状態を再構築して検証する。
- 3.代償として MSS の表現幅が狭まり、ウィンドウスケールや SACK 等の TCP オプションが原則失われる。常時有効ではなくキュー溢れ時のみ作動させるのが定石。
SYN フラッドはなぜサーバーを落とせるのか
3ウェイハンドシェイクでは、サーバーはクライアントの SYN を受け取ると SYN-ACK を返し、最終 ACK が来るまでその接続を half-open(半開) として保持します。この保持に使われるのが SYN キュー(バックログ)と呼ばれる接続テーブルで、各エントリには相手のIP・ポート・受信した SYN のシーケンス番号・選択されたオプションなどが記録されます。
攻撃者はここを突きます。送信元IPを偽装した SYN を大量に送りつけると、サーバーはそれぞれに SYN-ACK を返してエントリを確保しますが、偽装元からは最終 ACK が永遠に来ません。エントリは再送タイムアウトまで滞留し、わずか数千〜数万の偽 SYN で SYN キューが満杯になります。満杯になれば新規 SYN は捨てられ、正規ユーザーが接続できなくなる――これが SYN フラッド(half-open 枯渇攻撃)です。ハンドシェイクと half-open の遷移は /network/tcp-state-machine/ に詳しくまとめています。
SYN フラッドの本質は回線帯域の飽和ではなく、サーバー側の有限な状態テーブルの消費です。送信元偽装を使う点は増幅型DDoSと共通ですが(/network/ddos-amplification/ 参照)、狙うのは帯域でなくメモリ資源である点が異なります。だからこそ「状態を持たない」ことが直接の対策になります。
発想の転換:状態を ISN に埋め込む
SYN クッキーのアイデアは単純で強力です。SYN-ACK を返すときに エントリを一切作らない。代わりに、本来テーブルに保存すべき情報を、SYN-ACK が運ぶ 初期シーケンス番号(ISN)そのものに符号化 してしまう。
TCP では、相手はこちらの ISN に1を足した値を ACK 番号として返す決まりです。つまり最終 ACK のヘッダには、サーバーが選んだ ISN がそっくり戻ってきます。サーバーはその戻り値を復号すれば「自分が確かにこの相手へ SYN-ACK を返したこと」と「そのとき選んだ MSS」を、テーブルを引かずに再構成できます。状態をサーバーのメモリではなく ネットワーク上を往復するパケットに退避 させた、と言い換えられます。
ISN は32ビットしかないので、ここに全情報は入りません。実装(Linux など)はおおむね次の構成を取ります。
ISN(32bit)の内訳:
上位 5bit : t … 64秒刻みの粗いカウンタ(リプレイ有効期間の判定用)
次 3bit : m … 選んだ MSS を 8 段階のインデックスに量子化した値
下位 24bit: h … 秘密鍵を含むハッシュの下位 24bit
h = MAC( 秘密鍵, 送信元IP, 送信元ポート, 宛先IP, 宛先ポート, t, m )
ハッシュ h には接続を一意に決める4タプルと時刻 t・MSS インデックス m が入力されます。秘密鍵はサーバーだけが知るため、攻撃者は正しい h を作れません。
検証手順:戻ってきた ACK をどう確かめるか
最終 ACK が届くと、サーバーは ACK 番号から1を引いて元の ISN を取り出し、次の手順で検証します。
| 手順 | やること | 失敗したら |
|---|---|---|
| 1. 時刻検査 | ISN の t と現在時刻の差を見て、許容窓内かを確認 | 古すぎる ACK は破棄(リプレイ防御) |
| 2. ハッシュ再計算 | 受信パケットの4タプルと t・m から h を計算し直す | 下位24bitが一致しなければ偽造として破棄 |
| 3. MSS 復元 | 一致したら m を MSS 実値に戻して接続を確立 | 正当な ACK なので ESTABLISHED へ遷移 |
重要なのは、検証に必要な4タプルは 受信した ACK パケット自身のヘッダに全部書いてある ことです。サーバーは保存しておいた何かと突き合わせるのではなく、その場で同じ計算を再実行して一致を確かめます。一致すれば「秘密鍵を知る自分が、この相手に、この時刻に SYN-ACK を出した」ことが暗号学的に保証され、初めて接続テーブルにエントリを作ります。偽装 SYN にはそもそも ACK が返らないので、テーブルは1ミリも消費されません。
攻撃者が ACK を完成させるには正しい ISN が必要ですが、ISN は秘密鍵入りハッシュを含むため推測できません。さらに偽装した送信元IPには SYN-ACK が届かないので ISN を観測することもできない。結果、3ウェイを完走できるのは「自分宛ての SYN-ACK を実際に受け取れる本物の相手」だけに絞られます。これは送信元IPの到達性検証も兼ねています。
機能制限:タダではない
状態を捨てる代償として、本来 SYN キューに保存していた情報のうち、ISN に符号化しきれないものが失われます。これが SYN クッキーの実務上の弱点です。
- MSS の粒度低下:MSS は3ビット8段階のインデックスに丸められます。受信した値そのものではなく、代表値の近似になります。
- TCP オプションの喪失:ウィンドウスケール、SACK 許可、タイムスタンプといった SYN で交渉されるオプションは、保存場所が無いため原則として復元できません。ウィンドウスケールが落ちれば受信ウィンドウが64KB上限に張り付き、高帯域・高遅延の経路でスループットが頭打ちになります。SACK が落ちれば再送効率も下がります(/network/tcp-retransmission/ 参照)。
オプション喪失の影響は通常時の性能に直結するため、SYN クッキーは「常に有効」ではなく SYN キューが溢れたときだけ作動 させるのが定石です。Linux の net.ipv4.tcp_syncookies=1 は「平常時は通常のバックログを使い、満杯になった分にだけクッキーを発行する」フォールバック動作を意味します(=2 で常時、=0 で無効)。攻撃を浴びている間だけ性能を多少犠牲にして可用性を守る、というトレードオフです。
近年の Linux はタイムスタンプオプションが使える場合、ウィンドウスケールや SACK の有無をタイムスタンプの下位ビットに退避させることで、オプション喪失をある程度緩和します。ただしこれは相手がタイムスタンプを送ってくる場合に限られ、原理上の制約(ISN 24bit のハッシュ強度、MSS の量子化)は残ります。
「SYN フラッドが枯渇させるのは」→ 帯域でなく SYN キュー(half-open 接続テーブル)。「SYN クッキーが状態を持たない理由は」→ 情報を ISN に符号化し往復パケットに退避するから。「検証方法は」→ 戻った ACK の4タプルと秘密鍵からハッシュを再計算し ISN と照合。「代償は」→ MSS の量子化と TCP オプション(ウィンドウスケール/SACK)の喪失。「運用は」→ 常時でなくキュー溢れ時のみ作動。この5点が即答できれば上級。
まとめ
SYN クッキーは「攻撃が枯渇させる資源そのものを使わない」という発想で SYN フラッドを無力化します。SYN-ACK 時点では一切の状態を保存せず、保存すべき情報を秘密鍵入りハッシュとして ISN に畳み込む。戻ってきた ACK の番号を復号・再計算して検証が通ったときだけ、初めて本物の接続テーブルを確保する。これにより偽装 SYN は ACK を返せず、テーブルを1バイトも消費できません。代償は MSS の粒度と TCP オプションであり、だからこそ平常時は使わずキュー溢れ時のフォールバックとして働かせる――この「状態の外出し」と「条件付き作動」の両輪を理解しているかが、ステートレス防御を使いこなす分かれ目です。
ネットワーク Article
SYN クッキー:接続テーブルを使わない SYN フラッド防御を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
TCP
比較で見る軸
難易度: advanced / カテゴリ: ネットワーク / タグ数: 6
導入後に効く点
SYN クッキーは SYN-ACK を返した時点で状態を一切保存せず、初期シーケンス番号 ISN にタイムスタンプとハッシュを符号化する。戻ってきた ACK の番号から状態を再構築して検証する。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- ネットワーク
- タグ数
- 6
判断チェックリスト
- 自社の用途が「TCP / SYNフラッド」に近いか確認する。
- 強みである「SYN フラッドは偽の SYN で half-open 接続を量産し、サーバーの SYN キュー(接続テーブル)を枯渇させて正規接続を弾く攻撃。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。