Cloudflare Zero Trustを利用して快適なリモートワーク環境を構築する
自己紹介
こんにちは。株式会社DELTA代表の丹です。
この記事は Cloudfalre Advent Calendar 2023 の7日目の記事となります。
普段はAWSコスト削減をはじめとして、ベンチャースタートアップのCTOを中心に技術支援を行っています。
今回は私がCloudflare Zero Trustを活用して構築したリモートワーク環境について紹介しつつ、Cloudflare Zero Trustの基本的な考え方について紹介します。
Cloudflare Zero Trustとは
Cloudflare Zero Trustとは、一言でいうとVPNよりも高速かつ安全(とされる)ネットワークアクセスのサービスです。(多くのサービスが含まれるため、本当に一言でいうと、でしかないですが)
いわゆるZero Trustとは、そもそもVPNに入ってたからといってそこからのトラフィックって全部安全なん?という考え方です。
VPNはペリメター(境界)を持ち、ペリメター内に入っているトラフィックについては信頼するという考え方(Zero Trustに対して、いうなればFull Trust)ですが、
Zero Trustではペリメターなるものは特に持たず、単にすべてのトラフィックを検証します。
Zero Trust vs Perimeter: ラテラルムーブメント
よくZero Trustという考え方の特徴を表すのに援用される概念としてラテラルムーブメント、水平方向の移動というものがあります。
これは、VPNのペリメター内の入る動きを垂直とみなした際に、ペリメター内に入ってさえしまえば、そのネットワーク内のすべてのリソースや、そのネットワークを(例えば、NATに割り振られたエグレスIP)信頼している他のインスタンスやサービスまでフリーパスとなってしまうという危険性をさします。
すべてのトラフィックを検証するというゼロトラストの考え方からすれば、あるペリメターに入ったからといって、それがすなわち別のサービスやインスタンスにもアクセスしてよいということを示さない ということになります。
登場人物紹介
従来のVPNの存在意義はいろいろとありますが、リモートワークやハイブリッドワークといった「物理的に離れた場所からセキュアな領域に対してアクセスする」という要求を満たすという側面は大きいでしょう。
Cloudflare Zero Trustはそれをどのように快適に、かつよりセキュアに解決してくれるのでしょうか?
実際にCloudflare Zero Trustで、自宅のNWに職場からアクセスする というユースケースを想定して構築してみますが、その前にCloudflare Zero Trustに登場する主要な概念について紹介します。
Cloudflared
Cloudflaredとは、Cloudflare Zero Trustのコアなコンポーネントで、主にトンネルを実際にホストするプロセスを動かす、ローカルなサービスです。
つまり、適当な端末にインストールして動かすやつということです。基本的には、Cloudflare Zero Trustにおける特定のNWや端末へのアクセスはすべて、そのNW内に存在するCloudflaredプロセスがあけたトンネルを通して実現されます。
このサービスが存在することにより、各NWや端末へのアクセス時には実際にはそのNWや端末「への」アクセスを行うわけではなく、Cloudflareを介してその端末「からの」接続に対してトラフィックを送るということが実現されているようです。
これにより、アクセス対象のNWや端末のパブリックなIPが無い、またはアクセス元が知らなくてもセキュアにアクセスが可能になるうえ、そのNW内へのトラフィックをCloudflareが常に検証しコントロールできるというわけです。
Cloudflare WARP
Cloudflare WARPはCloudflare Zero Trustのコアなコンポーネントで、主にクライアントをCloudflare Zero Trustのネットワークに接続するための存在です。
これまた、お手元の端末にインストールして動かす必要があり、クライアント側がCloudflare Zero Trustにおけるトラフィックを送る前に、そのトラフィックに対して認証を行ったり、アウトバウンドの通信を検証・ルーティングする目的で利用します。
他にも、Cloudflare Zero Trustのネットワークに接続することで、Cloudflareの持つ地理的な最適化の恩恵を受けられるので、単純に速度が速くなるということもあるようです。
WARPがあることにより、Cloudflaredと特に関係のない、アウトバウンドなインターネットへの通信についても監視・制御することが可能になります。
これもかなりZero Trustの思想に根差していると思うのですが、かつて職場の中で働くのが当たり前で、VPNを使うとしてもせいぜい支社からといった時代と比べ、今ではペリメター自体の数や状態が多様化し、リモートワークの時代においては各自が各自の端末で好き勝手にインターネットへも出ていくのが当たり前となっていて、ペリメターの周辺だけを見ていればいいというよりは、常にインターネットとの通信にも気を配る必要があるという思想を持つ必要があると思います。
また、WARPは後述するDevice Posture(デバイスの状態)の収集も行うので、各自がWARPをインストールしておけば自然と端末もセキュアになる、というような体験が実現できるということも魅力の一つです。
基本的な考え方
つまり、VPNに近い考え方を適用するとすれば、Cloudflaredがトンネルを開けたNWや端末に対して、Cloudflare WARPで認証済みのトラフィックが流せるようになる、という世界観で理解していただいてまずはOKかと思います。
異なるパターンとして、Cloudflaredがトンネルを開けた特定の場所(典型的にはlocalhost:8080など。これをSelf-HostedなApplicationといいます)に対して、CloudflareのDNS経由でアクセスできるようにするという方法もあります。
こちらのパターンでは、CloudflareのDNSというパブリックな存在を経由するため、WARPは必ずしも必須の要件にはなりません(Cloudflare Accessの機能で認証します)。
ただし、こちらのパターンであっても、先述の通りWARPクライアントを必須にしておくことで、WARPを利用したインターネットへのアウトバウンド通信の監視・制御などの恩恵が受けられるため、今回はWARPは必須要件とする設定まで試みようと思います。
実際にやってみる
リモートワーク環境の構築のデモとして、私の自宅に置いてあるサーバに対して、スマートフォンから様々な方法で接続したいとします。
どのように実現できるでしょうか?
前提条件
Cloudflare Zero TrustのOrganization作成
CloudflareのダッシュボードからOrganizationが作成できます。
作成後、Settings > WARP Client > Device enrollment permissionsから好きなポリシーを作成しておきましょう。
私は自社のメールアドレスのドメインベースでの認証を行うように設定しておきました。
Cloudflared Tunnelの作成
まず、自宅のNWにある適当な端末に、Cloudflaredをインストールします。
CloudflaredはCloudflare公式からインストールできます。
インストール後、サービス化しておきましょう。
cloudflared tunnel login
してから、 cloudflared tunnel create sample
すると、Cloudflared CLIからCloudflaredのトンネルを作成できます。
このとき、返ってきたUUIDを控えておきましょう。
その後Cloudflare側のZero Trustのコンソールを見ると、今しがた作成したばかりのトンネルが Access > Tunnels に出ているのがわかると思います。
設定ファイルを作成する
tunnel: <Tunnel-UUID>
credentials-file: /root/.cloudflared/<Tunnel-UUID>.json
warp-routing:
enabled: true
というようなconfig.ymlを /etc/cloudflared
などに配置してあげましょう(詳細は sudo cloudflared tunnel run
したときのログを参照)
テスト用のwebサーバを立てておく
これは本当に何でもいいのですが、 docker run --rm -p 80:80 nginx:latest
とかで適当にwebサーバを立てておきます。
方法その1: 自宅のNWに対して、WARP経由で接続する
Cloudflared Tunnelに好きなCIDR範囲でのルーティングを追加
続いて、トンネルに対して「このCIDR範囲のトラフィックは、このトンネルがルーティングする」というのを設定します。
つまり、最終的にはこのトンネルを通ったトラフィックに対して、どのIP範囲へのアクセスを許可していくのかを決めるというイメージです。
例えば、自分のPCだけをアクセス対象にしたい場合は、
cloudflared tunnel route ip 自分のローカルIPアドレス/32 sample
して自分のローカルIPアドレスをcloudflaredのトンネルの対象にしておきます。
VPNと違うところが既にわかるかと思いますが、この時点で「ネットワークにはルーティングするが、その中でのラテラルムーブメントを制限する」ということができるというわけです。
当然ですが、自宅のNWのCIDR範囲をすべて cloudflared tunnel route ip
の引数に加えれば最大限にラテラルムーブメントが可能な状態にできます。
これでサーバー側の準備は完了です。
クライアント側の設定
とりいそぎテザリングで検証したいので、スマホにWARPまたは1.1.1.1という名前のアプリを入れます。
AccountからOrganizationを選択し、先ほど作成したOrganizationを選択し、先ほど設定した方法でログインします。
するとVPNが有効というようにスマートフォンからは認識されると思います。
スプリットトンネルからの除外
デフォルトだと、典型的なプライベートIPのCIDRはWARPによるルーティング対象から弾かれるようになっています。
コンソールから、Settings > WARP Client > Device Settings > Configure から、「Split Tunnels」のExclude対象にあるプライベートIPのCIDRを変更するか削除しておきましょう。
この状態で、スマートフォンから先ほど指定した「自宅PCのローカルIP」にブラウザからアクセスし、nginxのトップページが表示されれば成功です!
方法その2: 自宅のNW内のアプリケーションを、Cloudflared経由でDNSに登録する
Proxyの有効化とWARP自体のDevice Postureのチェック対象化
Settings > Network > ProxyをONにしておきます。
また、Settings > WARP Client > WARP Client ChecksからWARPのDevice Postureチェック対象化を行っておきます。
パブリックDNSとCloudflaredの紐づけ
コンソール側で、Access > Applicationsから、Self-Hostedを選択、好きなドメインを指定します。(Cloudflare側のDNSで管理されているドメインである必要があります)
Policiesでは、左辺に「WARP」が指定できるようになっているので指定しましょう。
Cloudflared側がDNSを待ち受け
sudo cloudflared tunnel route dns <Tunnel-UUID> ドメイン名
でトンネルへのDNS追加を行います。
その後、先ほど作成したconfig.yamlのingress欄を拡充します。
tunnel: <Tunnel-UUID>
credentials-file: /root/.cloudflared/<Tunnel-UUID>.json
warp-routing:
- enabled: true
+ enabled: false
+ ingress:
+ - hostname: demo.tan-t.cloud # 先ほど作ったDNSレコード
+ service: http://localhost
+ - service: http_status:404
このエントリで、対象のホスト名は自分が待ち受けるのだ!という認識をCloudflaredがするようになります。
一応 sudo service cloudflared restart
しておきましょう。
これだけ!
WARPをONにした状態でドメインにアクセスすると、認証が行われたのちアクセスできますが、WARPをOFFにした状態でアクセスすると、接続はできるがCloudflare側のForbiddenが発生するのがわかると思います。
これはDevice PostureのチェックとしてWARPを必須にしたポリシーを、Applicationに指定したからです。
ふりかえり
どちらの方式がよいのか?
今回は、ローカルNWに置いてあるインスタンスやサービスへのアクセスをセキュアに行う方法として、
- WARP + IPルートを利用した、ローカルIPベースでアクセスする方法
- DNSルートを利用した、パブリックなDNSベースでアクセスする方法
の二つを紹介しました。
どちらもCloudflaredのトンネルによる公開という意味では同じではありますが、アクセス方式として
-
IPレンジ以外のコントロールが効きづらいが、認証済みのWARPでしかそもそもNW的に到達できないという安心感があるWARP+IP形式
- Cloudflared Tunnel側で許可したIPに対して、例えばポートなどでの制御をする設定は見つかりませんでした
- ここに関してはマサカリ歓迎
-
パブリックなDNSに入口自体は公開してしまうものではあるが、Device Posture含めてきめ細やかなルールが指定でき、さらにそれぞれのインスタンスやサービスを独立しているかのように見せることでラテラルムーブメントもしづらいDNS方式
- CloudflareのCDN同様、DNSからオリジンを辿るのは不可能なので、DNS経由で公開されていること自体のリスクは本来ない
- そういう意味だと「そもそもNW的に到達できない」という点はWARP+IPと同じといえば同じ
この二つは一長一短のように感じます。
ただ、意外と比較してみるとDNSパターンをきちんと運用する方がセキュアかなと感じました。
VPNの延長で考えるとWARP + Cloudflaredだが、よりZero TrustなのはDNSのパターンなのではないでしょうか。
私のリモートワーク環境
私は基本的には出社していますが、自宅のPCをサーバにして普段開発しているため、自分用のリソースのみ自宅PCに集約したいと思っています。
エディタはNeoVimを使っていて、NeoVimはサーバ側で起動したウィンドウをターミナルで受け取れればそれでよいため、SSHが一本通っていれば極論問題ないという状態です。
そこで、DNSパターンの延長でSSHできるドメインを作ることができるのですが、それを使って職場のPCから自宅のサーバーに向かってSSHで繋いで普段開発をしています。
Cloudflare Zero Trustを使ってSSHを繋ぐという場合、クライアント側にもCloudflaredをインストールする必要こそあるものの、Short Lived Certificatesという、Cloudflare Accessの認証が成功したらデフォルトでは24hだけ有効な鍵を発行し、それを使ってSSHできるという機能が利用できてさらに快適です。
Short Lived Certificatesという機能を利用すれば、クライアント側に鍵を置く必要がなく、極論PCをなくしても全く問題がない(Cloudflare側からセッションを切れば終わり)という超快適な環境を構築できています。
今後はShort Lived Certificatesの認証にDevice Postureを追加するなど、クライアント側のセキュリティも強化していきたいですね。
We're Hiring!
最後までお読みいただきありがとうございます。
株式会社DELTAでは新しい技術をどんどん試しながらクライアントの課題解決を行う仲間を募集中です!
まずはカジュアル面談からできればと思います、ぜひPittaから
またはGoogle Formから お申込みください!
Discussion