WireGuard を守るために IPv6 を遮断するとホストが壊れる
IPv6 をすべて落とす入力ルールは、近隣探索と Packet Too Big も消してしまう。三つの責務を分けてから、ホストが動くか確認する。
目的は妥当だ。このマシンのサービスにはトンネルの利用者だけが届くべきである。よく採られる実装は、WireGuard 以外をすべて落とす IPv6 入力チェーンだが、これはホストを自分のリンクにつなぎ止めている通信も落とす。近隣探索や経路維持のメッセージはサービスへのアクセスではなく、それらを消すと、ポリシーとは無関係な理由で到達不能なマシンができる。トンネルは上がり、サービスは正しく絞られ、リンク上の他の何もが動かない。
三つの責務、一つのルールセット
第一の責務は外部ネットワークの動作だ。ホストは自分のリンクにつながったままで、近隣を解決し、そのリンクの経路限界を知る必要がある。第二は暗号化された待ち受けで、選んだアドレスとポートで UDP を受け付ける。第三は、トンネル利用者に届けたい復号後のサービス群である。
これは三つの別のポリシーであり、VPN に関わるのは第二と第三だけだ。これらを一つとして扱うルールセットは、アプリケーションの境界を締めることがホストの接続を静かに壊すという故障モードを受け継ぐ。
別のチェーン、少なくとも別のコメントに分けておけば、次の人がどの行が何のためにあるか分かる。
ICMPv6 がホストのためにしていること
IPv6 はエコーだけでなく、はるかに多くのことを ICMPv6 に頼っている。近隣要請と近隣広告は ARP を置き換え、ローカル配信に欠かせない。Packet Too Big は経路 MTU の情報を運び、これを無視すると大きなパケットで転送が止まる。リンクが自動設定を使う場合、ルータ広告は既定経路とプレフィックス情報を運ぶ。
RFC 4890 は、ホストのフィルタが必ず許可すべきメッセージと、運用上の選択に属するメッセージを分けており、それはネットワーク間を転送するルータの規則とは別のホスト向けの節で示されている。転送の節だけを読むと、守るべきホストにとって厳しすぎる入力ポリシーができあがる。
実務的な規則は、必要なインターフェースで重要なエラーと設定のメッセージを許可し、プラットフォームが許す範囲で種類と送信元によって絞り、残りについては明示的に決めることだ。
それをすべて包括的な ICMPv6 の許可に置き換えれば、可用性の問題は解けるがフィルタリングを失う。包括的な遮断に置き換えれば、フィルタリングの問題は解けるがホストを失う。
まずトンネルを通し、次にサービスを通す
意図した外部アドレスと UDP ポートで WireGuard の通信を受け入れ、戻りの通信はコネクション追跡で受け入れる。そのうえで、トンネルインターフェース経由でアプリケーションのサービスを、実際に許可した送信元から通す。
外部 UDP ポートの許可は、その中の復号済みの要求を許可しない。この区別こそが、サービス規則にトンネルインターフェースが現れる理由のすべてだ。
sudo nft list ruleset
ip -6 addr show
ip -6 route show default
物理アドレスでの待ち受けは、トンネルアドレス上の同じサービスとは別の露出である。マシンが別のマシンへも転送しているなら、それはこの入力ポリシーではなく転送チェーンの判断であり、独自の根拠が要る。
トンネルだけでなく、リンクを試す
変更後にトンネルが動いても、見た目ほど証明にならない。既存の近隣エントリと確立済みの接続が、いまポリシーが落としている制御メッセージを隠せるからだ。
接続を直接確かめ、そのうえで除外した経路が今も失敗することを確かめる。
ip -6 neigh show
ping -6 -c 3 2001:db8:1::1
sudo nft -c -f /etc/nftables.conf
再起動後も近隣テーブルが完全なままなら、探索はまだ働いている。空になって二度と埋まらないなら、除外してしまった証拠だ。三つ目のコマンドはルールセットを適用せずに構文を検証する。セッションが残っているうちにやっておく価値がある。
自分を締め出したホストを復旧する
自分の管理セッションを運ぶファイアウォール規則を変える前に、第二の経路を用意する。コンソール、シリアル接続、あるいは取り消さなければ新しい規則を外す予約済みのロールバックだ。
もし本当に締め出されたら、復旧はその経路を通るのであって、たったいま外したネットワークを通るのではない。保存した複製から以前のルールセットを戻し、ホストに再び届くことを確認し、それから初めて意図したポリシーを小さな単位で適用する。
最終的なポリシーは普遍ではない。アドレス構成、ルーティング、ファイアウォールの実装は配備ごとの入力だが、境界はどこでも同じだ。許可されたトンネルを運ぶ制御トラフィックを保ちながら、意図しないアプリケーションアクセスを拒否する。