概要
私は個人でWebサイトやWebサービスを色々公開しております。
この度、個人開発でWebサービスを運用するときにCloudflareを利用すると様々なリスクを無料でヘッジできるので事例を紹介します。
しかも無料です。
個人開発サービスの問題
費用をかけられない
お金をかければWAFや計算処理の高いサーバやコンテナなどの環境を使えますが、テストで開発したサービスや収益化するかどうかわからないサービスをたくさん運用することになるので固定費は可能な限り抑える必要があります。
いかに安く安定的にサービスを提供できるかは腕の見せどころでもあります。
複数サービスがダウンする可能性
固定費を抑えるために1ホストにいろいろなサービスを動かすことが多いと思います。
よって、1つのサービスに対してDoS攻撃や突発的にWeb上でバズって大量のトラフィックが来ると捌ききれなくなってあるホストで運用しているサービスがすべてダウンしてしまうリスクがあります。
自宅サーバの場合はポートを解放しないといけない
費用を抑えるために自宅サーバを運用して居る場合もあると思いますが、自宅サーバを公開するためにはポートを開放する必要があります。また、ホストレベルでクラックされた場合には自宅LANに第三者が入れる状態になってしまうリスクがあります。
Cloudflareとは
主なサービスは、コンテンツ配信ネットワーク(CDN)、DDoS攻撃防御、Webアプリケーションファイアウォール(WAF)などのセキュリティ機能、およびインターネット最適化を提供します。Cloudflareの主な機能は以下になります。
- コンテンツ配信ネットワーク (CDN)
- DDoS保護
- Webアプリケーションファイアウォール (WAF)
- SSL/TLS暗号化
- DNSサービス
- Zero Trustセキュリティ
- エッジコンピューティング
これ以外にもたくさんのWebサービスを運用する上で便利な機能があります。
概念的には以下のようなイメージです。主にレイヤー7のアプリケーション層においてのリスクをCloudflareで全部受け止めてくれるような使い方ができます。

Cloudflareのダッシュボードをチラ見せしますとこんな感じになります。左のメニューを見てもらうとわかると思うのですが、Webサービスを運用する上で便利な機能が用意されています。

変更前インフラ
おそらく、個人開発しているサービスや小規模サービスは以下のようなインフラ構成になっていると思います。
AWSでいえば、アプリケーションサーバはEC2やAWS Lightsail、自宅サーバで動かして、CDNに乗せられるようなコンテンツはCloud Frontを使うと言ったような感じです。

上記の構成であれば、無料枠で収まるかなと思います。
上記の構成を少し先に進めるために、WAFを入れたり、TLS証明書の自動更新を入れたりすると毎月数万円の金額がかかってきます。
Cloudflareでの設定
フェーズ1
Cloudflareを利用するためにはドメインが切られている必要があり、zoneサーバをCloudflareでホスティングする必要があります。
CloudflareのDNSだけを使うだけでも無料で運用できるのでそれだけでも価値はあったりしますが、まずはCloudflareの恩恵を受けるためには以下のような構成を作るのが1歩目です。

「Cloudflare as CDN」と書かれている部分が普通の概念とは異なるのですが、CDNとざっくり書いてしまいましがこの部分がCloudflareの超重要な部分です。そして説明しづらいところなのであんまりCloudflareが認知されていない理由にもなっているのかなと思います。
分かりやすく説明するために、1つのメインの機能としては、TLS terminationとReverse Proxyが動作しています。それにより、外部からの攻撃、リクエスト内容の検証、originへのトラフィックの制御を行えるようになっています。
次に、設定の手順の概略を書いておきます。
DNS zoneの登録
なにはともあれ、Cloudflareを使うための第1ステップはドメインのzoneを登録するところからです。
例えば、CloudflareのCDN(無料)だけを使いたかったとしてもDNS zoneをCloudflare上でホスティングする必要があります。Cloudflareの恩恵は受けられませんが、CloudflareのDNS zoneホスティングだけを使うと言ったことも無料で可能です。
(スクショは英語ですが、すべて日本語の表示もできます)

zoneを登録したら、各レコードを追加していきます。
レコードを追加する際に普通とは違うのが、”Proxy status” というスイッチがあることです。このスイッチをonにするとDNS zoneサーバのレスポンスは登録したIPアドレスなどではなく、CloudflareのReverse proxyサーバのアドレスに置き換わります。

では、”Proxy status”をonにしたら左の項目に登録したIPアドレスはどう扱われるのかといいますと、Reverse Proxyのoriginのホストとして扱われます。

独特な概念ではあって最初からつまずきやすいですが、一度理解してしまえば大丈夫ですし、段階的に切り替えられます。まずはReverse proxyをoffにした状態でDNS zoneを移行するのが良いです。
このblog.teraren.comのサイト自体もCloudflareを使っているのでDNSを引くとReverse proxyのアドレスが返ってきます。

Reverse proxyで受けられるようにoriginを設定
既存のはorigin側のwebサーバの設定では、グローバルからリクエストを受ける設定になっているのでreverse proxyからアクセスを受けられるように設定します。
今までは、ユーザに見せるホスト名でのTLS terminationなどを行ったいた設定をreverse proxyからのアクセスを前提とした設定を行います。
設定例: Configure Nginx Reverse Proxy behind Cloudflare
キャッシュルールの設定
Reverse Proxy自体がCDN機能を持っているので、どのコンテンツをキャッシュするかどうかを設定します。
WebからわかりやすいUIで設定できるので自分のホスティングするサービスに応じてルールを書いていきます。
無料だと10個までしかルールセットを作れません。私はキャッシュの期間ごとにルールセットを作っています。
1ヶ月キャッシュ、7日キャッシュ、1日キャッシュ、キャッシュ無しという分類です。

(2つ目と3つ目は同義です。もともとは別の期間を設定していた名残です。)
私の環境における「キャッシュ無し」のスクショを書いておきます。
WordPressの管理画面、ヘルスチェック用エンドポイント、動的なスクリプト、RSSフィードなどを記載してあります。

逆に1ヶ月の長期間を設定している設定はこちらになります。主に画像などの静的アセットになります。昨今はCDNを考慮したアセットの構築が行われているので内容が変わればURLも変わるという前提のためです。

CDN周りだけでも以下のような設定が簡単に行えます。
- Query Stringごとにキャッシュするかどうか
- ブラウザキャッシュのヘッダを付加するか
- Originが落ちたときにキャッシュをサーブするか
- CDNの一時的に一括無効化

CloudflareのCDNのすごいところはinvalidationが数秒で終わることです。Amazonだと数分とかかかったりしちゃいますが。
統計情報
Reverse ProxyとCDNを使いだすと以下のような統計情報が表示されてきます。眺めているだけでも楽しいです。

右にあるメニューに注目してほしいのですが、もしサービスが攻撃を受けていたら一時的に「Javascriptによる人間かどうかのチャレンジを挟む」というスイッチがあるのでONにすればoriginのサービスを過負荷から守れます。
トラフィックの統計も細かく表示されます。

Webサイトへの攻撃に関する統計情報

プロトコルやどれだけ待機を節約できたかの情報も表示されます。
30日で見てみると、300GBのトラフィックを節約できたみたいです。(無駄なトラフィックを節約することでCO2削減にも貢献!)

WordPressの設定
WordPress用にCloudflareのpluginが用意されています。
インストールしなくても使えることは使えるのですが、記事を更新すると自動でCDNの関連ページをpurgeしてくれます。あと、CDNでWordpressを運用するにあたってWordpressの挙動を勝手に裏で変更しているようです。

まとめ
IPv6対応、HTTP3/QUICK対応、DDoS対策、TLS証明書更新自動化、HSTS設定、CDN利用、DNSSECが行えてます。今までは自分で頑張って設定していたことがもうすでに用意されている感じです。
Cloudfalreは昨今の面倒なWebサイト運用における設定をWebサービスの1レイヤー上で面倒を見てくれるようなサービスです。
しかも無料。。。申し訳なくなってきます。
フェーズ2
フェーズ1からより安全にする方法です。
これにより、E2EEが実現でき、origin側のポート開放が不要になってよりセキュアにサービス運用を行えます。

tunnelのセットアップ
origin側にCloudflareのdaemonを動かして、tunnelを設定できます。cloudflareとoriginの間のトラフィックをこのtunnelを通すことによってoriginサーバ側でポート開放をする必要が無くなります。
tunnelを使うためにはCloudflare上のZero Trustの管理画面で設定します。
1ホストに対して1本のトンネルを作ってある設定例です。

daemonのインストールも非常に楽で管理画面上に表示されている例にあるコマンドを叩くだけです。

以下のようにpublicのホスト名と、originのサービス名を登録していきます。ここで登録するとCloudflareのDNSの設定にレコードが追加されていきます。既存のレコードと重複する場合はエラーが出ます。

tunnel経由でoriginへアクセス
1つ前のトンネルの設定をする際に、Cloudflareとoriginの通信を安全にしておくことをおすすめします。ブラウザとCloudflare間の設定はグローバルなのでLet’s encryptといった枠組みでTLS証明書の発行と運用簡単に設定できますが、originへのアクセスはprivateネットワークなのでそう簡単にはできません。
そこで、Cloudflareが発行する証明書をoriginサーバにインストールすることでCloudflareから発行された証明書がインストールされたoriginサーバということを担保する証明書を利用します。

その設定が完了すれば、上記のようにCloudflareを挟んでも安全にoriginの信頼性を保証できることになります。
Cloudflare上ではこのことをE2EEと呼んでますが、TLS terminationをCloudflare上で行っているのでE2Eでの秘匿性と、完全制は保証できないですね。紛らわしいです。
また、ここでは触れませんがsshなどのサービスもzero trustのサービスによってtunnel経由でアクセスできるように設定できるのでsshのポートすら空けないですみます。
BICはOFFにしたほうが良さそう
Security > Settingメニューに有るBrowser Integrity Checkはオフにしたほうが良さそうです。プログラムからアクセスされるAPIサービスを運用していると、このルールによってblockされているリクエストが存在します。

24時間以内に10件くらいがブロックされてしまっていました。

Cloudflareの有料機能
これまでの設定はすべて無料で行える範囲です。トラフィックがどんなに増えても無料です。
課金すれば、もっと良いサービスを利用できるので将来使いそうなサービスをいくつか紹介しておきます。
- Waiting page
急にサイトに大量のトラフィックが来たときに、Cloudflareでの待機ルームを表示してoriginが空くまでユーザを待たせる機能。チケット予約サイトとかはこれを使えば一発解決します。 - Image compression
pngやjpgなどの画像を次世代圧縮形式であるwebpに変換してブラウザにサーブしてくれる機能です。サーバサイドで色々設定しなくても済みます。 - Advanced WAF
怪しいアクセスをHTTPリクエストの内容を見て判断してくれます。
考察
Cloudflareを導入してみて大きく変わったことを書いておきます。
レスポンスタイムが超速い
CDNにキャッシュされると表示が一瞬で終わります。
$ ab -c 5 -n 20 https://blog.teraren.com | grep 'Time per request' Time per request: 30.551 [ms] (mean)
今見ているこのページをリロードしてみると、ブラウザキャッシュが読み込んだかのような速さで表示されると思います。
WordPressで運用しているサイトはそのままで運用しているとキャパが少ないので普通派WP Super Cacheを入れて運用すると思いますが、cache関連のプラグインもこの際にすべて削除しました。
Webサーバ側の設定が激減
WordPressのサイトでは1サイトあたり約100行削減できました。
HTTPのリダイレクト、HSTS、text compressionの設定などなどを削減できてメンテナンス性が上がります。
# git diff --stat a9d832ed7f1493ea0ce8e75664e7a1b70f95760e matsu.teraren.com.conf nginx/conf.d/matsu.teraren.com.conf | 178 ++++++++++++++++++++++++++++++++++++++++------------------------------------------------------------------------------------------------------------------------------------------ 1 file changed, 40 insertions(+), 138 deletions(-)
TLS証明書更新から開放
以前はcertbotで自動で更新を書けていても、知らない間に動かなくなっていたりとか設定ファイルが変わっていたりして結局は手での運用が発生してしまっていました。
Let’s encryptからの更新のお知らせのメールも一切期にしなくて良くなるので運用の手間からかなり開放されました。
TLS証明書に関連しては、HTTPからHTTPSのリダイレクト設定がスイッチ1つで行えたり、HSTSのヘッダ送信がUI上から行えるので非常に楽です。

HSTSの設定項目。

自宅サーバ用の固定IPまたはDynamic DNSが不要
tunnelをCloudflareに張るだけなのでローカルで動いているサービスをインターネット上に公開できるので自宅の回線に固定IPアドレスやDynamic DNSが不要になりました。
自宅ネットワークにDMZを作ったりVLANを切っている場合は、設定を無くせる場合もあります。(セキュリティ要件に応じてですが)
ポート開放が無くなった
外部から自宅のネットワークのポート開放を一切無くせました。Web系、SSHなどのリモートアクセス、場合によってはVPN関係のサービスを無くせます。
$ nmap <my home address> Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-22 11:40 JST Note: Host seems down. If it is really up, but blocking our ping probes, try -Pn Nmap done: 1 IP address (0 hosts up) scanned in 3.04 seconds
自宅のIPアドレスを晒さなくても良くなったので安心感があります。
Webページのパフォーマンススコアが向上
Webサイトのベストプラクティスを自動的に、または簡単に導入できるためGT metrixのスコアが上がります。

まとめ
最初はCloudflareのCDNが無料なので調査していたら、CloudflareはCDN以外の機能もかなり充実していてしかも無料で使えるサービスが沢山あるので今回は無料で使えるサービスをフルに活用して安全で安定的なサービス提供をできるように設定をしました。
最初の設定が大変ですし、知識が必要になりますがその後は安心して高速で安全なWebサービスの提供を行えるようになります。
Comments