パケットがノート PC を離れ、VPN ゲートウェイに届くこともなく、ファイアウォールのカウンタも動かない。ルートテーブルがすでにパケットの運命を決めていた。blackhole エントリが一致し、どのインターフェースが見る前にもカーネルがそれを破棄したのだ。この振る舞いは、宛先を閉じた状態で失敗させたいときには有用だが、範囲の狭いルーティング操作にすぎない。これを完全なキルスイッチと見なすことが、設計が誤る地点である。

破棄アクションが実際に一致させるもの

ルート検索はテーブルを選び、その中で 最長一致プレフィックス を選ぶ。blackhole ルートはアクションが破棄である通常のエントリなので、決定全体を経た後にそのエントリを選ぶパケットにしか影響しない。ポリシールールでテーブルを変えるか、より具体的なプレフィックスを追加すれば、破棄は適用されなくなる。

だから blackhole の範囲は正確で、説明しやすい。そのアドレスファミリについて、テーブル内のプレフィックスを覆う。別のテーブルが勝つ宛先は覆わず、IPv4 プレフィックスを破棄しているからという理由だけで IPv6 を覆うこともない。

ip route get は、何も配備する前に、テーブルとルート種別を含む決定を表示する。その出力を読むほうが、失敗した要求からどのルールやプレフィックスが効いたかを推測するより速い。

blackhole は unreachable や prohibit とは同じではない

Linux は破棄に似た三つのルート種別を提供し、送信側が観測する内容が異なる。blackhole は応答なしでパケットを捨てるので、クライアントはタイムアウトを見る。unreachable ルートは ICMP unreachable メッセージを返すので、接続はホストまたはネットワークのエラーで素早く失敗する。prohibit ルートは管理上の禁止エラーを返し、意図的なポリシー拒否に近い。

アプリケーションに見せたい振る舞いを選ぶ。ポリシーを明かしたくないときは静かな破棄が適切であり、利用者が宛先に到達できない理由を理解する必要があるときは即時のエラーがよい。種別をネットワーク全体で混在させると、同じポリシーを三つの異なる障害として説明するサポートチケットが生まれる。

接続を診断するとき、すべての破棄エントリが交換可能だと決めつけてはいけない。エラーの文言、タイミング、パケットキャプチャは異なり、テーブル内のルート種別がどれを見ているかを教えてくれる。ip-route のマニュアル には種別とそのエラー時の振る舞いが列挙されている。

キルスイッチとの比較

キルスイッチはパケットフィルタリングであり、トンネルの外へ出るはずの外向き通信を落とすファイアウォールルールである。blackhole ルートはスタックのより早い段階で下される転送の決定である。どちらも通信を止められるが、見えるものが違い、取りこぼすケースも違う。

MechanismWhat it blocksWhat it missesHow failure looks
Blackhole routeDestinations matching the prefix and tableOther tables, other address families, traffic with a different routeSilent timeout
Firewall kill switchEgress not bound to the tunnel interfaceRules that are too broad can break the endpoint or DHCPDropped packets with counters
WireGuard AllowedIPsDestinations not routed into the interfaceTraffic that never enters the interface at allNo tunnel route, direct egress

比較が意味を持つのは適用範囲である。ファイアウォールは所有者、ポート、インターフェースに一致でき、エンドポイントを到達可能なままアプリケーションを遮断できるが、ルートにはできない。逆に、ルートはパケットフィルタを一つも読み込まずにプレフィックス全体を破棄へ送れる。これは最小構成のシステムでは有用である。

WireGuard の AllowedIPs は暗号鍵ルーティングであり、ファイアウォールではない。どの宛先プレフィックスをインターフェースに受け入れるかを決めるもので、トンネルのサブネットだけを列挙したプロファイルは他の宛先を通常のデフォルトルートに委ねる。だからこそフルトンネルのプロファイルは 0.0.0.0/0 を使い、wg-quick も可能なときはファイアウォールルールをインストールする。

トンネルのエンドポイントを破棄の外に置く

エンドポイントの外側アドレスは物理インターフェース経由で到達可能なままでなければならない。そのアドレスまで捕捉する破棄はハンドシェイクの送出を妨げ、トンネルは決して上がらない。これはルーティングポリシーではなく VPN の障害に見える。変更の前後でエンドポイントへのルートを確認すること。

管理アクセスも同じレビューに含める。ルータやクライアントへの唯一の経路がトンネルなら、広すぎる破棄はそれを外すためのマシンからあなたを締め出す。文書化された帯域外の経路、コンソール、または時間制限付きのロールバックを用意しておく。

IPv6 には独自のエントリと独自のレビューが必要である。IPv4 を blackhole に送りながら IPv6 をデフォルトルートに残す設計は、ポリシーが止めるはずだった通信をまさに漏らし、その誤りは IPv4 だけの試験では見えない。

タイマーとロールバックで段階的に導入する

短い自動削除とともにルートを適用し、誤りが再起動を越えて残らないようにする。以下のコマンドは文書用の範囲を使っている。設計が実際に破棄するプレフィックスに置き換えること。

sudo ip route replace blackhole 10.0.0.0/8
ip route get 10.1.2.3
sudo systemd-run --on-active=60 /sbin/ip route del blackhole 10.0.0.0/8

二番目のコマンドは blackhole ルートとその由来のテーブルを報告するはずである。三番目は一分後の削除を予定する。ポリシーを確認するのに十分な時間であり、遠隔ホストでの誤りから復旧するのに十分短い。振る舞いが確認できたら、他のルートを管理しているのと同じ構成管理でエントリを永続化する。

プレフィックス、テーブル、アドレスファミリ、ロールバック方法を記録して変更を閉じる。破棄はルーティング設計における意図的な例外であり、次のエンジニアはそれがまだ必要かを決める前に、どの通信を止めるためのものだったかを知る必要がある。

関連記事