ルートテーブルにはZeroTierインターフェース経由のデフォルトルートが表示され、ネットワークはオンラインと報告され、それでもブラウザーはローカルISPのアドレスから出ています。この組み合わせはよくあることで、クライアントのバグではありません。デフォルトルートはパケットがどこへ行くべきかを示すだけで、反対側で転送と変換を行う何かが必要です。出口ノードが機能するには、三つの別個の部分がすべて満たされている必要があります。

ルートはあるのに何も出ていかない

まずクライアントのルートテーブルを確認してください。default via 10.147.20.5 dev zt0 のような行はルートがインストールされたことを証明しますが、宛先がトラフィックを受け入れることまでは示しません。次のホップは、それを転送する意思と能力のあるメンバーでなければなりません。

同じ要求が依然として物理インターフェースから出ているなら、クライアントはルートをインストールしていないか、ローカルのデフォルトに負けるメトリックでインストールしています。ルートのインストール後に要求が消えるなら、出口メンバーはパケットを受信しているものの、転送や変換に失敗しています。物理デフォルトを保持するクライアントは、出口へパケットを一切送りません。

この違いが、どこを直すべきかを決めます。変更の前後で公開アドレスを比較すれば、一度も使われなかったルートと、使われて破棄されたルートを切り分けられ、構成全体を見直す代わりにコマンド一つで済みます。他の何かを変更する前に比較を行い、両方の結果が同じ初期状態から得られるようにしてください。

すべて満たす必要がある三つの部分

出口は連鎖であり、最も弱い環が症状を決めます。以下の表は、通常失敗する順に環を挙げています。

PartWhere it livesWhat a failure looks like
Forwarding and NATExit node kernel and firewallTraffic arrives, no reply
Managed default routeZeroTier network controllerNo default via the tunnel on the member
Client acceptanceMember's per-network settingRoute offered but not installed
DNS behaviorClient resolver configurationPages fail by name, IP works

最初の行は、オプション名が隠している部分です。メンバーが出口になるのは、そのカーネルがZeroTierインターフェースとインターネット側インターフェースの間でパケットを転送し、応答経路がトンネルへ変換して戻されるときだけです。この転送がなければ、メンバーはピアであり、ゲートウェイではありません。

コントローラーの行は構成ではなく承認です。0.0.0.0/0 をメンバー経由で告知すると、各クライアントに出口の場所を伝えますが、そのメンバーがトラフィックを運べるようにはなりません。メンバーにインターネットへの有効な経路があることも検証しません。ZeroTierの出口ノードのドキュメントも、ノード・ルート・クライアントの同じ分離を扱っています。

出口ノードを転送と変換のために設定する

IPv4転送を永続的に有効にし、次にWANインターフェースを出るトラフィックに送信元NATを追加します。フィルタールールは転送されたフローを両方向で許可する必要があります。転送と変換は許可とは別だからです。

sysctl -w net.ipv4.ip_forward=1
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
iptables -A FORWARD -i zt0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o zt0 -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

zt0 と eth0 をホスト上の名前に置き換えてください。例のインターフェース用に保存されたルールは、実在のインターフェースでパケットを追いません。変更はルールを所有するファイアウォールマネージャー経由で永続化してください。対話型シェルで実行したコマンドは次の再起動で消えます。

ホストがUFWやfirewalldなどのファイアウォールマネージャーを実行している場合、iptablesの行を横に積むのではなく、そのマネージャー経由でルールを追加してください。同じチェーンを編集する二人の所有者は、起動順に依存するポリシーを生みます。マネージャーが独自のチェーンを生成する場合、順序が重要です。マネージャーを再読み込みした後にクライアントから試してください。その前ではありません。

ルートを告知し、クライアントで受け入れる

ネットワークコントローラーで、次のホップが出口メンバーのZeroTierアドレスである 0.0.0.0/0 の管理ルートを追加します。次に、それを使うべきメンバーで、そのネットワークの上書きを許可します。許可はローカルです。他のメンバーを再構成せず、コントローラーも変更しません。

zerotier-cli listnetworks
zerotier-cli set <network-id> allowDefault=1
ip route get 1.1.1.1

最後のコマンドはZeroTierインターフェースと出口メンバーのアドレスを報告するはずです。依然として物理インターフェースを報告するなら、ルートが欠けているか、競合するデフォルトのメトリックが優れています。

設定はそれを必要とするネットワークに限定してください。デフォルトルートの受け入れをグローバルに、あるいはプライベートサブネットだけを提供すべきネットワークで有効にすると、想定されていない出口を通してトラフィックを送ることになります。

出口を確認し、他のアドレスファミリーを調べる

送信元を報告するサービスから公開アドレスを取得し、出口ノードのWANアドレスと比較します。次に名前でサイトを読み込み、DNSがまだ解決することを確認し、ブラウザーだけでなく重要なアプリケーションを一つ試してください。

デュアルスタックのクライアントは、IPv4がZeroTier経由で出る間もネイティブのIPv6経路を使い続けられます。目標がすべてのトラフィックを隠すことや制御することなら、別個の ::/0 ルートと出口側のIPv6転送が必要であり、IPv4のテストではそれらについて何もわかりません。

Linuxの逆経路フィルタリングもクライアント上の有効な出口トラフィックを落とすことがあります。ZeroTierは参加メンバー向けのrp_filterの考慮を文書化しています。この設定は意図的に、ルートとNATを確認した後にだけ変更してください。最初の実験としてではなく。

要件がNASや一つのオフィスサブネットへのアクセスなら、そのプレフィックス向けの管理ルートは完全な出口より小さく安全な変更です。すべての閲覧を別の機器経由で送るのは、一つのプライベートリソースに届くのとは別の判断であり、別途のレビューに値します。

関連記事