はじめに
こんにちは!WireGuard大好きおじさんです。
この記事では(私が過去のLTで何度か語ったことがある)Cloudflare Tunnelやその基礎プログラムであるcloudflaredのちょっと意外かもしれない使い方と導入事例をいくつかご紹介します。
(本当は、あまり想定されていないニッチなネットワーク機器へのcloudflared導入事例をメインにする予定でしたが、気が付いたらCloudflare Tunnelの技術紹介がメインになっていました)
cloudflaredのリバースプロキシ機能などに着目して変な使い方を追求する内容となっておりますので、あまり 「Cloudflareが好きな人」「これからCloudflareを学びたい方」「Zero Trust環境を構築したい方」向けのものではございません。 内容も非常に冗長なものとなっております。あらかじめご了承ください。でもL3より上位のネットワークが薄く浅く好きな自分みたいな方には少しだけ刺さるお話になっていると思います。
また、私自身この機能をかなり長く使ってはいますが公式の情報をあまり深掘りしない悪癖があるので、技術的にも表現的にも間違っている箇所があればご指摘いただけますと幸いです。
1. Cloudflare Tunnelとは
上述の通り、この記事ではちょっとコアな部分に触れていきます。Cloudflare Tunnelの基本的な導入方法などをお知りになりたい方は、@sey323様「Cloudflare Zero Trustを利用して外部ネットワークからおうちサーバにSSHする」(明日10日!)@netou_kurage様「Cloudflare Tunnelで手軽にサーバーを公開する」(19日)などの記事がきっとわかりやすいかと思います。
その上で簡単にご説明させていただきますと、Cloudflare Tunnelとは、cloudflaredというプログラムを用いて、任意のネットワークサービスへの外部接続経路を簡単に提供してくれる仕組みです。Cloudflare Zero Trustというセキュリティサービスの1つとして提供されています。
何を言ってるかわからないですね。
例えば、手元のPCで8080番ポートにWebサーバーを建てたとしましょう。ApacheとかFlaskとかNginxとかNodeとか、お好きなものをご想像ください。
これはほとんどの場合、基本的にPC内だけ、もしくは同一LAN内だけに対しての公開となることでしょう。PC上からはhttp://localhost:8080
で繋ぎますし、このPCのIPアドレスが192.168.1.100/24
であれば、同じネットワークに参加している他PCからはhttp://192.168.1.100:8080
できっと繋がるでしょう。
ところがある日突然「このサイトを今すぐ遠くに住む友達に見せたい...!」という需要が発生するとします。すごく素敵なWebサイトが出来たのかもしれませんし、マイコンと連動してWebAPIを叩くだけで枕元のアラームがガン鳴りするような素晴らしいシステムが完成し、モーニングAPIコールをお願いしたくなったのかもしれません。
実現するための1つの方法としては、ご自宅のルータにポート開放&ポートフォワーディングの設定を入れてインターネット上からグローバルIPアドレスでPCまで到達できるように設定するというものがあります。普段「危険!外的要素全排除!」とセキュリティを頑張っているルータくんに「よく来たね。お探しのものはこちらだよ」と案内をしてもらえるように設定を変更するのです。
しかしこれをするためにはもちろんセキュリティを一部弱める必要がありますし、自宅のグローバルIPアドレスを友人に共有する必要があります。ひとたび不必要な設定が入ったり脆弱なアプリケーションが公開されてしまえば、たちまち大きなリスクが発生することになります。また、プロバイダの都合でグローバルIPアドレスを固定できない or (僕の愛してやまないWiMAXのように)固定するのに別料金がかかることもあります。
ここでCloudflare Tunnelの出番です!
cloudflaredというプログラムをPCにインストールしてからブラウザでちょちょっと設定を行ってあげるだけで
web.mydomain.com
⇔ http://localhost:8080
というコネクションを作成し、簡単にインターネット上から手元のWebサーバーにアクセスが通せるようになってしまうのです。(これをPublic Hostname設定といいます)
お友達にはweb.mydomain.com
を共有してアクセスしてもらうだけで、ちゃんと手元のWebサーバーに繋がるようになります。もちろんこの例のように独自ドメインで共有をするためにはCloudflareでドメインを契約する必要があるのですが、何故かCloudflareさんはドメインを手数料無し原価売りしているらしいので非常にお安いです。
しかも、ほとんどの場合でこれを動作させるためにルータの設定などは変更する必要がありません。インターネットに繋がってさえいれば、内向きのポートが解放されていなくとも、自宅だろうと職場だろうと場所すら問わずどこでも繋がります。NATなどの都合でスプラトゥーン2ではルームホストになれないようなネットワーク環境でも問題ありません。
2. cloudflaredとは
では、そんなcloudflared
とは一体どんなプログラムなのか、というお話です。
cloudflaredの仕事は大きく分けて
- トンネル機能
- リバースプロキシ機能
の2つに分かれると考えています。
まずトンネル機能ですが、これはcloudflaredをインストールした端末とインターネット(Cloudflare)を繋いでくれる役割です。cloudflaredはCloudflareのエッジサーバーに対してTLS接続を確立し「僕はここにいますよ」と知らせて、Cloudflareはそれを頼りにインターネット上からの通信をcloudflaredをインストールしてある端末まで誘導してくれます。
次にリバースプロキシ機能ですが、簡単に言うとこれは「Cloudflareに案内されてお手元の端末まで到達した通信が、次にそのPCから見てどこへ向かえば良いか」という行き先を示す機能です。「ようこそ。あなたが探し求めてるサービス(サーバー)はここに置いてありますよ」と案内をしてくれます。
同等の機能を持った別のサービスとしてはngrokが挙げられますね。Cloudflareで契約したドメインをすぐ使えて、通信先の設定をブラウザから簡単に設定できるngrokだと思って貰えれば差し支えないと思います。
また、WARPというCloudflareが提供するVPNアプリケーションをインストールして自身のアカウントにログインすることで、cloudflaredをインストールした端末からネットワーク単位で丸ごと共有を行うことも可能です。(これをPrivate Network設定といいます)
ちなみにトンネル機能については、本来接続元の端末にもcloudflaredをインストールし、1行だけコマンド実行が必要なのですが、Webレンダリングが可能なコンテンツ(ブラウザで見られるもの)と、SSH経由でのシェルアクセスに限ってはCloudflare側で勝手にトンネルを通してブラウザからアクセス可能な状態としてくれる機能があります。
これら機能はWireGuardというL3のVPNを構築するためのアプリケーションを元にして動作して...いたそうなのですが、現在はセキュリティに対する将来的な懸念などの都合でMASQUEというプロトコルによる実装に徐々に置き換わってきているそうです。これまでさんざ知った顔していろんな人にこのことをご説明してきましたが、自分は未だにMASQUEには触れてすらいないため、どんなプロトコルなのかは全然知りません。詳しい人がいたらどなたか教えてください。
とりあえずcloudflaredをインストールすると、設定次第でその環境に対して好き勝手インターネット上から繋げるようにできるんだな...と思っておいてください。
3. 使い方
こちらは他の記事にお任せいたします。
公式のGet startedドキュメントはこちら。
4. 導入事例
私自身cloudflaredをインストールして使ってみて、便利だったものや全然そんなことなかったものをいくつかご紹介します。
4.1 自宅PCに導入
まずはこれが一番お手軽に楽しめるかと思います。
Webサーバー
最初はPythonで8080番ポートにWebサーバーを立ち上げて、web.mydomain.com
⇔http://localhost:8080
という設定を入れて別回線から快適にアクセスできることを確認しました。
もちろんローカル開発しているWebページをnpm start
で立ち上げた後に発行されたローカルアドレスをドメインに紐づけ、知り合いに共有したりといった設定も簡単に行えます。Pythonで簡易的なWebファイラを自作してそれを共有したりもしていました。
しかし一生懸命自前で作ったりせずとも、実は探してみるとcloudflaredで共有できるWebコンテンツというのは存外多いものです。
ブラウザ動作するローカルアプリケーションのWebUI
例えばStable DiffusionやNVIDIA ChatRTXなどの生成AIをローカルWebUIから使える類のものを同様の方法で共有することで、出先からも画像生成やローカルChatAIを使えるようにしたりしてみました。もちろんWebの接続経路を外に共有するだけなので、外からアクセスしても使うGPUは自宅PCのものとなります。
(それでは誰でも自宅のGPUやリソースに誰でもアクセスし放題になって危ないのでは...?)と思うかもしれませんが、先述の通りCloudflare TunnelはCloudflare Zero Trustというセキュリティ機能の一部として提供されているものでして、実は接続ユーザーを簡単に制限することが可能です。一例を挙げると「web.mydomain.com
に繋ぐためにはmyaddress@gmail.com
からPIN認証を行わないと接続を許可しない」といった内容の設定を行ってあげると、web.mydomain.com
にアクセスした時点ですぐWebコンテンツに繋がるのではなく、一旦Cloudflareにより用意されたPIN認証の画面が表示され、そのチャレンジに成功して認証が通ると初めてWebコンテンツにリダイレクトされる...といった構築ができるのです。(ちなみにこれは別にCloudflare Tunnelのみの機能ではなく、Cloudflare PagesやWorkersといった別システムから公開されるあらゆるURLに対して設定が可能です)
mDNS(Bonjour)を使った名前解決にも対応しているので、例えば共有したいWebコンテンツのURLがmdns.local
のようなアドレスだった場合もそのまま設定が可能です。(ただしmDNSの仕様の都合で、当たり前ですがcloudflaredを導入した端末から確実に解決できるアドレスである必要がありますし、そもそもmDNSは遅いので結局解決済みのアドレスを設定してあげた方が早く動作します)
一時期はcloudflaredで共有できるものを探したいがために、ローカルWebサーバーとして機能するアプリケーションを探し回っていました。
ただし1つ注意点があり、nginxをゴリゴリ弄ったことがある方はよくご存じかと思いますが、リバースプロキシを通す/通さないで挙動が大きく変わるWebアプリケーションというのは多く存在します。(ログインできなくなる、そもそもコンテンツのレンダリングができなくなるなど)リバースプロキシを自前で構築しているのならアプリケーションごとにヘッダー書き換えるなりいろいろ対処してあげれば良いのですが、いかんせんcloudflaredは完全にプログラム内に組み込まれているため、その辺の制御が一切利きません。もしそこが原因となる不具合が発生して各アプリケーション側での対応が困難である場合は、潔く使うことを諦めましょう。もしくはPrivateNetwork設定を用いた共有であれば上手くいくかもしれません。
Remote Desktop
出先からリモートデスクトップを繋ぐなんて使い方も可能です。これは先述の通りWebアクセスまたはSSHシェル以外の接続(プロトコル)になりますので、接続元のPCにもcloudflaredのインストールと、事前にトンネル開通のためコマンド実行の必要があります。
自宅PCがWindowsの場合、
rdp://localhost
⇔rdp.mydomain.com
というコネクションをセットアップしておき、接続元のPCから
cloudflared access rdp --hostname rdp.mydomain.com --url localhost:8000
としてあげれば準備完了です。
Remote Desktop(現:Windows App)の接続ホストのところにlocalhost:8000と設定してあげればトンネルを介したリモートデスクトップ接続が可能となります。
ちなみにこちらでステップバイステップで解説されています。
このcloudflared accessコマンドの叩き方を覚えると一気に活用の幅が広がるので、WebとSSHだけしか触ったことがない方は是非試してみてください。
4.2 VPSに導入
これが実は一番アツいです。
(公式にもよく紹介されている構成です)
VPS上でWebサービスを立ち上げて、それを公開するためにcloudflaredを使います。
...というと何の目新しさも感じられないかもしれませんが、通常の公開方法と大きく異なる点が、インバウンドのポートを全閉じできるという点です。
Cloudflare TunnelはcloudflaredがCloudflareのエッジサーバーに向けてトンネルを確立してトンネル経由で通信を行うため、内向きのアクセスは完全に閉じた状態でWebサーバーの公開が可能となります。
さらにそこへ先ほどのCloudflare Zero Trustの設定を入れてあげると、あっという間に社内ユーザーだけが接続可能な公開Webサービスが構築完了です。
弊社はこの方法で社内向けにGitLabなどのセルフホスト系サービスを公開していくつか運用しています。
-
gitlab.mydomain.com
⇔localhost:80
-
gitlab-ssh.mydomain.com
⇔localhost:22
のように設定を行うことで、SSH接続によるgit操作も可能です。
また、もちろんVPSにインストールされたOSへのSSH接続(&シェル操作)もcloudflaredで共有が可能です。
そのポートすら開放の必要がないというのは、実際かなり気持ちの良い体験ですね。
4.3 ルータに導入
ルータなどの組み込みシステム用ファームウェアとして開発されているLinuxディストリビューションに、OpenWrtというものがあります。端的に言いますと、それをインストールするとルータがLinuxに化けてくれます。さらに、近頃のルータはSoCや搭載RAMのスペックもかなり良いものが多いです。
LinuxがモダンなSoCで動作しているとなれば、つまりcloudflaredが動きます。
OpenWrt環境への導入
こちらは、OpenWrt環境にcloudflaredをインストールしてinit.dサービスとして動作させるための手順です。導入後のテスト方法や活用方法まで書かれているので是非ご覧ください。一体何度この記事を読みながら導入してきたことか。
基本的にはお使いのルータがどのアーキテクチャで動いているかを確認して、それに対応したバイナリをgithubのreleasesから拾ってきて適切なパスに配置し、バイナリを手動実行するかinit.dサービスに記述してあげるという流れになります。
なお、パッケージマネージャであるところのopkgからcloudflaredをインストールすることもできますが、私の試した限りでは安定性に欠ける場合が多かったです。(init.dサービスとして安定して起動してこなかったりなど)
cloudflaredで到達可能な範囲の話
ここから地味に重要な話です。
CloudflareTunnelのPublicHost設定を入れる際、多くの場合ServiceのURL欄にはlocalhost:22
とかlocalhost:80
と入力するかと思います。言うまでもないですが、これはcloudflaredをインストールした端末でWebサーバーやSSHサーバーも動作しており、cloudflaredから見てlocalhost
で接続先が解決できるためです。
ここをlocalhost以外で設定したことがある方、実は少ないのではないでしょうか?
例えば、ネットワーク内の相互通信が許可された同一ネットワーク(192.168.1.0/24)内にクライアントA(192.168.1.100)とクライアントB(192.168.1.200)が存在していて、クライアントAで8080番ポートにWebサーバーが、クライアントBでcloudflaredが動作しているとします。
このとき、
web.mydomain.com
⇔http://192.168.1.100:8080
とPublicHost設定を入れてあげると、ちゃんとcloudflaredがインストールされたクライアントBからクライアントAにリバースプロキシされて、web.mydomain.com
からクライアントAのWebサーバーへ到達できるようになるのです。
わざわざクライアントAにもcloudflaredを別途インストールする必要はありません!
そう考えたときに、一般的にネットワークを構成する中で最も広い範囲にリーチしやすいネットワーク機器ってなんだと思いますか?そうですルータですね。しかも毎晩寝るときにPCの電源落として寝る人はいてもルータの電源落として寝る人は少ないでしょう。Availabilityも十分です。
ということで自宅にルータにOpenWrtを導入し、そこにcloudflaredを入れてあげると基本的にあとはやりたい放題になります。当たり前ですけどルータのWebコンフィグやSSHにも外から繋げるようになりますからね。ネットワーク構成すら弄りたい放題になります。
Private Network設定もルータに入れてこそ真価を発揮しますよね。やはりネットワーク丸ごと共有することの気持ち良さですよ。その分ちゃんと管理しないとあまりにも危険ですけどもね。
4.4 その他
上述のルータでcloudflaredを導入する方法を応用してあげれば、Linuxと名の付くモダンなSoCで動く環境であればcloudflaredは大体動かせてしまったりします。
例えば、Linuxを搭載したオシロスコープ(Analog Discovery Pro)に導入してみたこともありますね。ちょっと当時の検証記録が見当たらなかったのと再検証の時間が確保できなかったので今回は大きく取り上げませんでしたが、ちゃんと便利に活用できてました。あと私はやったことが無いのですが、Android端末にも導入できるようです。変態的過ぎる。
他にもこんな変な環境で動かしてみたよ、というお話があれば是非私に教えてください。
興奮してきたな。
5. おわりに
ここまで、Cloudflare Tunnelとその基礎プログラムであるcloudflaredについて、少し変わった使い方や導入事例を交えながら紹介してきました。特に、自宅PCやVPS、さらにはルータといった多岐にわたる環境での利用可能性は、Cloudflare Tunnelの柔軟性と実用性を示す好例だったのではないかと思います。
今回は深くご紹介できませんでしたが、Cloudflare Zero Trustとの連携を活用することで、ただ便利というだけでなく安全性も確保できる点がCloudflare Tunnelの大きな魅力の1つです。ポート開放やVPNといった従来の手段に代わり、Cloudflare Tunnelが新たな選択肢として広がりを見せている理由を、少しでも実感していただけたなら幸いです。
最後に、このようなニッチなネットワークの話題にお付き合いいただき、本当にありがとうございました。皆さんの環境にcloudflaredを導入する際のヒントやインスピレーションになれば幸いです。そして、この記事をきっかけに少しでも「Cloudflare Tunnelって便利だな」「Cloudflareのサービスって楽しそうだな」と思っていただけたら、私としてはこれ以上ない喜びです。
それでは、素晴らしいトンネルライフを!