ローカルを固定のドメインで公開したい - Cloudflare Tunnel 編

最近の個人の開発では LINE Bot を作ったり OpenAI API で遊ぶことが多い。その時外部からローカルのサーバーへのリクエストを受け付けたいことがある。例えば LINE Bot だと webhook の URL がある。今回はこれを Cloudflare Tunnel を使って解決する。

Cloudflare Tunnel

Cloudflare Tunnel は Cloudflare の提供するプロダクトの1つで、自分の環境を public な IP address なしで接続できるソリューションを提供します。public な IP address なしでどうやって接続するの?という疑問は下記公式ドキュメントの "How it works" が図を使って説明しているのでそちらを見てください。 developers.cloudflare.com

準備

Zone のセットアップを済ませておきます。Cloudflare はいくつかのセットアップ方法を提供していますが自分は Free plan を使用しているので Full setup を使用しました。

設定

今回は Cloudflare Tunnel の設定を Cloudflare とローカルで行います。 Cloudflare 上の設定に関しては Terraform で Cloudflare 公式の cloudflare provider を使用して行います。

Cloudflare 上の設定

まずは Cloudflare Tunnel のリソースを cloudflare_tunnel を使用して作成します。

resource "random_password" "cloudflare_tunnel_example" {
  length = 64
}

resource "cloudflare_tunnel" "example" {
  account_id = "your account id"
  name       = "example"
  secret     = base64encode(random_password.cloudflare_tunnel_example.result)
  config_src = "local"
}

ポイントとしては config_srclocal を指定している部分です。これは Cloudflare Tunnel の設定をローカルと Cloudflare 上どちらで管理するかを示します。今回はローカルのサーバーを公開するためローカルから設定できたほうが都合が良いので local を指定しました。

cloudflare_tunnel リソースの作成に成功すると Tunnel ID が生成されます。Tunnel ID は cloudflare_tunnel.example.id で取得できます。この Tunnel ID を使用して [your tunnel id].cfargotunnel.com でアクセスします。

今回は自分が用意したドメイン経由でアクセスしたいので cloudflare_record を使って CNAME レコードを作成します。今回は例として example.com zone を使用します。

resource "cloudflare_record" "local_example_com" {
  zone_id = "your zone id"
  name    = "local"
  value   = cloudflare_tunnel.example.cname
  type    = "CNAME"
  proxied = true
}

これで Cloudflare 側の設定は完了です。

Local の設定

Cloudflare Tunnel では cloudflared というデーモンを使用するので、公式の手順を参考にローカルマシンにインストールしておきます。

cloudflared が特定の Cloudflare Tunnel でのみ動くことを保証するために認証情報が必要となります。これは cloudflared tunnel token --cred-file .cloudflared-cred.json [your tunnel id] で取得することができます。あとは cloudflared を起動するだけです。今回は例として localhost:8787 を公開したいとします。その場合は下記のコマンドによって cloudflared を起動します。

$ cloudflared tunnel run --url http://localhost:8787 --cred-file ./.cloudflared-cred.json example

コマンドライン上で渡すものが多くなってきた場合は下記のような YAML ファイルを作っておくことで cloudflared tunnel --config ./config.yml run で起動できます。

tunnel: example
credentials-file: .cloudflared-cred.json

ingress:
- service: http://localhost:8787

アクセス

ここまで設定が終われば後は 「Cloudflare 上の設定」で作成した CNAME レコードを使ってアクセスすることができます。今回の例だと local.example.com です。

まとめ

Cloudflare Tunnel 便利!