Tailscale serveとfunnelの違いと使い分け
Tailscale serveはtailnet内限定、funnelは同じポートを公開します。Tailscale 1.38.3以降とHTTPS証明書が必要で、funnelにはポリシーのnode attributeも必要です。
tailscale serve と funnel: URL にアクセスできるユーザー
tailscale serveとtailscale funnelの違いは、アクセスできるユーザーだけです。それ以外に違いはありません。serveはローカルポートの前段に HTTPS(hypertext transfer protocol secure)を配置し、tailnet 内だけに公開します。funnelは、Tailscale が運用するリレーサーバー経由で、同じローカルポートをパブリックインターネット全体に公開します。2 つのコマンドで指定するフラグと対象は同じです。プライベートなダッシュボードと、世界中からアクセスできるダッシュボードを分けるのは、1 つの単語です。
どちらを使っても、ブラウザーがすでに信頼している証明書が、ts.netで終わる名前に対して発行されます。また、VPS のファイアウォールで受信ポートを開く必要もありません。tailscaledデーモンはすでに tailnet への外向き接続を保持しているため、トラフィックはその接続経由で到達します。サーバーを tailnet に参加させる作業については、VPS を Tailscale exit node として動かすまたはプライベートネットワーク向けに subnet router を広告するで説明しています。すでに tailnet 上にあるサービスを公開する方法が、ここで扱う内容です。
両方のコマンドを実行する前に必要なもの
- VPS に Tailscale 1.38.3 以降をインストールし、tailnet にログインしておきます。
tailscale versionとtailscale statusで確認できます。 - MagicDNS を有効にします。MagicDNS は Tailscale 組み込みの DNS(domain name system)です。これにより、マシンに
100.xアドレスだけでなく、blog-vps.your-tailnet.ts.netのような名前を付けられます。 - tailnet の HTTPS 証明書を、管理コンソールの DNS ページで有効にします。これを設定しないと、ポートの前段に配置する証明書がありません。
funnelの場合のみ、tailnet ポリシーファイルにfunnelnode attribute が必要です。ここで最初の試行が止まることが多いため、以下で説明します。
ここで使用するすべてのコマンドは sudo で始まります。CLI は root だけが書き込み可能なソケットを介して tailscaled と通信するためです。1 人のユーザーに、この制限を回避する権限を付与します。
sudo tailscale set --operator=$USERtailscale serve で tailnet に公開する
serve をローカルポートに向けるだけで、あとは tailscale serve が処理します。
sudo tailscale serve 3000Available within your tailnet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.単独の 3000 は http://127.0.0.1:3000 の省略形です。Tailscale はマシンの tailnet アドレスの 443 番ポートで待ち受け、ts.net 証明書を使用して TLS(トランスポート層セキュリティ)を終端し、プレーン HTTP をローカルポートへ転送します。アプリケーションが証明書の存在を認識する必要はありません。これは、通常ならプレーン HTTP のままにしてしまう管理パネルの前段で利用する主な理由です。
次に最後の行を確認します。Press Ctrl+C to exit. このコマンドはフォアグラウンドで実行され、マッピングはそのプロセス内に保持されます。ターミナルを閉じると URL は機能しなくなります。ディスクには何も書き込まれていないためです。--bg を追加すると、マッピングはノードの serve 設定に保存されます。この設定はターミナルを閉じた後も再起動後も維持されます。
sudo tailscale serve --bg 3000Serve はポート番号以外も指定できます。--set-path を使うとサービスをサブパス配下に配置できるため、複数のアプリで 1 つのホスト名を共有できます。
sudo tailscale serve --bg --set-path=/grafana 3000
sudo tailscale serve --bg --set-path=/metrics 9090ターゲットには静的ファイルのディレクトリや、すでに TLS で通信しているバックエンドも指定できます。証明書を検証したくない場合は、次のようにします。
sudo tailscale serve --bg /srv/reports
sudo tailscale serve --bg https+insecure://localhost:8443HTTP に限定されるわけでもありません。--tcp=<port> は生の TCP(トランスポート制御プロトコル)ストリームを転送します。--tls-terminated-tcp=<port> はノードで TLS を終端し、復号した通信を転送します。これにより、HTTP をまったく話さないサービスの前段にも信頼できる証明書を配置できます。
sudo tailscale serve --bg --tls-terminated-tcp=443 tcp://127.0.0.1:9899Funnel でノード属性が設定されていないと表示されるのはなぜですか?
デフォルトでは、tailnet 全体で Funnel が無効になっています。初回実行時には次のメッセージが表示され、停止します。
Funnel not available; "funnel" node attribute not set. See https://tailscale.com/kb/1223/tailscale-funnel/.コマンドは正しいです。tailnet ポリシーで、このノードに公開権限が付与されていません。そのため、クライアントは relay に接続する前に処理を拒否します。管理コンソールの Access Controls で tailnet ポリシーファイルを編集し、次の属性を追加します。
"nodeAttrs": [
{
"target": ["autogroup:member"],
"attr": ["funnel"],
},
],autogroup:member は、tailnet の全メンバーに属性を付与します。公開するマシンを 1 台だけに限定する場合は、そのマシンにタグを付け、代わりにタグを対象にします。たとえば tag:public のように指定します。ポリシーを保存してから、Funnel コマンドを再度実行します。
アカウントが tailnet admin の場合、最近のクライアントではショートカットを利用できます。CLI が login.tailscale.com に同意 URL を表示するので、その URL にアクセスすると HTTPS 証明書が有効になり、属性も追加されます。admin でない場合、その URL は役に立ちません。ポリシーを編集できるユーザーが変更する必要があります。
インターネットにtailscale funnelで公開する
属性を設定したら、使うコマンドは、動詞だけが異なる、すでに知っているコマンドです。
sudo tailscale funnel --bg 3000Available on the internet:
https://amelie-workstation.pango-lin.ts.net
|-- / proxy http://127.0.0.1:3000
Press Ctrl+C to exit.毎回、最初の行を必ず確認してください。Available within your tailnetとAvailable on the internetが、非公開サービスと公開サービスの目に見える唯一の違いです。これらを作成するコマンドは、1語しか違いません。
2026年8月時点で、funnelが待ち受けるポートは443、8443、10000だけです。それ以外のポートでは待ち受けません。デフォルトは443で、--https=8443または--https=10000が代替です。funnelのリレーはこれらのポートでのみ接続を受け付けるため、その他のポートは拒否されます。そのため、funnelのURLは常にホスト名だけになるか、末尾に:8443を付けた形式になります。
現在公開されている内容を確認するにはどうすればよいですか?
推測に頼ると、ダッシュボードを 1 か月間公開したままにしてしまいます。ノードに確認してください。
tailscale serve status
tailscale funnel status
tailscale serve status --jsonどちらの status コマンドも同じ設定を読み取るため、どちらを使っても全体を確認できます。スクリプトや定期チェックでは --json 形式を使用してください。通常の出力は人が読むための形式です。何も設定されていない場合は、次の 1 行が表示されます。
No serve config正常に完了した設定の後でこの表示になった場合、マッピングはフォアグラウンドで作成され、プロセスが終了しています。--bg で再作成してください。
1 つのマッピングを削除するには、作成時に使用したコマンドを再度実行し、末尾に off を追加します。ノード上のすべての serve と funnel のマッピングを削除するには、reset を使用します。
sudo tailscale funnel --https=443 3000 off
sudo tailscale serve resetどちらかの操作の後にもう一度 tailscale serve status を実行し、残っている内容を確認してください。意図した結果になったと決めつけないことが重要です。
得られるものと、失うもの
利点は明確です。リバースプロキシではなく、こちらを選ぶ理由でもあります。
- ブラウザーが信頼する証明書を取得でき、更新も自動で行われます。ACME(自動証明書管理環境)クライアントをインストールする必要も、更新ジョブを忘れる心配もありません。
- VPS のファイアウォールでインバウンドポートを開く必要がありません。
tailscaledは外向きに接続するため、VPS のデフォルト拒否 ufw ファイアウォールをこれまでと同じ厳しい設定に保てます。 - DNS レコードを購入、設定、反映待ちする必要がありません。
- ポートフォワーディングが不要です。これは、パブリック IP を持つ VPS ではなく、NAT(ネットワークアドレス変換)の背後にあるマシンでは特に重要です。
コストも同じく明確です。funnel には、そのすべてが当てはまります。
- 名前を所有できません。外部の訪問者に表示されるのは
host.your-tailnet.ts.netです。funnel はカスタムドメインに対応していないため、app.example.comを前面に置くことはできません。 - パスを管理できません。トラフィックはまず Tailscale のリレーに到達し、そのリレーが tailnet 経由でストリームをノードへプロキシします。Tailscale によると、funnel のトラフィックには公開されておらず、設定もできない帯域幅制限が適用されます。そのため、特定の数値を前提にする前に、実際のスループットを測定してください。
- 制御機能がありません。自分で運用するリバースプロキシなら、アクセスログ、レート制限、リクエストサイズ上限、認証を配置する場所を利用できます。funnel が提供するのは URL だけです。それ以外の機能はすべてアプリケーション内に実装する必要があります。
- ポート一覧は前述のとおり固定されています。
どちらの機能も、Tailscale が運用するインフラストラクチャに依存しています。ts.net の名前に対する証明書の発行と、funnel のリレー自体が該当します。Headscale の自己ホスト型コントロールサーバーを検討している場合、これらがその環境でも利用できるとは考えないでください。実行する予定の Headscale のバージョンについて、リリースノートを確認してください。
どちらを使うべきですか?
ルールは簡単です。
内部用途には serve を使用します。対象は、管理インターフェース、ダッシュボード、インデックス登録させたくないメトリクス UI、サイトのステージング環境などです。アクセス制御は tailnet のメンバーシップで行います。これは十分に有効な方法です。tailnet に接続していないデバイスは、その名前を解決することさえできません。
デモ用リンク、第三者から POST を受ける必要がある webhook receiver、開発中の OAuth callback には funnel を使用します。公開 HTTPS URL を最も速く用意でき、off コマンド 1 つで終了できます。ただし、公開される情報は公開されます。ホスト名は秘密ではなく、ログイン機能のないアプリの前段に funnel を置くと、公開サービスになります。その背後にあるものは、受信するリクエストを自ら認証する必要があります。これは、公開された Ollama API エンドポイントと同じ注意が必要です。
本番環境で使用するものには、実際のリバースプロキシを使用します。自分のドメイン、自分の証明書、自分のログ、独自のレート制限を使い、リクエスト経路に他者を介在させません。リバースプロキシとして nginx、Caddy、Traefik を比較するでは、選択方法を説明しています。
エラーが発生する場合と表示される文字列
Funnel が起動しません。 Funnel not available; "funnel" node attribute not set. はコマンドの問題ではなく、ポリシーの問題です。tailnet のポリシーファイルに funnel 属性を追加して保存し、再実行してください。
動作していましたが、現在は tailscale serve status に No serve config と表示されます。 マッピングをフォアグラウンドで作成していたため、そのプロセスが終了しています。同じコマンドを --bg 付きで再実行してください。
名前は解決されますが、応答がありません。 Serve は指定したターゲットへプロキシするため、そのアドレスで待ち受けているプロセスがなければ、プロキシ先もありません。tailscaled を実行している同じマシンで ss -ltnp | grep 3000 を実行し、確認してください。よくある原因は、コンテナがポートを 127.0.0.1 ではなく Docker ブリッジのアドレスに公開していることです。この場合、ホストからは想定した場所で待ち受けているプロセスが見えません。Docker Compose のネットワークの仕組みでは、公開ポートが実際にどこへ割り当てられるかを説明しています。
ts.net の名前で証明書エラーが発生します。 tailnet で HTTPS 証明書が有効になっていない可能性が高いです。管理コンソールで有効にしてから、証明書の処理を単独で実行してください。これにより、エラーが Serve の出力に紛れません。
sudo tailscale cert your-host.your-tailnet.ts.netモバイルデータ通信では Funnel が読み込めますが、ノートパソコンとは挙動が異なります。 ノートパソコンは tailnet に接続されているため、MagicDNS は名前を 100.x アドレスに解決し、relay を経由せずにサービスへ直接接続します。これは正常な動作です。つまり、ノートパソコンではパブリック環境からの到達性をまったくテストできません。tailnet に接続されていないマシンから curl を使用してください。
FAQ
tailscale serve と tailscale funnel の違いは何ですか?
結果にアクセスできる対象が異なります。tailscale serve はローカルポートを HTTPS URL で公開します。この URL にアクセスできるのは、tailnet 上のデバイスだけです。tailscale funnel は同じポートを、インターネット上の誰でもアクセスできる URL で公開します。通信は Tailscale が運用するリレーサーバーを経由します。フラグと対象は両者で共通です。最初の出力行に、どちらを使用したかが Available within your tailnet または Available on the internet と表示されます。
tailscale funnel で node attribute が設定されていないと表示されるのはなぜですか?
誰かが有効化するまで、tailnet では funnel が無効になっているためです。メッセージは Funnel not available; "funnel" node attribute not set. です。これはリレーへの接続前に、ローカルのクライアントが表示します。Access Controls の下にある tailnet policy ファイルへ nodeAttrs エントリを追加し、funnel 属性を autogroup:member に付与します。1 台のマシンだけが公開する場合は、autogroup:member の代わりにタグを指定します。tailnet 管理者は、CLI が出力する同意 URL にアクセスして有効化することもできます。
Tailscale Funnel で使用できるポートはどれですか?
443、8443、10000 のみです。デフォルトは 443 です。--https=8443 または --https=10000 を使用すると、別のポートを選択できます。これはサーバーではなく funnel リレーの制限です。そのため、VPS のファイアウォールや設定を変更しても、この制限は解除できません。tailscale serve にはこの制限がありません。通信が tailnet の外部へ出ないためです。
serve または funnel の URL は再起動後も維持されますか?
--bg を使用した場合だけ維持されます。これを指定しない場合、コマンドはフォアグラウンドで実行され、Press Ctrl+C to exit. を出力します。プロセスが終了すると、マッピングも消えます。--bg を使用すると、マッピングがノードの serve 設定に保存されます。再起動後は tailscaled によって復元されます。tailscale serve status で確認できます。何も設定されていない場合は No serve config が出力されます。
funnel を実行したままにしても安全ですか?
通信の観点では安全です。接続は HTTPS で、ファイアウォール上のポートも開きません。ただし、一般的な意味で安全とは限りません。URL が公開されるため、その背後にあるアプリケーションも公開されるからです。funnel は、リクエスト自体を認証する機能を持つものの前段でだけ使用してください。デモや webhook のテストが終わったら、作成時に使用したコマンドの末尾へ off を付けて停止してください。
上記のコマンド動作の出典は、tailscale.com/docs にある Tailscale Serve および Funnel のドキュメントと CLI リファレンスです。