🌐

Cloudflare Tunnnel を使った自宅サーバの公開

に公開

ほとんどのインターネット契約はプロバイダの都合でグローバル IP アドレスが定期的に変更されるため、インターネットに公開するとなるとアドレス変更への対応が非常に面倒です

Cloudflare Tunnel はサーバ内で稼働し、Cloudflare の DNS を使って直接インターネットに公開する仕組みです

つまり DNS 側からサーバを探すのではなく、サーバ内で稼働するプロセスがドメインとサーバを直接紐づけてくれるため、これを使うことで面倒なアドレス管理などを考える必要がなくなります
さらに自動的に SSL で保護してくれるため、証明書のインストールなども必要ありません

前提条件

独自ドメインを保有していること、Cloudflare のコンソールでそのドメインの DNS レコードを変更できることが前提です
Cloudflare でドメインを購入している必要はありません(そのほうが設定が楽ですが)
自分も Squarespace で購入したドメインを使い Raspberry Pi サーバを公開しています

手順

Cloudflare CLI のインストール

公式ドキュメント に従う
例えば Debian ベース(Ubuntu や Raspberry Pi OS も含む)であれば次のようになる

# Add cloudflare gpg key
sudo mkdir -p --mode=0755 /usr/share/keyrings
curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null

# Add this repo to your apt repositories
echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list

# install cloudflared
sudo apt-get update && sudo apt-get install cloudflared

トンネル作成

トンネル作成方法は、ローカル(サーバ上)で作成する方法と Cloudfalre Zero Trust 管理画面で作成する方法がある
ここでは、より簡単なローカル作成を採用する
※ ただし、ローカル作成の場合管理画面からの管理ができないなど少し制限があるためどちらがよいかはユースケースに合わせて要検討

# ログイン
cloudflared tunnel login

# トンネル作成
cloudflared tunnel create <任意のトンネル名>

設定ファイル作成

まず、トンネル ID を確認する
作業フォルダに作成された JSON ファイル名がそのままトンネル ID となる

ls ~/.cloudflared/
# 550e8400-e29b-41d4-a716-446655440000.json があった場合、ID はそのまま "550e8400-e29b-41d4-a716-446655440000"

ID を確認したら、設定ファイルを作成する

vim ~/.cloudflared/config.yml

ファイルに次のように記載する

tunnel: <作成時に指定したトンネル名>
credentials-file: /home/<ユーザー名>/.cloudflared/<トンネルID>.json

ingress:
  - hostname: myapp.example.com # インターネット上での URL
    service: http://127.0.0.1:3000 # ローカルホスト上での URL

  - service: http_status:404 # 末尾に必ず記載

DNS 設定追加

Cloudflare 管理画面で次のレコードを追加

  • Type: CNAME
  • Name: <任意のサブドメイン> # 上記例の場合、"myapp"
  • Target: <ドメインID>.cfargotunnel.com
  • Proxy status: Proxied
  • TTL: Auto

トンネル起動確認

下記コマンドでトンネルを起動し、
指定したインターネット URL でローカルホストのアプリケーションに接続できることを確認する

sudo cloudflared tunnel run <トンネル名>

例: 次のコマンドの結果が同じであることを確認

curl https://myapp.example.com
curl http://127.0.0.1:3000

トンネルを起動するとフォアグラウンドで稼働し続けるため、
nohup を使うか何かしらプロセス管理ツールを使わないと不便です
そのため、下記手順で systemctl に登録してしまうことを強く推奨します

systemctl 設定(任意)

systemctl を使い、サーバ起動時に自動的にトンネルを設定するようにすることが可能

まず、設定ファイルを作成する

sudo vim /etc/systemd/system/cloudflared.service

設定ファイルに次のように記載する

[Unit]
Description=cloudflared Tunnel
After=network-online.target
Wants=network-online.target

[Service]
TimeoutStartSec=0
Type=notify
ExecStart=/usr/bin/cloudflared --no-autoupdate --config /home/<ユーザー名>/.cloudflared/config.yml tunnel run
Restart=on-failure
RestartSec=5s

[Install]
WantedBy=multi-user.target

systemctl での起動が可能になる

sudo systemctl start cloudflared

自動起動を有効化する場合、次のコマンドを実行する

sudo systemctl enable cloudflared

Discussion