📑

Cloudflare Waiting Room (待合室)を設定する方法

2023/03/12に公開

CloudflareはWaiting Room/待合室という機能を提供しています。これは、高負荷が予測されるウエブサイトに対して、その前段に待合室というものを作成し、順次アクセスしてきたユーザーを順番にオリジンウェブサイトにリダイレクトしてあげる機能です。これを用いることで設計を超える急激なユーザーのアクセスをHTTP500エラー等を出力することなく捌くことが可能となり、ユーザー全体の体験を向上させることが可能です。

勿論、多くのユーザーは待ち時間を経験することになります。本質的にはウェブサイトはクラウドのAuto Scalingや例えばAmazon Aurora等のクラウドネイティブデータベースを用いることで、同時処理可能数を引き上げることが本質的な解決となりますが、アプリケーションによってはセッション管理がAuto Scalingに対応していなかったり、そもそもクラウドで動作していないなどそうもいかないケースがあります。またコンテナ等を用いていない場合、Auto Scalingはスパイク検知後コンピュートリソースの拡充まで数分間を要するため突発的、かつ断続的なケースでは対応しきれない場合もあります。Waiting Room/待合室はそういった場合に有効な機能です。

CloudflareはこのWaiting Room/待合室機能を公共性の高い機関には無償提供をしており、クラスメソッドと連携して300を超える自治体に提供しています。民間のサイトでは有償プラン(本来CloudflareのCDNは基本機能であれば利用は無償です)にご契約いただくことでご利用が可能となります。

それでは前置きはこれぐらいにして設定方法を見ていきましょう。

  1. オリジンウェブサイトの準備
    重要な点ですが、Waiting Room/待合室をを利用するためにCloudflareのCDNを使っている必要はありません。 ウェブサイトに対してCNAMEを行うドメイン名のみCloudflareで管理されていれば問題ありません。このため、例えば外部SaaSやPaaS等に対する待合室の設定も可能ですが、多くの場合自社が管理していないドメインに対するCNAME設定はオリジンのドメイン元が拒否していますので、その場合はオリジンのドメイン管理者と相談していただく必要があります。
    例えば www.google.com に対するCNAME設定はグーグル側からアクセスが拒否されます。

Cloudflareから以下の通りCNAMEを設定します。

まず"Add record"を押します。
以下のようにCNAMEレコードを追加し"Save"を押します。

この例ではCloudflare側で既に"harunobukameda.labrat.online"というドメインを管理しています。そして"waitingroomtest.harunobukameda.labrat.online"というCNAMEエントリを "www.testorigin.com" に対して設定しています。

この際必ずDNS Proxyモードにセットしてください。これを行うことで通信はCloudflareネットワーク内を通るようルーティングされます。またオリジンのIPアドレスが保護されたり、古いもしくは不正なDNSキャッシュの影響を受けず、最適化されたルーティング機能が用いられることによる通信の高速化等、多くのメリットが享受できます。Waiting Roomを使う場合このモードは必須です。

  1. Waiting Roomの設定
    左ペイン"Traffic"の下の"Waiting Room"をクリックします。

    "Create"ボタンをおします。

    "Name"には適当な名前を付けてください。
    "Hostname"は先ほど設定したCNAMEを設定します。上の例であればwaitingroomtest.harunobukameda.labrat.onlineとなります。
    "Total active users"は一度にオリジンが処理可能なユーザー数です。最小数は200です。
    "New users per minute"は1分間にWaiting Roomからオリジンに送り込むユーザー数です。最小数は"Total active users"が下限値となりその値に依存します。
    "Session duration"はそのユーザーがオリジンサイトに滞在すると予測される時間です。最大値は30分です。

Waiting Roomはオリジンの負荷状態をリアルタイムで判別し、ユーザーを送り込むわけではないことに注意してください。この3つの設定をもとにルールに従いユーザーを送り込みます。後ほど説明しますが、マネージメントコンソールでは現在の待ちユーザー数等のおおよその推察が可能となっておるため、運用中はこの値を確認しながらこれら3つのパラメーターをチューニングしていく必要があります。


次にWaiting Roomからオリジンへのユーザーの送り込み方法です。
ほとんどの場合、FIFO(First In First Out)モードを利用することになりますが、例えば抽選サイトなど様に"Random"が準備されていたりいくつかのパターンがあります。

"Next"を押すと待ち画面のカスタマイズ画面となります。

"Custom waiting room"を設定することで独自の待ち画面を設定可能です。
"Next"→"Save"を押すと設定が可能です。

3.実はこれだけ!
これでWaiting Roomがセットされました。CNAMEのドメインにアクセスしてみます。正しくオリジンが表示されれば完了です。(あとで使うのでそのブラウザのタブは消さないでください)
)もちろんこの際オリジン側では、直接のアクセスを防ぐ実装を行うことが望ましいです。Cloudflareでは以下の方法を提供しています。
1.IP アドレスレンジによる制御
2.HTTP Headerによる制御
3.WorkersやOriginによる独自認証機構組み込み
4.mTLSによる相互認証
5.Cloudflare Tunnelを使う
1および2は多くの方がご存じの通り書き換えが可能ですので手軽ではありますが完璧ではありません。3および4は強固ですが手間がかかります。5.は非常に強力かつ実装が簡単なソリューションですがオリジンに"cloudflared"というエージェントのインストールが必要で、その検証などが必要となるかもしれません。
ここで重要なのが上記で設定したDNSのProxyモードです。これによりオリジンは隠匿化されていますので、急ぎの設定であればオリジンへの直接アクセス対策はあと回しでもいいかもしれません。

なお、オリジンのドメインは隠匿化されていますが、ドメインがわかってしまった場合digでIPを掘ることはできますので注意して下さい。

4.テスト
ではテストしてみましょう。1分間に200を超えるアクセスを発生させることは手間がかかるので、一度Queueモードを以下のように"Queue-all"に変更します。

これにより全ての新規リクエストがQueueにはいります

別のブラウザでアクセスを行うと以下のように待合室の画面が表示されます。

この画面では定期的にブラウザをリロードしながら順番を待ちます。
一方先ほどアクセスを行った画面をリロードすると引き続きアクセスできていることがわかります。
オリジンにアクセスされた時点でそのクッキーがセットされているからです。

では一度Cookieを見てみます。Cookieは非常にシンプルです。アクセスができている場合以下の様にValueが0でセットされています。

一方待ち時間の間のCookieは以下です。

Valueに値が何かセットされているのがわかります。ではこの値を0に書き換えると中に入れるのでしょうか?そうはいきません。この値はDPAPI経由でAES256暗号処理がなされています。

こんな感じで待ちユーザー数などが確認できます。

5.例外ルール
Waitingルールには例外処理(直接ユーザーをオリジンへ送る)機能が準備されています。乱用はトラブルの元ですが、例えば社内からのアクセスのみをオリジンへ優先的に送る等が必要になるケースがあります。
"Manage rules"を押します。

"Create new bypass rule"を押します。
以下のように設定し"Save and Deploy"を押すと、Chromeだけは直接アクセスが可能で、それ以外のブラウザはQueueに回されるようになります。

6.Scheduleイベント
最後にShceduleイベントについても見ておきます。この機能はある指定された時間帯においてWaiting Roomの機能を変更します。例えば朝10時から一斉にアクセスを受け付ける場合デフォルトでは"Override with Reject-all"にしておいて10時時点で"Override with FIFO"にする使い方などが考えられます。

いかがでしたでしょうか。非常に簡単に実装ができることをご理解いただけたかと思います。
アクセス数が読みずらいサイトや予算の関係上オーバープロビジョニングできないサイトなどには有効なソリューションになります。高負荷によるシステムダウンは常に工期と予算の兼ね合いで発生し、フロントエンドエンジニアやインフラエンジニアの責任に起因しない場合が多くあります。というよりほとんどのケースはそうかもしれません。その場合に有効に使っていただければ幸いです。

Discussion