技術 約8分で読めます

Tailscaleの代替を考えるとWireGuardだけでは足りない

いけさん目次

DNS、100.64.0.0/10、iptables、MTU、ACL、SSO。
Tailscaleは便利だが、Linuxホストのネットワーク制御をかなり持っていく。
「Tailscaleやめたい」を読んで、自分も同じことを考えていたのに気づいた。

自分の構成を振り返ると、ローカルLLMをVPN経由で外部API化する で書いたのがまさにTailscale依存だった。
VPSから自宅PCへTailscale IPで叩く。NAT越しを考えなくていいから楽で、今も動いている。
ただ、あの構成は「閉じたサービスへ内側から入る」と「インターネットへAPIとして外に出す」を同じVPNトンネルに載せている。
辞めたいのに辞められない理由がここにある。

Tailscaleを別の製品に差し替えても、アクセス経路の設計が同じなら不満の根は残る。
内側へ入る道と、外側へ出す道を分けないと、どのVPNを選んでも結局フルトンネルに寄っていく。

Tailscaleが嫌われる理由はWireGuardではない

TailscaleのデータプレーンはWireGuardベースだが、文句が出やすいのはWireGuard暗号そのものではない。
LinuxホストでDNS、ルーティング、netfilter、MagicDNS、100.64.0.0/10の扱いまでTailscaleがまとめて面倒を見るところにある。

Tailscale自身も、LinuxのDNS設定を扱う難しさを The Sisyphean Task Of DNS Client Config on Linux で説明している。
/etc/resolv.conf、resolvconf、NetworkManager、systemd-resolvedが絡むので、実装側が泥臭くなるのはわかる。
わかるが、利用者から見ると「VPNを入れただけなのに名前解決とFirewallが変わる」になる。

netfilterについては、Tailscale公式ドキュメントに onnodivertoff の3モードがある。
デフォルトの on はTailscaleがルールを作り、必要な通信で評価されるよう管理する。
nodivert はルールを作るが有効化しない。
off はTailscaleがFirewallを管理せず、必要なルールを自分で書く。

つまり逃げ道はある。
ただし off にすれば、今度は自分で漏れなくFWを書く必要がある。
Tailscaleの便利さを買っていたはずなのに、危ない部分だけ自前運用へ戻る。

100.64.0.0/10の問題も同じだ。
GitHub issue #12829 では、100.100.0.0/20を内部で使っていた環境にTailscaleを入れたら、100.64.0.0/10全体へのDROPで到達不能になった例が報告されている。
CGNAT帯は「ISPだけが使うから安全」というより、今はKubernetes、VPN、社内ネットワークの逃げ場としても使われる。
ここを製品側が強い前提で握ると、既存ネットワークとの衝突が急に事故になる。

HeadscaleはTailscale社を外せるがtailscaledは残る

Headscaleは、Tailscaleのコントロールサーバーをセルフホストする実装だ。
公式サイトも「open source, self-hosted implementation of the Tailscale control server」と説明している。

これはSSOやTailscale社依存を減らすにはかなり効く。
tailnetの存在条件をTailscale社のSaaSに預けたくない、という不満には正面から刺さる。

一方で、Linuxホスト上で動くクライアントは基本的にtailscaledのままだ。
DNS、netfilter、100.64.0.0/10、MTUの不満が主戦場なら、Headscaleに移っても全部は消えない。
「Tailscaleの管理面が嫌」ならHeadscale。
「tailscaledがホストへ入ってくる感じが嫌」なら、別系統を見る必要がある。

NetBirdとNetmakerは代替になるが同じ種類の仕事をする

NetBirdはWireGuard、Pion ICE、Coturnなどを組み合わせたオープンソースのメッシュVPNだ。
管理サービス、Signal、Relayをセルフホストでき、クライアント同士は可能なら直接WireGuardでつながる。
NetBirdのドキュメントでは、クライアントがFirewall managerやDNS設定を適用することも明記されている。

ここは大事で、NetBirdは「Tailscaleよりオープンだからホストに触らない」ではない。
同じ問題空間を別の実装で解いている。
実装や運用思想が合えば代替になるが、DNSやFirewallに介入するタイプのソフトを避けたい人には、根本解決ではない。

NetmakerもWireGuard上にフルメッシュや部分メッシュ、ゲートウェイを作る製品だ。
公式ドキュメントは、WireGuardのポート、endpoint、鍵、peer設定を抽象化する、と説明している。
ルートやゲートウェイをGUIで扱いたいなら選択肢に入る。

ただ、NetBirdもNetmakerも「WireGuardの設定ファイルを手で配る面倒」を解消するための管理面を持つ。
管理面を持つ以上、どこかで認証、鍵配布、経路配布、DNS、ACLの設計が出てくる。
Tailscaleへの不満が「管理面がブラックボックス」なら前進する。
不満が「そもそもホストのネットワークをソフトに握られたくない」なら、まだ重い。

Nebulaは少し古風だが侵襲範囲を読める

NebulaはSlack由来のオーバーレイネットワークで、GitHubでは「performance, simplicity and security」を重視したツールとして説明されている。
WireGuard系ではなく、CAでノード証明書を発行し、lighthouseでピア発見する設計だ。

良いところは、勝手にやることが少ないことだ。
証明書、lighthouse、静的設定、ルートを読めば、だいたい何をしているかわかる。
悪いところも同じで、Tailscaleのような「入れてログインしたら全部つながる」にはならない。
モバイル端末や非エンジニア利用者まで含めると、運用の手触りは一気に硬くなる。

自分のサーバー数台、VPS数台、自宅の固定機材だけならNebulaはかなり筋がいい。
家族のスマホ、出先のノートPC、短命な検証VMまで含めるなら、Tailscale系のほうが楽になる。

Cloudflare Tunnelは外部公開の道具であってVPNの置き換えではない

外から自宅サービスへアクセスしたいだけなら、Cloudflare Tunnelや類似のリバーストンネルで足りることがある。
CloudflareのPrivate networksドキュメントでは、cloudflared はプライベートネットワーク内のサーバーからCloudflareへアウトバウンドトンネルを張り、ユーザーからサーバーへ向かう通信をプロキシする、と説明している。
公開Webサービス、管理画面、Webhook受け口ならこの形が合う。

ただし、これはVPNではない。
任意のIPプロトコルで双方向にLANへ入るものではなく、基本はアプリケーション入口をCloudflare側に作る設計になる。
Cloudflare WARPやMeshまで使えばプライベートネットワーク接続に寄せられるが、その時点でCloudflareのZero Trust基盤へ寄る。

以前の WireGuard VPN サーバーの構築メモ では、AllowedIPs = 0.0.0.0/0 のフルトンネルと、10.0.0.0/24 のスプリットトンネルを並べていた。
今回の話では、基本は後者だ。
自宅NAS、管理用SSH、ローカルLLM、DB管理画面だけをプライベート経路に載せる。
外部に見せるHTTP APIはVPS、Cloudflare Tunnel、ngrok系、あるいは普通のリバースプロキシで分ける。

flowchart TD
  A[ノートPCやスマホ] --> B[閉じた管理アクセス]
  A --> C[公開APIやWeb UI]

  B --> D[スプリットトンネル]
  D --> E[自宅NASや管理SSH]
  D --> F[ローカルLLMの内部API]

  C --> G[HTTPS入口]
  G --> H[VPSまたはCloudflare Tunnel]
  H --> I[必要なサービスだけ転送]

この分け方なら、VPN側で外向きインターネット通信まで抱え込まない。
DNSも、全クエリをMagicDNS相当へ寄せるのではなく、内部ドメインだけをsplit DNSにする。
経路も、0.0.0.0/0 ではなく、到達したいCIDRだけを広告する。

HTTP/3やQUICは公開側で考える

対中国通信 VPN規格によるつながりやすさの比較VeilShift™でわかるDPI回避の実装差分 では、Hysteria2、VLESS + REALITY、XHTTP、uTLS、パディングの話を書いた。
あれは検閲やDPIを相手に、通信を普通のWebっぽく見せる話だ。

自宅やVPSをつなぐ閉じた管理ネットワークでは、そこまでやると過剰になる。
WireGuardでよい場所に、HTTP/3偽装やパディングを入れても、運用の面倒が増えるだけだ。
HTTP/3やQUICを考えるべきなのは、外部公開するWeb入口、モバイル回線での体感、CDNやエッジの扱いが問題になる場所だ。

たとえばローカルLLMを外から使うなら、内側はWireGuard系のスプリットルートで十分。
外側はVPSのnginxやCloudflareでHTTPS終端し、可能ならHTTP/3を有効にする。
外から見えるのは普通のHTTPS APIで、裏側だけ閉じた経路に逃がす。
この構成なら、LLMサーバー自身をインターネットへ出さずに済むし、VPNクライアントを全利用者へ配る必要もない。

すぐ使うならTailscaleを狭く使う

代替が本当にないのか、と聞かれたら「ある」。
Headscale、NetBird、Netmaker、Nebula、素のWireGuard、Cloudflare Tunnelを組み合わせれば、Tailscaleなしでも作れる。
ただ、Tailscaleの代替は単体製品ではなく、だいたい部品の組み合わせになる。

すぐ使うなら、Tailscaleを消すより先に範囲を絞るほうが効く。
MagicDNSを使わない。
exit nodeを普段使いしない。
subnet routerは専用VMに閉じ込める。
CGNAT帯を内部で使っているなら、Tailscaleを入れるホストを分ける。
LinuxでFirewallを強く管理しているホストには、いきなり入れない。

Tailscaleのuserspace networking modeも逃げ道になる。
公式ドキュメントでは --tun=userspace-networking を使うとSOCKS5やHTTP proxyとして動かせる。
ただしこれは主にコンテナやserverless向けで、通常のTUNインターフェースを作らない代わりに、アプリ側がproxyを使う必要がある。
ホスト全体のネットワークを触られたくない用途には合うが、LANの全プロトコルへ自然に入るVPNではない。

Tailscaleは、捨てるより隔離したほうが現実的な場面が多い。
自宅や会社の中核ルータ、Kubernetesノード、Firewallを細かく触るサーバーには入れない。
代わりに小さいVPSや専用Linux VMを境界に置き、そこから必要なサービスだけへ流す。
「すぐつながる」はTailscaleに任せてもいいが、「どこへ流れるか」はTailscaleに全部任せない。

参考