TAPはEthernetフレームをオペレーティングシステムに渡す。これは大半のリモートアクセス設計が必要とするより大きな能力であり、ブリッジよりは小さい。カーネルはそれをアドレス指定し、そこを通してルーティングし、どの物理セグメントにも接続せずにファイアウォールで守ることができる。この構成はまず理解する価値がある。サーバーが実在のLANに向かうルーターとして振る舞う、隔離された仮想Ethernetセグメントである。トンネルの内側では第二層の振る舞いを外側では通常のIP転送を与えるが、これは二つの異なる約束である。残りは構築、経路、戻り経路、そしてロールバックである。

隔離されたセグメントを構築する

Linuxではインターフェースは三つのコマンドを取る:作成し、起動し、意図するセグメントの内側でアドレスを与える。オフィスのLANと衝突しないプレフィックスを選んで書き留める。衝突は、存在すべきでないホストが応答するまで見えないからだ。

ip tuntap add dev tap0 mode tap
ip link set tap0 up
ip addr add 10.77.0.1/24 dev tap0

ここでブリッジを必要とするものはなく、後から追加することを妨げるものもない。カーネルのTUN/TAPドキュメントはインターフェース自体を説明している。ブリッジへの参加と転送ポリシーは、あとで下す別の判断である。

境界を越えてルーティングする

転送を有効にし、転送チェーンで二つのプレフィックスを許可し、LANルーターを次のホップとしてオフィスのプレフィックスへの経路を追加する。するとVPN側はオフィス向けのトラフィックを自分のゲートウェイとしてサーバーへ送り、サーバーはそのパケットをブリッジとしてではなく自分自身として転送する。転送を無効にしたTAPインターフェースは、ローカルに応答し、その先には何も届かないセグメントであり、よくある中途半端な状態である。あとで両側のインターフェースカウンターを確認する。LAN側で送信カウンターが横ばいなのに受信カウンターが増えているなら、悪い経路ではなく転送チェーンでのドロップである。

経路とファイアウォール規則を一つの変更として書く、なぜならどちらか一方だけでは、クライアント側からルーティング障害に見える状態を作るからである。

戻り経路を決める

LANルーターがVPNプレフィックスへの戻り経路を学習するか、サーバーが出ていくときに送信元アドレスを変換するかのどちらかである。変換は戻り経路を自明にし、送信元の同一性を破壊する。だから宛先のログには、その背後のすべてのクライアントについてサーバーのアドレスが表示される。ルーティングされたプレフィックスは同一性を保ち、管理していないかもしれない機器での変更を必要とする。

どちらが入力しやすいかではなく、意図して選ぶ。単一のルーティングされたプレフィックスは通常、変換よりきれいであり、一つの実験室のために管理外のルーターに新しいプレフィックスを教えるより、変換のほうが通常はよい。

ブロードキャストの範囲を意図的に保つ

仮想セグメントの内側では、DHCP、発見、近隣通知はスイッチ上と同じように振る舞う、一つのリンクだからだ。ルーティングされた境界の向こうではそうならない、だからオフィスのDHCPとサービス発見には、TAPがそれらを含むという前提ではなく、明示的な設計が必要である。インターフェースの種類は、別の場所に住むサービスのための中継ではない。

そもそもTAPを選ぶ正直な理由はこれである。仮想セグメント上の何かがリンク内の振る舞いを必要としている。何も必要としないなら、ルーティングされたプレフィックスを持つTUNデバイスのほうが小さく、壊れたときに説明することも少ない。

検証してからロールバックを書く

VPNクライアントからLANルーターにpingし、ホストにpingし、TCPで重要なサービスを一つ開く。次にカウンターと転送チェーンを確認する、ポリシーによるドロップは遠くから見るとちょうど欠けた経路のように見えるからだ。ロールバックは構築の逆であり、始める前の変更記録に属する。経路を外し、アドレスを外し、インターフェースを削除する。

要件が本当に二つの拠点にまたがる一つのEthernetセグメントなら、ブリッジが正直な答えであり、影響範囲の異なる別の設計である。要件が到達性なら、ルーティングされたアップリンクを持つ隔離セグメントが、あとで説明することが少なくて済む。

関連記事