ゲートウェイへの ping は通るのにその先の何にも届かないというのは、トンネルの問題ではなく転送の問題の形です。ゲートウェイへのローカル配送が証明するのは、トンネルが上がりアドレス割り当てが機能したことだけであり、カーネルがあるインターフェースから別のインターフェースへパケットを通すかどうかは何も語りません。sysctl に触れる前に、このマシンがこのトラフィックをルーティングするためのものか確認し、クライアント側インターフェースを持つネットワークコンテキストを特定します。そのうえで、最後に読んだガイドがたまたま見ていた場所ではなく、その場所で値を読みます。

ゲートウェイに到達できることは転送とは別

カーネル内部では二つの別個の判断が行われます。ローカルアドレスへの配送はパケットの旅を終わらせ、転送は別のインターフェースから外へ送り出しますが、この二つ目の判断はネットワーク名前空間ごとに管理されます。ゲートウェイに完全に到達できても転送が無効なことはあり、ping のプロンプトからは二つの故障は同じに見えます。

クライアントのパケットがどのインターフェースに到着し、先の経路がどのインターフェースから出るのかを書き留めます。どちらも一つの名前空間に属し、重要な設定はその名前空間にあります。

パケットが実際にある場所で値を読む

ホスト名前空間でルーティングするゲートウェイでは、一つのコマンドが問いに答えます: sysctl net.ipv4.ip_forward。入り口と先の経路が名前付き名前空間にある場合は、その名前空間に尋ねます: ip netns exec vpn-gw sysctl net.ipv4.ip_forward。ホストの値は名前空間の値の代理ではなく、ホスト側で有効になっていても何の証拠にもなりません。

すべてのルーティングコンテキストに ip netns へ渡せるラベルがあるわけではありません。コンテナランタイムやサービスは、親しみやすい名前で登録されない名前空間を作るので、そうした場合はランタイムの検査ツールを使います。vpn-gw を実際の名前に、または同じコンテキストに到達するランタイムの仕組みに置き換え、ホスト側での推測をやめます。

設定に単一の所有者を与える

従来の systemd ホストゲートウェイでは、永続的な形は管理者が選んだ名前の drop-in ファイルで、たとえば /etc/sysctl.d/60-vpn-forwarding.conf に net.ipv4.ip_forward = 1 を書きます。ファイルを書いたら、その特定のファイルを読み込んで実行中の状態も変えます: sudo sysctl -p /etc/sysctl.d/60-vpn-forwarding.conf、その後に読み戻しを行います。ファイル名は例であり予約された VPN パスではなく、先頭の番号が重要なのは後で並べ替えられるファイルが勝つからです。

永続性が静かに壊れるのは優先順位のところです。配布物のローダーと自分の drop-in の両方を確認しますが、procps の sysctl --system も最後に /etc/sysctl.conf を読むのに対し、systemd の sysctl.d の順序はまったく別の並びだからです。後からの代入が同じキーをすぐに戻してしまえば、ファイルは正しくても実効値は間違ったままになります。その議論に勝つために既存の管理者ファイルを上書きせず、所有者を見つけてそこで変更します。

起動後に作られた名前空間はホストの drop-in ではまったく管理されません。その設定は、コンテナランタイムであれ名前空間のプロビジョニング単位であれ、それを作ったものに属します。問いを避けるためにコンテナに広いホスト権限を与えるのは、正しい所有者を特定する十分間を費やすより悪い取引です。

スイッチを切り替える前にその代償を知る

ip_forward は無害な真偽値ではありません。カーネルのドキュメントは、これを変更すると他のいくつかの IPv4 パラメーターがホストまたはルーターの既定値にリセットされると述べているため、診断のつもりの切り替えが別の場所で行った調整を捨ててしまい、そのことに触れもしないことがあります。気軽に実行できる検査ではなく、副作用のある構成変更として扱います。

それゆえ、クライアントがホストに届かないたびにオフとオンを繰り返すこともできません。値がすでに有効なら障害は経路の別の場所にあり、同じキーを三度書き直しても動きません。

永続性を証明し、それから経路の残りを試す

四つの時点で値を読み戻します: 変更直後、VPN インターフェースが現れた後、再接続の後、計画的な再起動の後です。これらのどこかで戻る値には第二の所有者がおり、もう一度だけ書き込んでも次の再起動まで隠れるだけです。

転送を有効にしても、確認すべきことは三つ残ります。クライアントには宛先への経路が必要で、ゲートウェイには先の経路とそれを使う許可が必要で、宛先にはクライアントのトンネルアドレスへの戻り経路が必要です。プライベートなルーティング済み LAN は自動的に NAT を必要としないので、三つのどれが欠けているかを知る前にマスカレードを追加せず、ゲートウェイ自身からではなく想定したクライアントから試します、なぜならゲートウェイ上で始まった要求は、いま有効にした転送経路を決して通らないからです。IPv6 は独自の転送とルーティングの方針を持つので、IPv4 のテストが通ってもそのことは何も示しません。

drop-in のパス、名前空間の所有者、読み戻しコマンドを runbook にまとめておきます。次にこれを引き継ぐ人は、値を読み、誰が所有しているかを見て、問題が永続性なのか経路の残りなのかを一分で判断できるべきです。

関連記事