Cloudflare Tunnelで自宅サービスを独自ドメインで公開する:Tailscaleとの使い分けも整理

Photo: Brett Sayles / Pexels
自宅サーバーに Jellyfin や Nextcloud を立てると、次に来るのが「外からも見たい」です。ルーターのポート開放は避けたい。かといって Tailscale だと、アプリを入れていない人には渡せません。
ここで出てくるのが Cloudflare Tunnel です。先に結論を書きます。
自分と家族だけが使うなら Tailscale、アプリを入れていない相手にも URL を渡すなら Cloudflare Tunnel。 そして Cloudflare Tunnel を使うなら、公開と同時に Cloudflare Access で鍵をかけるところまでが 1 セットです。ここを分けて考えると、まず間違いなく「裸のサービスがインターネットに出ている」状態を作ってしまいます。
Tailscale と Cloudflare Tunnel はどちらが上でもない
両方とも「ポート開放せずに外から自宅へ入る」ための道具ですが、向いている場面が違います。
| Tailscale | Cloudflare Tunnel | |
|---|---|---|
| 接続する側の準備 | アプリのインストールとログインが必要 | ブラウザだけ。URL を開けば済む |
| 扱えるもの | SSH・SMB・RDP など何でも | 基本は HTTP/HTTPS。他はひと手間 |
| 独自ドメイン | 基本は .ts.net の名前 | 自分のドメインで公開できる |
| 必要なもの | アカウントのみ | Cloudflare で管理しているドメイン |
| 無料枠 | 個人向けは 3 ユーザー / 100 デバイスとされています | Zero Trust の無料枠は 50 ユーザーまでとされています |
私の使い分けはこうです。管理用(SSH、Proxmox の画面、NAS の共有フォルダ)は Tailscale。人に見せるもの(写真アルバム、家族が使う Web UI)は Cloudflare Tunnel。 管理系まで Web に出す理由はないので、無理に片方へ寄せないほうが安全です。
準備:ドメインを Cloudflare に預ける
Cloudflare Tunnel で独自ドメインを使うには、そのドメインのネームサーバーを Cloudflare に向けておく必要があります。ドメイン自体はどこで買っても構いませんが、DNS の管理は Cloudflare 側に移します。
Cloudflare の管理画面でドメインを追加すると、2 つのネームサーバーが表示されます。それをレジストラ側に設定し、反映を待ちます。反映前にトンネルを作っても、ルートの追加でドメインが選べません。
ステップ1:トンネルを作る
昔の記事だと cloudflared tunnel login から始まる手順が多いのですが、今は管理画面で作る「リモート管理トンネル」が標準です。設定が Cloudflare 側に保存されるので、サーバー上に設定ファイルを置かずに済みます。
one.dash.cloudflare.com にログインし、Networking → Tunnels → Create a tunnel から Cloudflared を選び、名前を付けます(home-01 など)。
次の画面で OS を選ぶと、そのままコピーできるインストールコマンドが出ます。Debian / Ubuntu なら、こういう形です。
curl -L https://pkg.cloudflare.com/cloudflared.deb -o cloudflared.deb
sudo dpkg -i cloudflared.deb
sudo cloudflared service install eyJhIjoi...(長いトークン)
最後のトークンがそのトンネルの鍵そのものです。ブログや Discord に貼らないでください。貼った時点で、他人が同じトンネルの出口を名乗れます。
Docker で揃えているなら、Compose に足すほうが管理しやすいです。
services:
cloudflared:
image: cloudflare/cloudflared:latest
restart: unless-stopped
command: tunnel --no-autoupdate run
environment:
- TUNNEL_TOKEN=${TUNNEL_TOKEN}
トークンは .env に置き、.env は Git に入れないようにします。
数十秒待って、管理画面のトンネル一覧が Healthy になれば接続できています。ならない場合は、サーバーから 外向き TCP/UDP 7844 が出られるかを確認します。外向きだけなので、ルーター側の設定は基本的に不要です。
ステップ2:ルート(公開ホスト名)を足す
トンネル自体は「道」でしかないので、どの名前をどのサービスに繋ぐかを決めます。
トンネルの Routes タブから Add route → Published application を選び、次を入れます。
- Subdomain:
photos - Domain: 自分のドメイン
- Service:
http://localhost:2283(サービスの待ち受け先)
保存すると、DNS の CNAME まで自動で作られます。数秒後には https://photos.example.com が開くはずです。証明書も Cloudflare 側で用意されるので、Let’s Encrypt の更新を気にする必要はありません。
なお、UI の表記は改定が入っており、少し前までは Public Hostname という名前でした。画面が違っても、やることは「サブドメイン」と「ローカルの URL」を紐付けるだけです。
複数サービスを出すときは、1 本のトンネルにルートを増やすのが素直です。Jellyfin 用、Immich 用とトンネルを分けても動きますが、動かすプロセスが増えるだけで得はありません。
ステップ3:Access で鍵をかける(ここを飛ばさない)
ここまでの状態は、世界中の誰でもその URL を開ける状態です。 検索避けは対策になりません。公開した瞬間から、証明書の透明性ログ経由でホスト名は拾われるとされていて、自動アクセスは普通に来ます。
Zero Trust の Access → Applications → Add an application → Self-hosted で、さきほどのホスト名を指定します。ポリシーは最初これで十分です。
- Action: Allow
- Include: Emails に自分と家族のアドレスを列挙
- 認証方法: One-time PIN(メールに届く数字を入れる方式)
これで、URL を開くとまず Cloudflare の認証画面が挟まります。Google や GitHub を ID プロバイダーに設定すれば、パスキーでのログインも使えます。
ひとつ注意があります。スマホアプリから使うサービスは、この認証と相性が悪いことがあります。 Immich や Nextcloud のアプリはブラウザのログイン画面を通れないため、アプリ用のパスを Access の対象から外す(Bypass にする)といった調整が必要になります。その場合、アプリ側の認証が唯一の防御になるので、パスワードは必ず強くしてください。
無料枠でやらないほうがいいこと
- 動画配信の常用:Cloudflare の規約では、CDN を通して大きな動画などを配信するのは、Stream や R2 といった同社のサービスに置いた場合を前提にすると整理されています。Jellyfin の常時ストリーミングを無料枠で回すのは、規約上グレーで、止められても文句が言えない使い方です。動画は Tailscale 経由にしておくのが無難です
- 大きなファイルのアップロード:無料・Pro プランではリクエストボディの上限が 100MB とされています。Nextcloud に動画を上げると途中で失敗します。チャンク分割の設定を入れるか、アップロードは LAN 内で済ませます
- SSH や RDP をそのまま通す:HTTP 以外は
cloudflared accessクライアントや WARP が要ります。その手間をかけるなら Tailscale のほうが早いです - 管理画面を公開する:Proxmox や OpenMediaVault の UI を出す理由はありません。Tailscale 側に置きます
つまずいたときの見どころ
502 Bad Gateway が出たら、ほぼ Service に書いた URL とサービスの実際の待ち受けが噛み合っていないケースです。cloudflared を Docker で動かしている場合、localhost はコンテナ自身を指すので、http://immich-server:2283 のようにコンテナ名で書くか、同じネットワークに載せます。
接続が不安定なときは、QUIC が通っていない可能性があります。--protocol http2 を付けて起動し、改善するか見てみてください。
常時起動させる以上、サーバー側は落ちない構成にしておきたいところです。N100 クラスのミニPCなら消費電力も小さく、cloudflared を常駐させても気になりません。停電対策まで含めるなら小型の UPSも候補になります。
まとめ
- Tailscale は自分用、Cloudflare Tunnel は人に渡す用。片方に寄せず、管理系は Tailscale に残します
- 手順は ドメインを Cloudflare に預ける → トンネル作成 → ルート追加 → Access で保護 の 4 つです
- 今はダッシュボードで作るリモート管理トンネルが標準。サーバー側はトークンを渡すだけで、外向き 7844 が出られれば繋がります
- Access の設定までが 1 セット。ルートを足した時点の URL は、誰でも開ける状態です
- 無料枠では 100MB のアップロード上限と、動画配信が規約上グレーな点に注意します
502はほぼ Service の URL 間違い。Docker ならlocalhostではなくコンテナ名で書きます
ポート開放の設定と DDNS の更新に悩んでいた時間が、まるごと無くなります。「外に出す」と「鍵をかける」を同じ作業として扱う、それだけ守れば怖い仕組みではありません。
運営者が作った Excel テンプレートを BOOTH で配布しています。IT 資産管理台帳(無料 Lite 版あり) / IT 資格の学習管理シート


