Tailscale サブネットの SNAT を無効化した後の片方向通信
Tailscale サブネットルーターで SNAT を無効にすると、応答が届かなくなります。実際の送信元アドレスは残るため、LAN には 100.64.0.0/10 への戻り経路が必要です。
Tailscale サブネットルーターで送信元 NAT を無効にすると、トンネルは動き続けるものの、その内部を通る接続は止まります。リクエストはリモートクライアント自身のオーバーレイアドレスを携えて宛先に届き、これはまさにこの変更の狙いであり、応答には LAN がこれまで知る必要のなかった経路が必要になります。その経路がなければパケットは届いても応答は通常のゲートウェイから出ていき、障害はどのファイアウォールルールでも説明できないファイアウォール問題のように見えます。トンネルは健全で、戻り側だけが欠けています。
SNAT が隠していたもの
SNAT が有効な場合、ルーターはサブネットへ転送する前に送信元アドレスを自身の LAN アドレスに書き換えるため、宛先はすでに到達方法を知っているホストへ応答し、ほかに何も設定する必要がありません。無効にすると元の送信元が保たれ、宛先は自分の回線上の隣人ではなくオーバーレイ範囲内のアドレスを見ることになります。そのアドレスは実在し tailnet 全体でルーティング可能ですが、LAN から既定ゲートウェイ経由では到達できません。文書化されたスイッチは --snat-subnet-routes=false で、Linux サブネットルーター自体に適用します。
これはパケットごとの切り替えではなく常設の設定なので、そのルーターが担うすべての宛先ネットワークに戻り経路が必要です。だからこそこの変更はチェックボックスではなく導入判断になります。そのルーターが担うものすべてが、同じ瞬間にこの要件を引き継ぎます。
戻り経路を置ける場所
置き場所は三つが一般的で、違いは正しさではなく到達範囲にあります。宛先ホスト上の静的ルートは最も直接的で最も拡張性が低く、すべての機器が自前のコピーを必要とします。VPC や拠点ルーターのルートテーブルはネットワーク全体を一度に覆い、クラスレス静的ルートを運ぶ DHCP オプションはクライアントへ自動的に届きますが、それを無視する機器では静かに失敗します。
ip route add 100.64.0.0/10 via 192.168.1.10
ip route get 100.64.0.5
どの置き場所を選んでも、次のホップはルーターの LAN アドレスであり、tailnet アドレスでは決してありません。LAN のホストはこのルートを持たなければオーバーレイに到達できないため、オーバーレイ内部を次のホップにすると循環し、パケットはどこにも届きません。この一つの誤りが、正しく見えてなお失敗する構成の大半を説明し、ルーター自身のテーブルだけを読むあらゆる確認をすり抜けます。次の担当者が間違ったほうを試すことになるため、どの置き場所を使ったかを書き留めてください。
障害を片方向通信として読む
症状は原因より見分けやすく、サービスはルーター自身では応答するのにリモートクライアントからは沈黙します。宛先での取得ではリクエストが届き応答が出ていく様子が見え、応答の向かう先に気づくまでは成功に見えます。応答は既定ゲートウェイへ向かっており、つまり行きの区間は機能し、戻りの区間が機能していません。
ルーターは一つのやり取りの両方向が見えて応答がそもそも届いたかどうかが分かるため、代わりにそちらで取得してください。応答が宛先には現れるのにルーターには決して現れないなら、宛先側でルートが欠けているか誤っています。ルーターに現れてそこで止まるなら、問題はさらに先にあり、別の調査に属します。
sudo tcpdump -ni any host 100.64.0.5
ip route get 100.64.0.5
実際のアドレスはルートに値するか
宛先ネットワークを再構成できない場合、SNAT を残すほうが常に簡単な答えであり、代償はすべてのクライアントが宛先のログとポリシー上でルーターに見えることです。アプリケーションが実際の送信元アドレスを必要とする場合や、ネットワークポリシーがルーターを共有するクライアントを区別しなければならない場合には、無効化が正当化されます。どちらも正当な理由で、どちらも無料ではありません。利点は、すべての宛先ネットワークで経路を維持する手間に見合うものでなければならず、さらに後述するファイアウォールの見直しも伴います。
小さな LAN 一つならこの交換はたいてい元が取れますが、静的ルートを受け入れられない機器が散在する場合はたいてい元が取れません。判断と理由をルーターの設定のそばに記録し、次の管理者がどの挙動が意図的かを分かるようにしてください。誰も書き残さなかった既定値は、うっかりと同じに見えます。
ファイアウォール、ログ、二重の役割
ルーターの LAN アドレスに一致していたすべてのルールが今では別の送信元に一致し、それには許可ルールやルーターをクライアントとして記録していたログ項目も含まれます。ルーターのアドレスだけを許可するルールは新しい送信元を完全に遮断するため、最初の失敗の後ではなく最初のテストの前にそれらのルールを読んでください。置き換えは必要なクライアントとポートに絞り、その後で tailnet 全体を静かに通していないことを確認してください。
sudo nft list ruleset | grep -n '100\.64'
sudo iptables-save | grep -n '100\.64'
一つのノードが出口ノードとサブネットルーターを兼ねるのは文書化された組み合わせで、サブネット SNAT を無効にすると上流のトラフィックを落とすことがあります。これらの役割を別々のノードに分ければその注意書きは消え、各ルートとファイアウォールポリシーに単一の所有者ができます。役割を同居させなければならない場合は、その挙動を想定し、クライアントを疑う前に試験してください。次の接続が失敗するときにはまとめて読まれるため、ルート、スイッチ設定、役割の割り当てを一つのメモにまとめてください。