📝 TailscaleのSubnet RouterとExit Nodeは、通信の行き先で使い分ける
haruki256

Tailscaleでスリープ中PCを起こす構成を、通信経路から順に整理する

結論

外出先からTailscale経由で自宅PCをWake on LANで起こすときは、Subnet Routerが作るIP経路だけで成功を判断できません。LAN側でマジックパケットを送る常時起動端末と、スリープ中もネットワークアダプターが起動信号を待てる条件を分けて確認します。

Subnet Routerを有効にすると、Tailscaleを入れられないLAN内機器のIPアドレスへ通信できます。ただし、離れた場所からLAN内へブロードキャストする通信を、そのまま自宅LANへ転送する機能ではありません。

Wake on LANでは、対象PCを起こすマジックパケットをネットワークアダプターへ届けます。よく使われるのは、UDPを使って同じLAN内へ一斉に送る方法です。

Tailscale側:LANのIP範囲までの経路を作る
LAN側   :対象PCのネットワークアダプターへ
              マジックパケットを送る

そのため「LAN宛てのIP経路を設定したので、ブロードキャストも必ず届く」とは判断できません。実際の動作は環境によって変わります。確認する条件は次の4つです。

  • 使うOS
  • Tailscaleの設定
  • Wake on LANを送るアプリ(WoLアプリ)
  • マジックパケットの宛先

まず、同じLAN内から対象PCを起動できるかを確認します。

僕の構成では、起動中のAndroidを自宅LAN側へ置きました。外出先から操作し、PCが起動するところまで確認しました。

ただし、Android版TailscaleとWoLアプリが、受け取った通信をどのようにLANへ送るかは未確認です。構成を再現するときは、Android経由でLAN内のIPへ届くことと、WoL操作で実際にPCが起動することを分けて試します。

参考:Subnet routersKernel vs. netstack subnet routing

IP経路だけではWoLの成功を判断できず、LAN側でマジックパケットを送る役割が必要です。次は、スリープ中のPC自身がその役割を担えるかを見ます。

スレッドを開く スレッドを閉じる 2

LAN側に送信役が必要でも、PCがスリープしてTailscaleも止まる構成では、そのPC自身に送信役を任せられません。

TailscaleはOS上で動くソフトウェアです。PCがスリープし、OSとアプリの実行が止まれば、Tailscaleも新しい通信へ応答できません。

一方、Wake on LANに対応したネットワークアダプターは、対応する低電力状態でマジックパケットを検知し、PCへ復帰を要求できます。この役割は、停止したTailscaleアプリではなく、通電が続くネットワークアダプターが担います。

スリープ中のPC
├─ Tailscaleアプリ:停止しており応答できない
└─ Wake on LAN対応ネットワークアダプター:
    条件が合えばマジックパケットを待てる

利用できるスリープ状態やWake on LANの可否は、次の条件で変わります。

  • PCが対応するスリープ状態
  • ネットワークアダプター(NIC)とドライバーのWake設定
  • UEFI(PC起動前の設定画面)のWake設定
  • 有線または無線の接続方法

Windowsならpowercfg /aで利用可能なスリープ状態を確認し、デバイス側のWake設定も別に確認します。

この制約を避けるには、自宅LANへ常時起動の端末を置きます。外部からはその端末までTailscaleで到達し、最後のWake on LANはLAN側から送る役割分担です。

参考:Wake on LAN behaviorAbout Network Wake-Up Events

スリープ中のPCとは別に、Tailscaleへ応答してLAN側からWoLを送れる常時起動端末が必要です。続けて、その役割をAndroidへ任せる場合の確認へ進みます。

その常時起動端末として、僕は使っていなかったAndroidを置きました。初回の起動成功だけでなく、画面消灯後と再起動後も中継できるかを確認します。

自宅LAN宛ての通信をAndroid経由で送れるよう、LANの経路をTailscaleへ知らせました。外出先のスマホからWoLアプリを操作すると、PCが起動するところまでは確認しました。

ただし、Androidの省電力機能であるDozeやApp Standbyにより、未使用時にはバックグラウンドのCPU処理やネットワーク利用が制限されます。端末メーカー独自の省電力設定が重なる場合もあります。

確認は次の順に分けます。

  1. 画面を点灯した状態で、Tailscale経由の到達とPC起動を確認する
  2. 画面を消し、時間を置いた後も同じ操作を繰り返す
  3. 失敗時は、Wi-Fi、Tailscale接続、アプリの省電力対象を一つずつ確認する
  4. 端末の再起動後にも、Wi-Fi、Tailscale接続、WoLアプリが使える状態へ戻るか確認する

設定名や制限はAndroidの版とメーカーで変わります。特定の画面名を手順として固定せず、画面消灯後と再起動後の動作を合格条件にします。

参考:Subnet routers — AndroidOptimize for Doze and App Standby

TailscaleのIP経路とWoLの到達を分けると、スリープ中のPCとは別に常時起動端末を置く理由が見えます。Androidを使う場合は、PCが一度起動したことだけで終えず、中継役を継続できる条件まで確認します。

haruki256

Subnet RouterはLAN内の特定範囲へ、Exit Nodeはインターネット全体へ通信を送る

結論

Tailscaleを入れられない自宅LANの機器へ届きたいならSubnet Router、Web閲覧などのインターネット通信を別の端末から出したいならExit Nodeを選びます。違いは中継端末の名前ではなく、経路の宛先です。

どちらも、Tailscale端末を別の通信先への中継に使います。そのため設定画面だけを見ると似ていますが、クライアントへ配る経路が異なります。

Subnet Router
外出先の端末 → 自宅LANの特定範囲 → プリンターやNASなど

Exit Node
外出先の端末 → インターネット全体への経路 → Webサイトなど

Subnet Routerは、自宅LAN内の機器へ届けるためのIPアドレス範囲を、Subnet Router経由で使える経路としてTailscale端末へ知らせます。接続する側の端末は、その範囲宛ての通信だけをSubnet Routerへ送ります。目的は、Tailscaleを直接動かせないLAN内機器への到達です。

Exit Nodeは、インターネット全体へ向かう通信の経路を引き受けます。接続する側の端末が明示的にExit Nodeを選ぶと、Tailscale宛てや個別に設定したLAN向けの経路を除くインターネット通信がその端末を通ります。

僕は「何を置くか」ではなく、「どの宛先へ届けたいか」を先に決めます。LAN内の一部ならSubnet Router、インターネット側ならExit Nodeです。

参考:Subnet routersExit nodes

スレッドを開く スレッドを閉じる 1
📝 Tailscaleはなぜポート開放なしでつながるのか――NAT越え・直接接続・中継の仕組み
haruki256

Tailscaleがポート開放なしでつながるまでを、NATから順に整理する

結論

外出先から自宅のIPv4端末へTailscaleで接続するときは、NATで届きにくいことと、安全対策が済んでいることを分けて考えます。そのうえで、自宅側と通信事業者側のNAT、Tailscaleの接続調整、実際の通信経路を順に追うと、ポート開放なしで接続できる理由を整理できます。

家庭のIPv4ネットワークでは、NAT(ネットワークアドレス変換)を行うルーターが、LAN内の複数端末を一つのグローバルIPv4アドレスへ対応付けます。LAN内の端末から外へ出た通信は対応表に記録され、その返答だけが元の端末へ戻ります。

反対に、外部から突然届いた通信に対応する記録や転送規則がなければ、通常そのままLAN内へ転送されません。

ここで起きているのは、外部から自宅LAN内の端末へ届く経路が作られていないということです。端末やアプリに脆弱性がないこと、許可された人だけが使えること、データが暗号化されていることまで保証しているわけではありません。

僕は次の二つを分けて考えます。

  • 到達性:どの経路を通れば、目的の端末やサービスへ届くか
  • 安全対策:誰の通信を許可し、何を暗号化し、端末をどう更新するか

Tailscaleのような仕組みでNATを越えて到達経路を作っても、安全対策が不要になるわけではありません。反対に、NATの内側に置いただけで安全対策が完成するわけでもありません。

参考:How NAT traversal worksControl and data planes

ここまでで、自宅ルーターのNATが外から突然届く通信を端末へ渡せない理由が分かりました。ただし、回線によっては自宅ルーターの外側にもNATがあります。次はCGNATで、なぜ自宅側のポート開放だけでは届かないかを見ます。

スレッドを開く スレッドを閉じる 5

通常の家庭内NATだけなら、自宅ルーターへ「このポートはこの端末へ渡す」という転送規則を設定できます。ところがCGNATでは、その外側に通信事業者が管理するNATがあります。

インターネット
通信事業者のCGNAT  ← 利用者は転送規則を設定できない
自宅ルーター       ← ここだけ開けても経路は未完成
自宅PC

自宅ルーターの設定を変えられても、CGNAT側で「どの契約者の、どの端末へ渡すか」が決まりません。

インターネット上で自宅回線を個別に識別できるグローバルIPアドレスを契約する方法もあります。ただし、利用できるかは回線や契約に依存します。

Tailscaleは、自宅側へ固定の受信ポートを用意する代わりに、端末側から外向きに接続を始めます。NATの内側にある端末同士で直接経路を作れるか試し、できなければ中継を使います。

参考:How NAT traversal works — Concerning CGNATsConnection types

ポートを外から開ける方法と、端末側から接続を作る方法の違いは見えました。では、外向きに接続した端末同士を誰が引き合わせ、実際のデータはどこを通るのでしょうか。次は、接続の調整とデータの経路を分けます。

端末側から外向きに接続を作るTailscaleでは、相手を見つける調整と、暗号化したデータを運ぶ経路が別の役割を持ちます。

Tailscaleへ端末を追加すると、調整サーバーは同じtailnet(Tailscaleで管理するネットワーク)内で通信を許可された端末の公開鍵、接続候補、経路、規則を配ります。端末は、その情報を使って相手との接続経路を組み立てます。

一方、アプリのデータは各端末上のデータプレーンが暗号化し、相手へ送ります。直接接続なら、暗号化されたデータは端末間を流れます。

直接接続できなければ、Tailscaleの中継サーバーであるDERPか、別のTailscale端末を中継にするPeer Relayを通ります。どちらも調整サーバーとは別の経路です。

調整サーバー:誰と、どの鍵・経路・規則でつなぐかを配る
データ経路 :暗号化した通信内容を端末間で運ぶ

「中央サーバーを使う」ことと、「すべての通信内容がそのサーバーを通る」ことは同じではありません。Tailscaleの接続を理解するときは、接続を調整する役割と、パケットを運ぶ役割を分けると追いやすくなります。

参考:Control and data planesConnection types

ここまでで、調整サーバーが接続情報を配り、データプレーンがパケットを運ぶところまで分かりました。次は、そのデータ経路が中継から直接接続へどう変わるかを追います。

実際の接続開始時は、相手が接続しているDERPサーバーを経由して接続要求を届けます。両端末は接続候補を交換します。その後、NATの内側から互いにUDPを送り、直接届く組み合わせを探します。

DERPで接続開始
直接UDP接続を試す
  ├─ 成功 → direct
  └─ 失敗 → 別のTailscale端末を中継にするPeer Relayを試し、
              使えなければDERPを継続

この順序なら、直接経路の探索を待ってから通信を始める必要がありません。ネットワーク条件が変わった後も、Tailscaleはよりよい経路を定期的に探します。

「Tailscaleは必ず端末同士で直接通信する」と考えると、接続状態の中継表示を異常だと誤解します。直接接続は性能面で望ましい経路ですが、中継は接続を保つための正規の経路です。

参考:Connection types

接続経路は、DERP、Peer Relay、直接接続の間で変わり得ます。現在どの経路を使っているかをコマンドで確認します。

速度や遅延が気になるときは、接続経路を推測せず、コマンドライン(CLI)から確認します。

tailscale ping <相手の端末名またはTailscale IP>

viaの後にIPアドレスとポートが表示されれば直接接続です。via DERP(...)ならDERP中継、via peer-relay(...)なら同じtailnet内のPeer Relayを使っています。

接続開始直後はDERPから直接接続へ切り替わることもあります。最初の一行だけで決めず、複数回の応答を見ます。

普段の接続一覧は、次のコマンドでも確認できます。

tailscale status

直接接続できない理由を調べる段階では、tailscale netcheckを使います。確認するのは次の項目です。

  • UDPを利用できるか
  • 接続先によってNATの割り当てが変わるか
  • どのポートマッピング方式が使われているか
  • どのDERPが近いか

中継であることだけを原因と決めず、「今どの経路か」と「現在のネットワーク条件」を分けて確認します。

参考:Connection typesTailscale CLI

NATで外から届きにくい理由と、Tailscaleが作る通信経路を分けると、ポート開放なしでつながる仕組みと、現在の経路を確かめる方法を同じ流れで追えます。