SSD Nodes Learn Hosting plans →
ガイド Matt Connor著者 Matt Connor

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 -4

tailscale 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 status

ufw 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 status

2 番目のルールは、全員にゲームへの接続を許可します。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 がブロックされているピアは、どの方法でも中継接続になります。