Tailscaleはポートフォワーディングの代わりになりますか?
Tailscaleならルーターのポートを開けずにNAS、Raspberry Pi、Minecraftサーバーへ接続できます。NAT越えの仕組み、リレーへのフォールバック、できないことを解説します。
Tailscale にポートフォワーディングは必要ですか?
Tailscale にポートフォワーディングは必要ありません。自分のマシンへ接続する場合、ポートフォワーディングを完全に置き換えられます。tailnet(Tailscale がデバイス間に構築するプライベートネットワーク)内の各デバイスが、それぞれ外向きの接続を確立します。自宅のルーター側で変更する設定はありません。転送ポート、DMZ(非武装地帯)ホスト、ダイナミック DNS レコード、パブリック IP も必要ありません。ipTIME や Fritz!Box のルーター配下にある NAS(ネットワーク接続ストレージ)、Raspberry Pi、ゲームサーバーにも、外出先のラップトップから専用のプライベートアドレスで接続できます。ルーターの受信側は閉じたままです。
Tailscale ができないことも明確です。Tailscale は、tailnet にログインしているデバイス、または tailnet に共有されたデバイスを接続します。インターネット上の第三者や、tailnet に参加していない友人は、Tailscale 経由で何にも接続できません。サービスをインターネット全体に公開することは別の作業であり、その方法については終盤で説明します。
NAT を越えて Tailscale がポート転送なしで接続する仕組み
ポート転送が必要になるのは、NAT(ネットワークアドレス変換)があるためです。一般的な家庭用回線では、ルーターが 1 つのパブリック IPv4 アドレスを持ち、背後の各デバイスにはプライベートアドレスが割り当てられます。ルーターに到着したインバウンドパケットには、どのプライベートデバイス宛てかを示す情報がないため、ルーターはそのパケットを破棄します。ポート転送は、「port 25565 は 192.168.0.20 に転送する」という手動ルールです。Tailscale は、次の 4 つの手順で同じ状態をルールなしに実現します。
最初に、すべてのノードが外向きに接続します。起動時に tailscaled はコーディネーションサーバーへ接続します。通常は独自の暗号化トランスポートでラップした TCP 80 番ポートの HTTP を使用し、port 80 から応答がない場合は TCP 443 番ポートの HTTPS にフォールバックします。自身の WireGuard 公開鍵を送信し、tailnet 内にある他のすべてのノードの公開鍵とアドレスを取得します。コーディネーションサーバーがトラフィックを運ぶことはありません。扱うのは鍵とアドレス帳だけです。
次に、各ノードは外部からどのように見えるかを確認します。Tailscale のリレーサーバーの UDP 3478 番ポートへ、STUN(NAT セッショントラバーサルユーティリティ)リクエストを送信します。応答には、ルーターがその外向きパケットに割り当てたパブリック IP アドレスとポートが含まれます。これは、外向きの通信に対してルーターが自動的に作成したマッピングであり、手動でポート転送を設定した場合に作成されるものと同じです。ルーターが UPnP または NAT-PMP に対応している場合、Tailscale はマッピングの作成も自動的に要求します。これは接続に役立ちますが、必須ではありません。
3 つ目に、双方がホールパンチングを行います。ノード A とノード B は、コーディネーションサーバーを通じて互いのパブリックエンドポイントを取得します。双方が自身のリスナーから、デフォルトでは port 41641 を使用して、相手側のパブリックエンドポイントへ UDP パケットを同時に送信します。各ルーターには自ノード用の外向きマッピングがすでにあるため、反対側から到着したパケットはそのマッピングに一致し、通過します。この時点から、2 つのノードは WireGuard で直接通信します。ルーターに転送ルールは必要ありません。
4 つ目に、ホールパンチングに失敗すると、トラフィックはリレー経由になります。すべての接続は実際には最初に DERP(パケット用指定暗号化リレー)サーバーを経由して開始します。DERP は暗号化された WireGuard パケットを TCP 443 番ポートの HTTPS で転送し、Tailscale はその後、3 つ目の手順で説明した直接 UDP 経路への切り替えを試みます。CGNAT(キャリアグレード NAT。ISP が管理する 2 つ目の NAT の背後に置かれる構成)と、対称 NAT(ルーターが宛先ごとに新しいポートを選ぶため、STUN の応答が役に立たない構成)は、どちらもこの切り替えを妨げます。UDP をブロックする企業ファイアウォールも同様です。切り替えに失敗すると、Tailscale はまずピアリレーを試します。これは、自分の tailnet 内にあるデバイスを設定して、UDP 経由でトラフィックをリレーする方式です。利用可能なピアリレーがなければ、接続は DERP 上に残ります。リレーから見えるのは暗号文だけです。ただし、遅延とスループットに影響します。Tailscale のリレー接続が遅い理由と直接接続に切り替える方法では、現在の経路の確認方法と変更方法を説明します。
この 4 つの手順のいずれも、ルーターへのインバウンド接続ではありません。これが、ポート転送が不要な理由です。
クライアントをインストールしてパスを確認する
インストールは、各デバイスで 1 つのスクリプトを実行し、1 回ログインするだけです。
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale ip -4tailscale up はログイン URL を表示します。URL を開いてサインインすると、そのデバイスが tailnet に参加します。tailscale ip -4 は、100.64.0.0/10 の範囲にあるデバイスの tailnet アドレスを表示します。このアドレスは再起動後もネットワークを変更しても変わりません。そのため、SSH 設定やゲームクライアントにはこのアドレスを指定します。
tailnet 内の別のデバイスから、最初のデバイスまでの経路を確認します。
tailscale ping nasホスト名または tailnet アドレスを使用します。最初の応答では、接続が開始時点ではすべてリレー経由で、直接経路のネゴシエーション中であるため、via DERP と表示されることがよくあります。数秒以内に、応答はパブリック IP とポートの表示に切り替わるはずです。これは hole punching が成功したことを示します。1 分経過しても via DERP と表示される場合は、hole punching を完了できなかったことを意味します。通常は、一方が hole punching で通過できない NAT の背後にあるか、UDP をブロックするネットワーク上にあることが原因で、接続はリレー経由になります。
追加する価値があるファイアウォールルール
Tailscale は、通常は送信 UDP が許可されているため、ほとんどのネットワークでファイアウォールを変更せずに動作します。任意で 1 つルールを追加すると、直接接続できる可能性が高まります。UDP の送信元ポート 41641 からの送信を許可します。
家庭用ルーターや、送信 UDP を制限する職場のファイアウォールでは、送信元ポート 41641 の UDP を任意のアドレスおよび任意の宛先ポートへ送信できるようにします。さらに、STUN 用に宛先ポート 3478 への送信 UDP も許可します。宛先ポート 41641 だけを許可しても十分ではありません。ピアの NAT や設定によって、接続先のポートが任意のポートになる場合があるためです。ほとんどの家庭用ルーターは送信 UDP をすでにすべて許可しているため、何もする必要はありません。
VPS では、受信方向のルールが有効です。通常、VPS は自身のネットワークインターフェースにパブリック IP を持ちます。少なくとも、AWS のインターネットゲートウェイが行うような固定の 1 対 1 NAT です。そのため、UDP 41641 の受信ルールを追加すると、すべてのピアに安定して到達可能な接続先を提供できます。NAT の制約が厳しい環境にあるピアでも、自身のネットワークが UDP の送信を許可していれば、直接接続できる場合があります。UDP をブロックするネットワーク上のピアは、VPS 側の設定にかかわらずリレー接続になります。ufw では次のように設定します。
sudo ufw allow 41641/udp
sudo ufw statusufw status には、Anywhere からの ALLOW として 41641/udp が表示されます。管理パネルで別のネットワークファイアウォールを提供しているプロバイダーでは、そちらにも同じルールが必要です。プロバイダー側でパケットがブロックされると、ufw には到達しないためです。このルールは利便性のためのものであり、必須ではありません。ポートを閉じたままでも、VPS は tailnet に参加し、ピアから到達できます。ただし、一部の接続は直接接続ではなくリレー経由になります。
自宅の NAS や Raspberry Pi に外部から接続する
ケース1は最も簡単です。多くの人が「Tailscale によるポート転送」と呼ぶのは、自宅にない場所の laptop や phone から自宅の box に接続する構成です。
自宅の box と laptop に client をインストールします。設定はこれだけです。NAS や Pi で全インターフェースを対象に待ち受けているサービスは、転送設定なしで tailnet アドレスから利用できるようになります。127.0.0.1 または LAN アドレスだけに bind されているサービスは、待ち受け先を変更するまで tailnet からは見えません。
ssh pi@100.101.102.103
curl -I http://100.101.102.103:8080/アドレスは、自宅の box で tailscale ip -4 を実行した結果に置き換えます。SSH login は自宅の Wi-Fi 上での動作とまったく同じになるはずです。curl -I を実行すると、その box で動作している Web アプリの HTTP status line が表示されます。接続は、ログイン済みデバイスに紐付いた WireGuard key によって認証されます。そのため、SMB (server message block) share や Web admin panel のように、ポート転送で公開すると危険なサービスも、ここでは適切に利用できます。パケットを送信できるのは自分のデバイスだけだからです。間にある ipTIME や Fritz!Box は inbound connection を認識せず、変更も必要ありません。ISP によって CGNAT 配下に置かれている場合でも動作します。自宅の box から外向きの接続だけを確立し、必要な場合は relay を経由するためです。
新しい tailnet ではデフォルトで有効になっている MagicDNS により、すべての node に名前も割り当てられます。そのため、laptop が tailnet に接続されていれば ssh pi@nas も動作します。
Tailscale を実行できないデバイス: サブネットルーター
プリンター、IP カメラ、制限されたオペレーティングシステムを搭載した古い NAS、スマートテレビなど、クライアントを実行できないデバイスがあります。サブネットルーターを使えば解決できます。Tailscale を実行できるホームネットワーク上の 1 台のマシン(Pi で十分)がホームサブネット全体を広告し、他の tailnet デバイスはそのマシン経由でサブネットへルーティングします。
echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-tailscale.conf
sudo sysctl --system
sudo tailscale up --advertise-routes=192.168.0.0/24実際のホームサブネットを使用してください。その後、管理コンソールのマシンのルート設定でルートを承認する必要があります。また、Linux クライアントでは sudo tailscale set --accept-routes を使ってオプトインする必要があります。これで、ノートパソコンから ping 192.168.0.50 を実行すると、自宅のカメラに到達できます。転送用の sysctl は重要です。これを設定しないと、Pi は自身宛てではないすべてのパケットを破棄します。そのため、ルートが承認済みと表示されても、その先にあるデバイスは応答しません。承認手順、クライアント側のオプトイン、ルートが承認済みなのに到達できないその他の原因については、Tailscale サブネットルーターの実行を参照してください。そこでは VPS をルーターとして使用していますが、リビングルームの Pi にもそのまま適用できます。
ルーターのポートを開放せず、友人を Minecraft サーバーに参加させる
ケース2は、自宅の PC で Minecraft サーバーを運用し、友人にも参加してもらう構成です。従来の方法は、ルーターで TCP 25565 をポート転送し、公開 IP アドレスを伝えることでした。しかし、そのアドレスはインターネット上のすべてのスキャナーにも知られることになります。Tailscale では、代わりに共有を使用します。
方法は2つあります。1つ目は、友人をユーザーとして tailnet に招待する方法です。これは機能しますが、free plan のユーザー枠には上限があり、デフォルトでは招待したユーザーが tailnet 内のすべてのデバイスにアクセスできます。ゲーム用途には過剰であり、アクセスルールを記述して範囲を絞る必要があります。2つ目は、より簡単なノード共有です。管理コンソールで Machines ページを開き、ゲーム用 PC を見つけてメニューを開き、Share を選択します。Tailscale が招待リンクを作成します。各友人は自分専用の無料 Tailscale アカウントを作成する必要があります。このアカウントにより、それぞれが自分の小さな tailnet の所有者になります。そのアカウントでリンクを受け入れます。共有したマシンは相手のマシン一覧に表示されます。表示されるのはそのマシンだけです。共有では、共有先に許可したマシンへのアクセスだけが与えられ、tailnet 内の他のリソースにはアクセスできません。共有したマシンはデフォルトで隔離されます。友人の tailnet からの接続には応答できますが、自分から接続を開始することはできません。
友人は Minecraft で tailnet のアドレス 100.101.102.103:25565 を指定してサーバーを追加します。ポートがデフォルトの場合は、アドレスだけを指定できます。ゲーム用 PC ではポート転送が一切不要で、ルーターの設定も変更しません。共有したマシンはサブネットルートを広告しません。そのため、共有は共有先のマシン上で実行するサービスに使用できます。これはゲームサーバーの構成に適しています。
制限は、すべてのプレイヤーが Tailscale を実行し、共有を受け入れる必要があることです。友人同士のグループであれば問題ありません。誰でも参加できる公開サーバーには適していません。その場合の方法を次の2つのセクションで説明します。
VPS でゲームサーバーを運用し、RCON は tailnet 内に限定する
ポートフォワーディングを避けるもう 1 つの方法は、自宅でゲームをホストしないことです。VPS には直接到達できるパブリック IP があるため、自宅ルーターを介さずにゲームポートをインターネットへ公開できます。VPS で Minecraft サーバーを運用するでは、サイジング、Java のフラグ、バックアップ、systemd の unit について説明しています。ここで重要なのは、どのポートをインターネットへ公開するかです。
Minecraft サーバーは 2 つのポートを開きます。TCP 25565 はゲーム用で、プレイヤーに必要です。TCP 25575 は RCON(リモートコンソール)用で、パスワードを受け取った後、op や stop を含む任意のサーバーコマンドを実行します。インターネットに公開された RCON ポートは、パスワード推測攻撃の標的になります。VPS を tailnet に追加し、2 つのポートに異なるルールを設定します。
sudo ufw allow OpenSSH
sudo ufw allow 25565/tcp
sudo ufw allow in on tailscale0 to any port 25575 proto tcp
sudo ufw enable
sudo ufw status2 番目のルールは、全員にゲームへの接続を許可します。3 番目のルールは、tailscale0 インターフェースから到着したパケットに限って RCON を許可します。つまり、tailnet 内のデバイスと、VPS を共有しているユーザーだけが対象です。VPS を共有する場合は、tailnet のポリシーでアクセスルールを設定し、共有ユーザーが port 25575 に接続できないようにします。インターフェースのルールだけでは、共有ユーザーと自分のデバイスを区別できないためです。パブリック IP は引き続き 25565 で応答します。一方、パブリック側から 25575 へ接続すると、ufw のデフォルト拒否ポリシーによって破棄されます。tailnet 内にある laptop から、両方を確認します。
nc -zv 100.101.102.103 25575
nc -zv <vps-public-ip> 25575最初のコマンドは succeeded と表示するはずです。2 番目のコマンドは、パケットがパブリックインターフェースから到着し、許可ルールに一致しないため、しばらく待った後にタイムアウトするはずです。同じ構成は、SSH、Web マップ、データベース、metrics dashboard にも適用できます。パブリック IP では公開ポートだけを開き、管理用ポートは tailscale0 上だけで待ち受けます。
インターネット全体に公開する: Funnel または VPS リバーストンネル
3 つ目のケースは、Tailscale だけでは解決できません。ブログ、公開 API、公開ゲームサーバー、ステータスページなどが該当します。アクセスするユーザーは tailnet 内におらず、今後も参加しません。この用途に対応するツールは 2 つあり、それぞれ個別の記事で説明します。
Tailscale Funnel は、Tailscale のリレーを介して、ノード上の HTTPS サービスをパブリックインターネットに公開します。TLS (transport layer security) 経由でのみ動作し、使用できるポートも 443、8443、10000 に限られます。そのため Web アプリには適していますが、25565 のようなポートを使う生のゲームプロトコルには適しません。Tailscale Serve と Funnel の違いでは、それぞれが何を誰に公開するのかを説明します。
VPS リバーストンネルは、それ以外の用途に対応します。自宅のマシンがパブリック IP を持つ VPS へアウトバウンドトンネルを開き、VPS が任意のポート番号の TCP または UDP の公開ポートを、トンネル経由で自宅側へ転送します。CGNAT の背後にある自宅で公開 Minecraft サーバーを運用する場合は、この方法を使います。CGNAT の背後にある自宅サーバー向け VPS リバーストンネルで手順を説明します。この 2 つのどちらかを選び、世界中にポートを公開する Tailscale の設定を探し続けるのはやめてください。そのような設定はありません。
Tailscale が行わないこと
- 任意の公開クライアント向けにポートを転送することはありません。tailnet 外部の相手から送信されたパケットがノードに到達することはありません。その相手に対応する WireGuard key が存在しないためです。有効な key のない WireGuard パケットは、応答を返さずに破棄されます。
- 公開側に接続手段を提供することはありません。利用者は tailnet のメンバーになるか、共有された node を受け入れる必要があります。
- 直接経路を保証することはありません。NAT の通過が難しい場合、接続は relay 経由になり、速度が低下します。
- router を開放することはありません。router は閉じたままです。それが目的です。
FAQ
Tailscale にはポートフォワーディングが必要ですか?
いいえ。Tailscale の各ノードは、外向きの接続だけを確立します。TCP 80 で協調サーバーに接続し、ポート 80 が応答しない場合は TCP 443 の HTTPS にフォールバックします。また、UDP 3478 の STUN で自身のパブリックアドレスを取得します。各ピア接続は、まず TCP 443 の DERP 経由で中継されます。これも外向きの接続です。その後、UDP 41641 から UDP ホールパンチングを行い、直接経路へ切り替えます。ホールパンチングに失敗した場合、設定済みのピアリレーがあればそこへ通信を移し、なければ DERP を使い続けます。家庭用ルーターでポートフォワーディングや DMZ ホストを設定する必要はありません。CGNAT 配下のデバイスも同じ方法で参加できます。
Minecraft サーバーで Tailscale はポートフォワーディングの代わりになりますか?
はい。友人が接続するサーバーであれば可能です。ゲーム PC に Tailscale をインストールし、admin console の Machines ページから各友人にそのマシンを共有します。友人は、ポートを転送せずに、そのマシンの tailnet アドレスのポート 25565 へ接続できます。パブリックサーバーの場合、ポートフォワーディングの代わりにはなりません。tailnet 外のプレイヤーはそのノードへ到達できないためです。その場合は、パブリック IP を持つ VPS でゲームをホストし、RCON は tailnet 上に残します。または、自宅のマシンから VPS へのリバーストンネルを使用します。
Tailscale が使用するポートはどれですか?
4 つです。外向きの TCP 80 は、優先される協調サーバー接続です。Tailscale 独自の暗号化トランスポートで通信します。外向きの TCP 443 は、ポート 80 が応答しない場合のフォールバックです。この接続では常に DERP リレーの通信も運びます。外向きの UDP 3478 は STUN に使用し、パブリックアドレスを検出します。UDP 41641 は、直接接続に使用するデフォルトのローカル WireGuard ポートです。このポートから、ピア側が使用する任意のポートへパケットを送信します。41641 が使用中の場合は変更できます。これらのポートをインバウンドで開放する必要はありません。TCP 80 をブロックしても問題ありません。クライアントが 443 にフォールバックするためです。VPS でインバウンドの UDP 41641 を許可する設定は任意ですが、ピアが直接経路を使用できる可能性が高くなります。
Tailscale の接続が直接ではなく中継になるのはなぜですか?
tailscale ping は、UDP ホールパンチングを完了できない場合も via DERP に応答し続けます。一般的な原因は、ホールパンチングで通過できない NAT(CGNAT、または宛先ごとに新しいポートを割り当てる対称 NAT)と、外向きの UDP をブロックするファイアウォールです。管理できる範囲を修正してください。任意の宛先ポートに対して、UDP 41641 から外向きの UDP を送信できるようにします。UDP 3478 への外向きの UDP を許可します。または、一方のピアをインバウンドの UDP 41641 を開放した VPS に配置します。これにより、もう一方のピアは固定された到達可能な宛先に対してホールパンチングを実行できます。自身のネットワークで UDP がブロックされているピアは、どの方法でも中継接続になります。