Cloud Armor によるレート制限

1. はじめに

Google Cloud HTTP(S) ロード バランシングは、世界中の Google の接続拠点(POP)で Google ネットワークのエッジにデプロイされています。HTTP(S) ロードバランサを送信先とするユーザー トラフィックは、ユーザーに最も近い POP に入った後、Google のグローバル ネットワークで負荷分散されて、十分な容量がある最も近いバックエンドに送られます。

Cloud Armor は、Google が提供する分散型サービス拒否攻撃およびウェブ アプリケーション ファイアウォール(WAF)検出システムです。Cloud Armor は Google Cloud の HTTP ロードバランサと緊密に連携しているため、受信トラフィックで不要なリクエストの有無を調べることができます。このサービスのレート制限機能を使用すると、リクエストの量に応じてバックエンド リソースへのトラフィックを制限し、望ましくないトラフィックによって Virtual Private Cloud(VPC)ネットワーク上のリソースが消費されるのを防ぐことができます。

次の図に示されるように、このラボではグローバルなバックエンドを使って HTTP ロードバランサを構成します。次に、ロードバランサのストレステストを行い、Cloud Armor のレート制限ポリシーを追加して、バックエンド リソースに到達するトラフィックを制限します。

2e1b99d22f4f32a.png

学習内容

  • 適切なヘルスチェックを使用して HTTP ロードバランサを設定する方法。
  • Cloud Armor のレート制限ポリシーを作成する方法。
  • VM からストレステストを実施する際に、レート制限ポリシーによってトラフィックがブロックされているかどうかを検証する方法。

必要なもの

  • ネットワーキングの基礎と HTTP の知識
  • Unix / Linux コマンドラインに関する基本的な知識

2. 設定と要件

セルフペース型の環境設定

  1. Google Cloud Console にログインして、プロジェクトを新規作成するか、既存のプロジェクトを再利用します。Gmail アカウントも Google Workspace アカウントもまだお持ちでない場合は、アカウントを作成してください。

96a9c957bc475304.png

b9a10ebdf5b5a448.png

a1e3c01a38fa61c2.png

  • プロジェクト名は、このプロジェクトの参加者に表示される名称です。Google API では使用されない文字列で、いつでも更新できます。
  • プロジェクト ID は、すべての Google Cloud プロジェクトにおいて一意でなければならず、不変です(設定後は変更できません)。Cloud Console により一意の文字列が自動生成されます(通常は内容を意識する必要はありません)。ほとんどの Codelab では、プロジェクト ID を参照する必要があります(通常、プロジェクト ID は「PROJECT_ID」の形式です)。好みの文字列でない場合は、別のランダムな ID を生成するか、独自の ID を試用して利用可能であるかどうかを確認することができます。プロジェクトの作成後、ID は「フリーズ」されます。
  • 3 つ目の値として、一部の API が使用するプロジェクト番号があります。これら 3 つの値について詳しくは、こちらのドキュメントをご覧ください。
  1. 次に、Cloud のリソースや API を使用するために、Cloud Console で課金を有効にする必要があります。この Codelab の操作をすべて行って、費用が生じたとしても、少額です。このチュートリアルを終了した後に課金が発生しないようにリソースをシャットダウンするには、Codelab の最後にある「クリーンアップ」の手順を行います。Google Cloud の新規ユーザーは、300 米ドル分の無料トライアル プログラムをご利用いただけます。

Cloud Shell の起動

Google Cloud はノートパソコンからリモートで操作できますが、この Codelab では、Google Cloud Shell(Cloud 上で動作するコマンドライン環境)を使用します。

GCP Console で右上のツールバーにある Cloud Shell アイコンをクリックします。

bce75f34b2c53987.png

プロビジョニングと環境への接続にはそれほど時間はかかりません。完了すると、次のように表示されます。

f6ef2b5f13479f3a.png

この仮想マシンには、必要な開発ツールがすべて用意されています。永続的なホーム ディレクトリが 5 GB 用意されており、Google Cloud で稼働します。そのため、ネットワークのパフォーマンスと認証機能が大幅に向上しています。このラボでの作業はすべて、ブラウザから実行できます。

始める前に

Cloud Shell 内で、プロジェクト ID が設定されていることを確認します。

gcloud config list project
gcloud config set project [YOUR-PROJECT-NAME]
PROJECT_ID=[YOUR-PROJECT-NAME]
echo $PROJECT_ID

API を有効にする

必要なサービスをすべて有効にする

gcloud services enable compute.googleapis.com
gcloud services enable logging.googleapis.com
gcloud services enable monitoring.googleapis.com

3. バックエンドへの HTTP トラフィックを許可するファイアウォール ルールを構成する

Google Cloud ヘルスチェックとロードバランサからバックエンドへの HTTP トラフィックを許可するように、ファイアウォール ルールを構成します。

プロジェクトで作成された default VPC ネットワークを使用します。バックエンドへの HTTP トラフィックを許可するファイアウォール ルールを作成します。ヘルスチェックでは、ロードバランサのどのインスタンスが新しい接続を受け取れるかを確認します。HTTP ロード バランシングの場合、ロード バランシング インスタンスへのヘルスチェック プローブは、130.211.0.0/22 と 35.191.0.0/16 の範囲のアドレスから送信されます。VPC ファイアウォール ルールで、これらの接続を許可する必要があります。また、これらのロードバランサは同じ IP 範囲のバックエンドと通信します。

  1. Cloud コンソールで、ナビゲーション メニューmainmenu.png)>VPC ネットワーク >ファイアウォール

dbdf491e6d7863f3.png

  1. ICMP内部RDPSSH のファイアウォール ルールがすでに存在します。Google Cloud プロジェクトには、それぞれ default ネットワークとこれらのファイアウォール ルールがあります。
  2. [ファイアウォール ルールを作成] をクリックします。
  3. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(値を入力するか、指定されたオプションを選択)

名前

default-allow-health-check

ネットワーク

default

ターゲット

指定されたターゲットタグ

ターゲットタグ

http-server

ソースフィルタ

IP 範囲

ソース IP の範囲

130.211.0.0/22、35.191.0.0/16

プロトコルとポート

[指定したプロトコルとポート] と [TCP] のチェックボックスをオンにする

  1. [作成] をクリックします。

または、gcloud コマンドラインを使用する場合。コマンドは以下のとおりです。

gcloud compute firewall-rules create default-allow-health-check --direction=INGRESS --priority=1000 --network=default --action=ALLOW --rules=tcp --source-ranges=130.211.0.0/22,35.191.0.0/16 --target-tags=http-server

4. インスタンス テンプレートを構成し、マネージド インスタンス グループを作成する

マネージド インスタンス グループは、インスタンス テンプレートを使用して同一インスタンスのグループを作成します。これらを使用して、HTTP ロードバランサのバックエンドを作成します。

インスタンス テンプレートを構成する

インスタンス テンプレートは、VM インスタンスとマネージド インスタンス グループの作成に使用する API リソースです。このテンプレートは、マシンタイプ、ブートディスク イメージ、サブネット、ラベル、その他のインスタンス プロパティを定義します。us-east1europe-west1 にインスタンス テンプレートを 1 つずつ作成します。

  1. Cloud コンソールで、ナビゲーション メニューmainmenu.png)>Compute Engine >[インスタンス テンプレート] をクリックし、[インスタンス テンプレートを作成] をクリックします。
  2. [名前] に「us-east1-template」と入力します。
  3. [シリーズ] で [N1] を選択します。
  4. [ネットワーキング、ディスク、セキュリティ、管理、単一テナンシー] をクリックします。

b60e2a44c3e4d50e.png

  1. [管理] セクションに移動します。

ee57f20ce55298fd.png

  1. [メタデータ] で [項目を追加] をクリックし、次の値を指定します。

Key(キー)

startup-script-url

gs://cloud-training/gcpnet/httplb/startup.sh

  1. [ネットワーキング] をクリックします。
  2. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(値を入力するか、指定されたオプションを選択)

ネットワーク([ネットワーク インターフェース] の下)

デフォルト

サブネット(ネットワーク インターフェースの下)

default (us-east1)

ネットワーク タグ

http-server

  1. [作成] をクリックします。
  2. インスタンス テンプレートの作成が完了するまで待ちます。

次に、us-east1-template をコピーして、subnet-b にもう 1 つのインスタンス テンプレートを作成します。

  1. [us-east1-template] をクリックし、上部の [コピー] オプションをクリックします。
  2. [名前] に「europe-west1-template」と入力します。
  3. [ネットワーキング、ディスク、セキュリティ、管理、単一テナンシー] をクリックします。
  4. [ネットワーキング] をクリックします。
  5. [ネットワーク インターフェース] で、デフォルト インターフェースを編集します。[サブネット] で [デフォルト(europe-west1)] を選択します。
  6. [作成] をクリックします。

マネージド インスタンス グループを作成する

マネージド インスタンス グループを us-east1europe-west1 にそれぞれ作成します。

  1. 引き続き [Compute Engine] で、左側のメニューの [インスタンス グループ] をクリックします。

72319de055de3942.png

  1. [インスタンス グループを作成] をクリックします。[新しいマネージド インスタンス グループ(ステートレス)] を選択します。
  2. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(値を入力するか、指定されたオプションを選択)

名前

us-east1-mig

ロケーション

マルチゾーン

リージョン

us-east1

インスタンス テンプレート

us-east1-template

自動スケーリング >自動スケーリング ポリシー >鉛筆アイコン > をクリックします。指標タイプ

CPU 使用率

CPU 使用率の目標値

80 が表示されたら、[完了] をクリックします。

クールダウン期間

45

インスタンスの最小数

1

インスタンスの最大数

5

  1. [作成] をクリックします。

同じ手順を繰り返して、2 つ目のインスタンス グループ europe-west1-migeurope-west1 に作成します。

  1. [インスタンス グループを作成] をクリックします。
  2. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(値を入力するか、指定されたオプションを選択)

名前

europe-west1-mig

ロケーション

マルチゾーン

リージョン

europe-west1

インスタンス テンプレート

europe-west1-template

自動スケーリング >自動スケーリング ポリシー >鉛筆アイコン > をクリックします。指標タイプ

CPU 使用率

CPU 使用率の目標値

80 が表示されたら、[完了] をクリックします。

クールダウン期間

45

インスタンスの最小数

1

インスタンスの最大数

5

  1. [作成] をクリックします。

5. HTTP ロードバランサを構成する

以下のネットワーク図に示されるように、HTTP ロードバランサを構成して、2 つのバックエンド(us-east1 の us-east1-mig と europe-west1 の europe-west1-mig)間でトラフィックを分散します。

2e1b99d22f4f32a.png

構成を開始する

  1. Cloud コンソールで、ナビゲーション メニューmainmenu.png)> [[ネットワーク サービス] >[ロード バランシング] をクリックし、[ロードバランサを作成] をクリックします。
  2. [HTTP(S) ロード バランシング] で [構成を開始] をクリックします。

8197d8f041e8eafd.png

  1. [インターネットから自分の VM へ]、[従来の HTTP(S) ロードバランサ] を選択し、[続行] をクリックします。
  2. [名前] を http-lb に設定します。

バックエンドを構成する

バックエンド サービスによって、受信トラフィックが、接続されている 1 つ以上のバックエンドに振り向けられます。各バックエンドは、1 つのインスタンス グループと、追加の提供容量メタデータで構成されます。

  1. [バックエンドの構成] をクリックします。
  2. [バックエンド サービスとバックエンド バケット] で、[バックエンド サービスを作成] をクリックします。
  3. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(指定されたオプションを選択)

名前

http-backend

インスタンス グループ

us-east1-mig

ポート番号

80

分散モード

レート

最大 RPS

50(インスタンスあたり)

容量

100

  1. [完了] をクリックします。
  2. [バックエンドを追加] をクリックします。
  3. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(指定されたオプションを選択)

インスタンス グループ

europe-west1-mig

ポート番号

80

分散モード

使用率

バックエンドの最大使用率

80

容量

100

  1. [完了] をクリックします。
  2. [ヘルスチェック] で [ヘルスチェックを作成] を選択します。

199239806577ceac.png

  1. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(指定されたオプションを選択)

名前

http-health-check

プロトコル

TCP

ポート

80

20f7af9fce140475.png

  1. [保存] をクリックします。
  2. [ロギングを有効にする] チェックボックスをオンにします。
  3. [サンプルレート] を 1 に設定します。

dab4b15c13917786.png

  1. [作成] をクリックすると、バックエンド サービスが作成されます。

2db64614f855f239.png

フロントエンドを構成する

ホストとパスのルールによって、トラフィックの転送方法が決定されます。たとえば、動画のトラフィックと静的トラフィックをそれぞれ異なるバックエンドに転送できます。ただし、このラボではホストとパスのルールは構成しません。

  1. [フロントエンドの構成] をクリックします。
  2. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(値を入力するか、指定されたオプションを選択)

プロトコル

HTTP

IP バージョン

IPv4

IP アドレス

エフェメラル

ポート

80

  1. [完了] をクリックします。
  2. [フロントエンドの IP とポートを追加] をクリックします。
  3. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(値を入力するか、指定されたオプションを選択)

プロトコル

HTTP

IP バージョン

IPv6

IP アドレス

エフェメラル

ポート

80

  1. [完了] をクリックします。

HTTP ロードバランサを確認して作成する

  1. [確認と完了] をクリックします。

2c88715aa5f22800.png

  1. [バックエンド サービス] と [フロントエンド] を確認します。

b2fffef90be309f0.png

  1. [作成] をクリックします。
  2. ロードバランサの作成が完了するまで待ちます。
  3. ロードバランサの名前(http-lb)をクリックします。
  4. 次のタスクのために、ロードバランサの IPv4 アドレスと IPv6 アドレスをメモしておきます。以降はこれらのアドレスをそれぞれ [LB_IP_v4]、[LB_IP_v6] と呼びます。

6. HTTP ロードバランサをテストする

バックエンドのための HTTP ロードバランサを作成できたので、トラフィックがバックエンド サービスに転送されるかどうかを確認します。

HTTP ロードバランサにアクセスする

HTTP ロードバランサへの IPv4 アクセスをテストするには、ブラウザで新しいタブを開いて http://[LB_IP_v4] に移動します。[LB_IP_v4] はロードバランサの IPv4 アドレスに置き換えてください。

ローカル IPv6 アドレスがある場合は、http://[LB_IP_v6] に移動して HTTP ロードバランサの IPv6 アドレスを試します。[LB_IP_v6] はロードバランサの IPv6 アドレスに置き換えてください。

812d1fc75d9dfb3c.png

HTTP ロードバランサのストレステストを実施する

新しい VM を作成し、siege を使用して HTTP ロードバランサの負荷をシミュレートします。負荷が高くなるとトラフィックが両方のバックエンドに分散されることを確認します。

  1. コンソールで、ナビゲーション メニューmainmenu.png)>Compute Engine >VM インスタンス
  2. [インスタンスを作成] をクリックします。
  3. 以下の値を設定し、他はすべてデフォルト値のままにします。

プロパティ

値(値を入力するか、指定されたオプションを選択)

名前

siege-vm

リージョン

us-west1

ゾーン

us-west1-c

シリーズ

N1

  1. [作成] をクリックします。
  2. siege-vm インスタンスの作成が完了するまで待ちます。
  3. siege-vm で [SSH] をクリックし、ターミナルを起動して接続します。
  4. 次のコマンドを実行して siege をインストールします。
sudo apt-get -y install siege
  1. 次のコマンドを実行して、HTTP ロードバランサの IPv4 アドレスを環境変数に格納します。[LB_IP_v4] は IPv4 アドレスに置き換えます。
export LB_IP=[LB_IP_v4]
  1. 次のコマンドを実行して負荷をシミュレートします。
siege -c 250 http://$LB_IP

出力は次のようになります(コピーしないでください。これは出力例です)。

New configuration template added to /home/student/.siege
Run siege -C to view the current settings in that file
** SIEGE 4.0.4
** Preparing 250 concurrent users for battle.
The server is now under siege...
  1. Google Cloud コンソールのナビゲーション メニューmainmenu.png)で、[ネットワーク サービス] >ロード バランシング
  2. http-lb をクリックします。
  3. [モニタリング] タブをクリックします。北米と 2 つのバックエンド間のトラフィックを 2 ~ 3 分間モニタリングします。

最初はトラフィックが us-east1-mig のみに転送されていますが、RPS が増加すると europe-west1-mig にも転送されるようになります。

ead1e6d5c1f4cc4b.png

これで、デフォルトではトラフィックが最も近いバックエンドに転送され、負荷が高くなるとバックエンド間で分散されることを確認できました。

e5c6a657706c832c.png

  1. siege-vmSSH ターミナルに戻ります。
  2. Ctrl+C キーを押して siege を停止します。

7. Cloud Armor レート制限ポリシーの作成

このセクションでは、Cloud Armor を使用してレート制限ポリシーを設定し、siege-vm による HTTP ロードバランサへのアクセスを拒否します。

  1. Cloud Shell で(Cloud Shell の使用方法については、「設定と要件」の「Cloud Shell の起動」を参照)、gcloud を使用してセキュリティ ポリシーを作成します。
gcloud compute security-policies create rate-limit-siege \
    --description "policy for rate limiting"
  1. 次に、レート制限ルールを追加します。
gcloud beta compute security-policies rules create 100 \
    --security-policy=rate-limit-siege     \
    --expression="true" \
    --action=rate-based-ban                   \
    --rate-limit-threshold-count=50           \
    --rate-limit-threshold-interval-sec=120   \
    --ban-duration-sec=300           \
    --conform-action=allow           \
    --exceed-action=deny-404         \
    --enforce-on-key=IP
  1. セキュリティ ポリシーをバックエンド サービスの http-backend に接続します。
gcloud compute backend-services update http-backend \
    --security-policy rate-limit-siege –-global
  1. コンソールで、ナビゲーション メニュー >ネットワーク セキュリティ >Cloud Armor
  2. Click Rate-limit-siege。ポリシーが次のようになります。

8be87aa31c2ed74e.png

セキュリティ ポリシーを確認する

  1. siege-vm の SSH ターミナルに戻ります。
  2. LB IP に対して curl を実行し、まだ接続できることを確認します。200 レスポンスが返されます。
curl http://$LB_IP
  1. siege-vm の SSH ターミナルで、次のコマンドを実行して負荷をシミュレートします。
siege -c 250 http://$LB_IP

出力は次のようになります(コピーしないでください。これは出力例です)。

** SIEGE 4.0.4
** Preparing 250 concurrent users for battle.
The server is now under siege...
  1. セキュリティ ポリシーのログを調べて、このトラフィックもブロックされているかどうかを確認します。
  2. Console で、ナビゲーション メニュー > [ネットワーク セキュリティ] > [Cloud Armor] に移動します。
  3. [rate-limit-siege] をクリックします。
  4. [ログ] をクリックします。

f8be7c01c3d7c8f5.png

  1. [ポリシーログを表示] をクリックします。
  2. [ロギング] ページで、[クエリのプレビュー] のテキストをすべて消去してください。
  3. リソースを「Cloud HTTP ロードバランサ>」として選択します。http-lb-forwarding-rule >http-lb を選択し、[追加] をクリックします。または、以下の MQL(モニタリング クエリ言語)クエリをコピーして、クエリエディタに貼り付けることもできます。
resource.type="http_load_balancer" resource.labels.forwarding_rule_name="http-lb-forwarding-rule" resource.labels.url_map_name="http-lb"
  1. [クエリを実行] をクリックします。
  2. [クエリ結果] でログエントリを開きます。
  3. [httpRequest] を開きます。リクエストは、siege-vm という IP アドレスから送信されるはずです。そうでない場合は、別のログエントリを展開します。
  4. jsonPayload を展開します。
  5. enforcingSecurityPolicy を展開します。

151f575ba7b3bde9.png

configAction が rate-limit-siege という名前の RATE_BASED_BAN に設定されていることに注目してください。

  1. さらに、ナビゲーション メニューmainmenu.png)で [ネットワーク サービス] >ロード バランシング。[http-lb] をクリックします。[モニタリング] タブをクリックします。

ab9a8a66573a5ebd.png

Siege のトラフィックはグラフで確認できます。また、レート制限されたトラフィックはバックエンドに到達せず、Cloud Armor ポリシーによってブロックされます。

これで完了です。これで、Cloud Armor によるレート制限に関するラボが完了しました。

©2020 Google LLC All rights reserved.Google および Google のロゴは、Google LLC の商標です。その他すべての社名および製品名は、それぞれ該当する企業の商標である可能性があります。

8. ラボのクリーンアップ

  1. [ネットワーク セキュリティ >>Cloud Armor >>%POLICY NAME%」と入力し、[削除] を選択します。

eeafa7cafa11c4c7.png

  1. [ネットワーキング >>ネットワーク サービス >>ロード バランシング。作成したロードバランサを選択し、[削除] をクリックします。

3886458f25cfbd36.png

削除する追加リソースとしてバックエンド サービスとヘルスチェックを選択します。

a0193e91b2f4cb6f.png

  1. ナビゲーション メニューmainmenu.png)>Compute Engine >インスタンス グループ。両方のマネージド インスタンス グループを選択して [削除] をクリックします。

5027d56977997f70.png

「delete」と入力して削除を確定してください入力します。

マネージド インスタンス グループが削除されるまで待ちます。これにより、グループ内のインスタンスも削除されます。テンプレートを削除できるのは、インスタンス グループの削除後のみです。

  1. 左側のペインから [インスタンス テンプレート] に移動します**。**両方のインスタンス テンプレートを選択し、[削除] をクリックします。

8d88abacd32c11ce.png

  1. 左側のペインから [VM インスタンス] に移動します**。**siege-vm インスタンスの横にある省略記号を選択し、[削除] をクリックします。

2b58ab43695836e9.png

  1. ナビゲーション メニューmainmenu.png)>VPC ネットワーク >ファイアウォール。default-allow-health-check を選択し、[削除] をクリックします。

561d5e771d36d85.png

9. 完了

Cloud Armor を使用してレート制限を正しく実装できました。us-east1 と europe-west1 のバックエンドで HTTP ロードバランサを構成しました。次に、VM を使用してロードバランサのストレステストを実施し、Cloud Armor でレート制限によって IP アドレスを拒否リストに登録しました。最後に、セキュリティ ポリシーのログを調べて、トラフィックがブロックされた理由を特定しました。

学習した内容

  • インスタンス テンプレートを設定し、マネージド インスタンス グループを作成する方法。
  • HTTP ロードバランサの設定方法
  • Cloud Armor のレート制限ポリシーを作成する方法。
  • レート制限ポリシーが意図したとおりに機能していることを確認する方法。

次のステップ

  • ソース IP 範囲に基づいてレート制限ポリシーを設定してみてください。以下にサンプル コマンドを示します -
gcloud alpha compute security-policies rules create 105 \
    --security-policy sec-policy     \
    --src-ip-ranges "1.2.3.0/24"     \
    --action throttle                \
    --rate-limit-threshold-count 100 \
    --rate-limit-threshold-interval-sec 60 \
    --conform-action allow           \
    --exceed-action deny-429         \
    --enforce-on-key IP
  • 地域コードに基づいてレート制限ポリシーを設定してみてください。以下にサンプル コマンドを示します -
gcloud alpha compute security-policies rules create 101 \
    --security-policy sec-policy     \
    --expression "origin.region_code == 'US'" \
    --action rate-based-ban                 \
    --rate-limit-threshold-count 10         \
    --rate-limit-threshold-interval-sec 60  \
    --ban-duration-sec 300           \
    --ban-threshold-count 1000       \
    --ban-threshold-interval-sec 600 \
    --conform-action allow           \
    --exceed-action deny-403         \
    --enforce-on-key IP