現場の最前線で「SYNフラッディング」を迎え撃つ:ソケットバッファが悲鳴を上げる時
深夜のデータセンター。監視モニターが突如として深紅に染まり、アラートが鳴り響く。Web APIのレイテンシが急上昇し、リクエストがタイムアウトしていく。そんな時、ベテランのエンジニアがまず疑うのは「ネットワークの飽和」ではなく、OSの「ソケットの息切れ」だ。
今日は、現代のインフラ運用において避けられない脅威の一つ、SYNフラッディングによるリッスンキューの枯渇と、その泥臭い現場の診断手法について話をしよう。
—
1. なぜ「SYN_RECV」でサーバーが沈むのか
まず、TCPのハンドシェイクを思い出してほしい。クライアントから SYN が届き、サーバーは SYN-ACK を返し、クライアントからの ACK を待つ。この「待ち」の状態が SYN_RECV だ。
正常な通信なら一瞬で終わるこのプロセスだが、攻撃者は SYN を投げつけるだけで、最後の ACK を決して返さない。サーバーは「返事が来るはずだ」と信じて、メモリ上のキュー(backlog)にその接続情報を保持し続ける。このキューが満杯になると、正当なユーザーからの接続さえも Connection refused やタイムアウトで弾き飛ばされる。これが、SYNフラッディングの正体だ。
—
2. 現場の眼:ssコマンドで「異常」を嗅ぎ取る
パケットキャプチャを仕掛ける前に、まずは ss コマンドでカーネルの状態を確認するのがプロの流儀だ。netstat も悪くはないが、現代の高速なLinux環境では、より詳細な情報を高速に引き出せる ss を推奨する。
# SYN_RECVの状態にあるコネクションをカウントする
ss -nt state syn-recv | wc -l
# 特定のポートへの接続状態を詳細にダンプする
ss -nlt sport = :80 | grep SYN-RECV
もしここで、普段のトラフィック量からは考えられない数の SYN-RECV が並んでいたら、それはもう「異常事態」のサインだ。
—
3. カーネルパラメータで「防波堤」を築く
攻撃が始まってから慌ててパッチを当てるのは得策ではない。あらかじめカーネルパラメータをチューニングし、この「半開きの接続」からシステムを守る防波堤を築いておこう。特に重要なのが tcp_syncookies だ。
/etc/sysctl.conf に以下の設定を追記し、sysctl -p で反映させるのが定石だ。
# SYN Cookieを有効化:キューが溢れそうになったらCookieで認証し、メモリ消費を抑える
net.ipv4.tcp_syncookies = 1
# SYN-ACKの再送回数を減らす(攻撃によるリソース枯渇を早めるのを防ぐ)
net.ipv4.tcp_synack_retries = 2
# SYNを受け付けるバックログのサイズを拡大する
net.ipv4.tcp_max_syn_backlog = 2048
特に tcp_syncookies は魔法のような機能だ。本来ならメモリに保存すべき接続情報を、SYN-ACK のシーケンス番号に埋め込んでクライアントに送り返す。正当なクライアントなら ACK でその値が返ってくるため、サーバーはそこで初めてメモリを割り当てる。これにより、メモリを無駄に占有する攻撃者を無力化できる。
—
4. アプリ側からの「死活監視」:Pythonでパルスを測る
インフラ側で防御を固めつつ、アプリ層から見た疎通状況も監視しておこう。curl で叩くのもいいが、Pythonで簡単なスクリプトを書いておくと、障害時の切り分けが格段に早くなる。
import requests
from requests.exceptions import ConnectTimeout
# ターゲットURL
url = "http://api.example.com/health"
try:
# 接続タイムアウトを短めに設定し、反応の鈍さを早期検知する
response = requests.get(url, timeout=2.0)
print(f"Status: {response.status_code}")
except ConnectTimeout:
print("警告: サーバーが応答不能です。SYNキューが溢れている可能性があります。")
except Exception as e:
print(f"エラー発生: {e}")
—
最後に:エンジニアとしての心構え
SYNフラッディングは、単に「パケットを遮断すればいい」という単純な話ではない。ロードバランサーの配下にあるのか、ファイアウォールの設定はどうなっているのか、そして何より「どの程度のリソースを攻撃者に明け渡してしまっているか」を冷静に判断する力が求められる。
教科書的な知識だけでは、現場の「謎の重さ」は解けない。まずは ss でコネクションの状態を覗き、カーネルがどこで悲鳴を上げているのかを見極めること。それが、復旧への最短ルートだ。
トラブルは必ず起きる。だが、それに対応する備えと知識があれば、それはただの「一時的な現象」に過ぎない。さあ、次は君のサーバーの backlog を確認してみようか。
コメント