ローカルに立てたアプリケーションを、Cloudflareを使って独自ドメインかつ認証機能付きで限定公開する
概要
自分が作ったウェブアプリケーションを少数ユーザにさくっと公開して使ってほしい、できればIPアドレス直打ちではなく独自ドメインを使って、なおかつ認証機能も付けておきたい、という条件でクラウドなどあれこれ試した結果、Cloudflareエコシステムで実現することができました。
今回は大まかな技術スタックで実現方法を解説しつつ、あれこれ試行錯誤して選択しなかった方法などにも触れつつ紹介していきたいと思います。
利用したサービス
Cloudflare Register
ドメインはCloudflareで購入しました。
Cloudflare Tunnels
ウェブアプリケーションは、自宅で常時起動しているプライベートなサーバの中でアプリケーションを起動して、それをCloudFlare Tunnelsを使って外部に公開します。
詳細は割愛しますが、以下のようにcloudflared tunnel create
をするとtunnel IDが発行され、それをもとに設定ファイルを書いて実行するだけです。
$ cloudflared tunnel login
$ cloudflared tunnel create <NAME>
$ cloudflared tunnel --config ~/.cloudflared/config.yaml run <NAME>
# ~/.cloudflared/config.yaml
url: http://localhost:8501
tunnel: <Tunnel-UUID>
credentials-file: /home/yag_ays/.cloudflared/<Tunnel-UUID>.json
Cloudflare Access
認証機能はCloudflare Accessを利用します。今回はオーソドックスな認証方法である、メールアドレスにPINが送られて、それを入力することで認証が通るというシステムにします。
まずAccess Groupで認証を通すユーザの属性を設定します。ここでは、特定のメールアドレスもしくは、メールアドレスの末尾(ドメイン)が特定のユーザに限定しています。こうするとことで、自分を含めて、任意のユーザのみが認証を通るようにします。この条件以外のユーザがアクセスしても、そのユーザのメールアドレスに認証用のメールが送られることはありません。
このAccess Groupを用いて、Applicationsで設定を行います。アプリケーションタプはSelf-Hostedとし、サブドメインを設定することで他のウェブアプリケーションを作ったときにも同じドメインを使うことができます。先ほど作成した認証を通すユーザのグループは、設定の中のAssign a groupで紐づけます。
動作確認
それでは実際にアクセスして動作確認します。サブドメイン付きのURLにアクセスすると以下の認証ページが表示され、メールアドレスを入力するとcodeを求められます。
メールを確認すると、以下のようにログイン用のURLおよび6桁のcodeが記載されているので、どちらでも好きな方で認証を通すことで、ウェブアプリケーションにアクセスすることができます。認証後に有効なセッション時間等は、Cloudflareで設定が可能です。
選択しなかった方法
さて、ここまででCloudflareを使った一連の方法を紹介しましたが、逆に選択しなかった方法も合わせて紹介します。私はネットワークやクラウド周りは素人のため勘違いや知識不足はあるかもしれません、間違っていたらごめんなさい 🙏
[ドメイン] Google Domain
Google Domainsは、以前ではドメインを購入/管理する上で便利でかつGCPのクラウドとの連携も容易と思われたのですが、Squarespaceが買収したことによって選択肢からは除外しました。
[アプリ公開] GCPの利用
当初はGCPのComputing Engine上で動かしており、外部IPを割り振って公開できる状態ではありました。ここから独自ドメインを設定したりIdentity Platform等でGCPのエコシステムを使った認証や公開も可能であったと思います。しかし今回は検証目的で限定利用ということもあり、あまりクラウド利用料を掛けたくなかったのと、私自身があまり知見が無くアプリケーション側の追加実装も必要であったことから、手元のアセット(自宅サーバ)を使いつつ無料のSaaSでなんとかしようということで採用しませんでした。これがサービス公開のために本番環境を作るのであれば、ほぼ確実にGCPを利用する選択肢を選ぶと思います。
[アプリ公開] ngrokやtailscaleの利用
ウェブアプリケーションを公開する上で、ngrokやtailscaleなどを利用することも検討しましたが、独自ドメインでURLを作りたい場合には無償の範囲内では対応していなかったので、これらは採用しませんでした。
もし独自ドメインでなくても良いという場合にはngrok有効な選択肢になりえますが、URLを固定出来ない点は注意です。またtailscaleなら3ユーザまでFreeプランの範囲内ですので、VPNでアクセスしてもらうことで認証を考えなくてもよくなります。
[認証] ウェブアプリケーション自体に認証機能をつける
今回はPythonのstreamlitを使ったアプリケーションを作成しましたが、一般にウェブアプリケーション側で何らかの認証を付けることは一般的です。streamlitもパスワード入力欄を作ることで擬似的にアクセス認証を実装することは可能ですが、そのためにコードに変更を加える必要があるため、今回は採用しませんでした。
[認証] ウェブアプリケーションを実行している環境でnginxを使ってBASIC認証を使う
他の方法としてnginxなどのウェブサーバを使うことで、リクエストに対してBASIC認証をかけることも可能です。URLにアクセスすると毎回ポップアップでid/passwordの入力が求められるようになります。簡単な認証方法としては使い勝手が良いものであはりますが、アカウント管理などが煩雑になるため、今回は採用しませんでした。
Discussion