アカウント単位のルーティングは、一人の Linux ユーザーが所有するすべての IPv4 ソケットを既存のトンネルから出すべき場合に適し、プログラム単位の分離が必要な場合には適しません。UID で選ぶため、そのアカウントで動くものはすべて対象になり、忘れていたバッチ処理も含まれます。一つの ip rule に触れる前に、その問いを片付けてください。

以下の例は、UID 1500 の専用ブラウザーアカウント、ローカルアドレス 10.80.0.11 を持つトンネルデバイス tun-office、および該当する宛先を許可する VPN を前提とします。デーモン自体はその UID の外で動作します。

方式を選ぶ三つの条件

UID ルールは、作業を行う主体がアカウントであり、そのすべての通信を移してよい場合、そして namespace が作業に見合わないほど重い場合に選びます。ネットワーク namespace は、ワークロードが独自のインターフェース、リゾルバー、ルーティングテーブルを必要とする場合に選びます。プロキシまたはプロセス単位のバインドは、ちょうど一つのアプリケーションだけを移し、セッションの残りはローカルの経路に残すべき場合に選びます。この三つを書き留めておけば、意図より広く静かに覆ってしまうルールを防げます。

避けるべき間違いは、ランチャーが所有者を決めると思い込むことです。別のユーザーのセッションから URL を渡されたブラウザーは UID 1500 の下にソケットを作っておらず、どのルールもそれが生む通信を動かしません。

テーブル、ルール、ガード

既存のルールを確認し、未使用のテーブル番号と優先度番号を選んだ後の構成は短く、トンネルの送信元アドレスを持つ専用テーブルのデフォルトルート、アカウントの参照をそのテーブルへ送るルール、フォールバックを塞ぐ終端ルールからなります。書き下すと、冪等なルート置換 ip -4 route replace default dev tun-office src 10.80.0.11 table 51820 と、それに続く ip -4 rule add priority 12100 uidrange 1500-1500 lookup 51820 になります。

ガードは ip -4 rule add priority 12101 uidrange 1500-1500 unreachable で、その長さが示す以上に重要です。これがなければ、テーブル 51820 でルートが見つからない場合に通常のアップリンクへ抜け、アカウントは方針が捕まえるはずだった通信を静かに漏らします。これがあれば、同じ障害はタイムアウト、つまりフォールバックではなく遮断になります。

通常のローカルアドレスのルールはこれらの前に置き、LAN や管理用の例外を選択したテーブルの前に置くかを意識的に決めてください。そこで見つかったデフォルトは、後からより具体的な LAN ルートのために main を参照せず、最長プレフィックス一致がテーブルをまたいで効くと期待する人を驚かせます。意図した例外の一覧は、理由が新しいうちに変更ノートへ書いてください。

UID ルーティングが除くもの: DNS

リゾルバーのデーモンは上流のソケットを自分の UID で開くため、1500 を選んでもそれらの問い合わせはテーブル 51820 へ移りません。DNS の統合は別の判断であり、アカウントをトンネル経由で到達できるリゾルバーに向けるか、名前解決はホストの経路に従い通信は従わないと受け入れるかです。

ローカルのスタブへの loopback 問い合わせは、上流の問い合わせがブラウザーの経路を使った証拠にはならず、キャッシュからのページ読み込み成功も証拠になりません。

IPv6 には設計の中で独自の一文が要ります

上記のルールは IPv4 だけを対象にしています。要件がこのアカウントからの直接 IPv6 を伴わない IPv4 トンネルなら、レビュー済みの終端ルール ip -6 rule add priority 12101 uidrange 1500-1500 unreachable のようなものを追加し、その後に以前の IPv6 ルールと残したい loopback 例外を確認します。

直接の IPv6 を遮断することはデュアルスタックのトンネリングではなく、境界です。それをトンネリングと呼ぶと方針を読む次の人を混乱させ、その混乱は壊れた IPv6 サイトについてのヘルプデスク依頼として表面化します。

実際のアカウントで検証し、そのうえでライフサイクルを引き受ける

ip -4 route get 198.51.100.25 uid 1500 と同じ宛先を通常の UID で引いた結果を比較します。次に専用アカウントで許可された要求を行い、遠端が見る送信元アドレスを確認します。優先送信元アドレスは source NAT ではなく、別のものをバインドするアプリケーションを上書きしません。両方の参照が同じ経路を返すなら、ルールは思っているとおりに動いていません。

テーブル、ルール、トンネルルートの寿命を一人の所有者の下に置き、再接続とトンネル喪失を試し、方針を廃止するときは正確なエントリだけを削除します。別々のインターフェースと別々の状態が本当に必要ななら、namespace は今も使えます。

関連記事