Cloud Armorで地理制限を行い、Cloud Load Balancingでトラフィック分散を行う構成を実践する。

## はじめに

この記事は、
　[SRE ディビジョンの新卒向け研修に取り組んだ話
](https://zenn.dev/cloud_ace/articles/e0247381ae971b)という記事を読んで、その成果物となる一部の構成に
注目して自身の環境で『実際にやってみた』という記事になります。


## この記事で実施する事。
- `Cloud Run Service` をデプロイする。
- `Cloud Load Balancing` をデプロイする。
- `Cloud Armor` をデプロイする。
- 地理制限とトラフィックの分散を確認する。


今回はタイトルにもあるように、以下の範囲を実践します。
![cloudarmor-lb-run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/74fd682e-7a7f-6bed-3701-59a9762cb892.png)


## Cloud Run Service をデプロイする。
[get-current-time](https://github.com/tomo8332/gcp-sample/tree/main/cloud-run/golang/get-current-time) を、git clone してください。

```
git clone https://github.com/tomo8332/gcp-sample.git
```

git cloneの実行が完了したら、cdコマンドを使って、対象のディレクトリ階層へ移動。

```
cd gcp-sample/cloud-run/golang/get-current-time
```

[README.md](https://github.com/tomo8332/gcp-sample/blob/main/cloud-run/golang/get-current-time/README.md) を読んで、Cloud Run サービスのデプロイを行なってください。

今回は、トラフィックが分散されている事を確認したいので、
少なくとも2つ以上の異なるリージョンにデプロイしてください。


## Cloud Load Balancing をデプロイする。

GCPコンソールを開いて、『`load balancing`』を検索。
![gcp-load-balancing-search.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/e9a8c45f-7bd8-5abf-e6f4-2d6d6140cb55.png)

ロードバランサを作成をクリック。
![gcp-load-balancing-create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/f533eff1-d3bf-d169-d9b4-7914081d750d.png)

アプリケーション ロードバランサ（HTTP/S）の『構成を開始』をクリック。
![gcp-load-balancing-create-http.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/a407c897-e729-5afa-5b81-922a3053d651.png)

適切なロードバランサのタイプを選択。
![gcp-load-balancing-create-http-ques.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/32410f61-050b-6989-a9ff-31c32e34d68a.png)

新しいフロントエンドを作成。
名前：`cloud-armor-cloud-run-frontend`
プロトコル：`https`
![gcp-load-balancing-create-front.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/f0677519-f06d-6e09-2688-727d2b8d9dbe.png)

証明書を作成。
名前：任意の名前を入力。
作成モード：`Google マネージドの証明書を作成する`
ドメイン：[お名前.com](https://www.onamae.com/) などのドメイン登録サービスで取得したドメインを入力。
![gcp-load-balancing-create-ssl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/5e47346b-fa92-f643-b032-fa762159a2f2.png)

フロントエンドの設定は、その他の項目はデフォルトで完了。  

バックエンドの構成 > バックエンドサービスを作成。  
![gcp-load-balancing-create-back.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/8902ee6c-13e3-77c7-309c-e28a7b4b7670.png)

新しいバックエンドサービスを作成。
名前：`cloud-armor-cloud-run-backend`
バックエンドタイプ：`サーバーレス ネットワーク エンドポイント グループ`
![gcp-load-balancing-create-back-name.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/116a7c82-5208-a1a9-82f1-ef183bcc43b3.png)

バックエンドのサーバレスネットワークエンドポイントグループを選択。
既存で作成していれば、対象のサーバレスネットワークエンドポイントグループを選択。
作成していない場合は、新規でサーバレスネットワークエンドポイントグループを作成。
![gcp-load-balancing-create-back-neg.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/d17048fb-7e3c-4920-7222-668fed9e5f30.png)

サーバーレス ネットワーク エンドポイント グループの作成。

名前：任意の名前を入力。
リージョン： Cloud Run Service をデプロイしているリージョンを選択。
サービス：バックエンド対象のCloud Run Service を選択。
![gcp-load-balancing-create-back-neg-create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/2472ffa6-e748-ff83-8d55-44bc13db3c2b.png)

バックエンドは、`Cloud Armor` で地理制限を行い、
`Cloud Load Balancing` で、分散したいので、
異なるリージョンにデプロイされた
２つ以上の `Cloud Run` で構成された
サーバレスNEGを選択してください。
![gcp-load-balancing-create-back2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/b8cf3564-e547-6609-6eac-1ec1a4df22c3.png)

バックエンドサービスの以下の設定を変えて、作成をクリック。

『Cloud CDN を有効にする』> チェックを外す。
『ロギングを有効にする』> チェックを入れる。

今回は、検証環境での実装の為、この条件としています。
![gcp-load-balancing-create-back-cdn-log.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/ff50b1bb-b505-48b1-2b2a-5fe5ac42ab28.png)

ルーティングルールを設定。

モード：`単純なホストとパスのルール` 

ホストとパスのルールで、バックエンドとそのバックエンドに
ルーティングするためのホストとパスを入力。
![gcp-load-balancing-create-rooting2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/40b016a8-bcdc-a7ff-8c2e-f7046fa07cef.png)

ロードバランサの名前を入力して、ロードバランサを作成。
![gcp-load-balancing-create-lb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/1dcb724e-a2e4-2892-b364-2226da966eb9.png)

ブラウザを開いて、ホストとパスを入力、Cloud Run Service に接続ができればOK。
![gcp-load-balancing-cloud-run.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/070f773f-05c8-6769-6dfa-a77f75496162.png)


## Cloud Armor をデプロイする。
GCPコンソールを開いて、『`cloud armor`』を検索。
![gcp-cloud-armor-search.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/ebdeca78-8188-b77f-b865-94287c26dd40.png)

『ポリシーの作成』をクリック。
![gcp-cloud-armor-create.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/56c56922-9635-be11-2fb1-44badffd77f1.png)

ポリシーの構成

名前：`cloud-armor-cloud-run`
ポリシータイプ：`バックエンド セキュリティ ポリシー`
範囲：`グローバル`
デフォルトのルールアクション：`拒否`
レスポンスコード：`403（アクセス拒否）`

これは、次のステップで登録するルールに一致しない場合、
グローバルの範囲でデプロイされたリソースに対して、実行内容を拒否する。

つまりは、『ルールに一致しないリクエストを拒否する』ということである。

![gcp-cloud-armor-create-policy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/58adb909-52ff-5b3e-3009-25a054bd70fe.png)

ルールの追加

モード：`詳細設定`
ルール構文に、下記をペースト。

```
origin.region_code == 'JA'
```

これは、特定のリージョンからのトラフィックを許可するルールを構築。
![gcp-cloud-armor-create-rule.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/a00c36cf-8772-ee22-845c-bf1419b1cc11.png)

カスタムルール言語属性の構成は、下記を参照。

https://cloud.google.com/armor/docs/rules-language-reference?hl=ja#expression-examples

ルールの追加の続き。

アクション：`許可`
優先度：`0`

特定のリージョンからのトラフィックを許可するルールを
設定しているので、アクションは `許可` を選択。

また、新規で別のルールを作成、
新規のルールの方が優先度が高い場合は、

- 新規のルールの優先度は、`0` に修正
- 既存のルールの優先度は、`1` に修正

が必要となる。

`Cloud Armor` では、優先度の数値が
小さいほど優先度が高いと見なされる。
![gcp-cloud-armor-create-rule2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/44b34c07-a654-354e-0016-2d25e7d7c2c8.png)

ターゲットへのポリシーの適用。

今回は、`Cloud Load Balancing` のバックエンドサービスに対して、
ポリシーを適用するので、対象のバックエンドサービスを選択。

ポリシーの構成とルールの追加、ターゲットの選択を終えたら、ポリシーの作成を実行。
![gcp-cloud-armor-create-target.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/9e48e745-adcf-23ae-31a9-cb0120082977.png)

## 地理制限とトラフィックの分散を確認する。

下記のガイドに従って、Compute Engine で Linux VM インスタンスを作成する。

https://cloud.google.com/compute/docs/create-linux-vm-instance?hl=ja

なお、VMインスタンスは検証の為、3つ作成する。

名前：
1つ目のインスタンス：`asia-northeast1-vm`
2つ目のインスタンス：`asia-northeast2-vm`
3つ目のインスタンス：`us-west2-vm`

リージョン：
1つ目のインスタンス：`asia-northeast1`
2つ目のインスタンス：`asia-northeast2-`
3つ目のインスタンス：`us-west2`

ゾーンはデフォルト


マシンの構成
シリーズ：`E2`
マシンタイプ：`e2-micro`

を選択。
![gcp-cloud-vm1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/559d328d-111f-db80-4776-c9d40d3e56c7.png)

ブートディスクの構成はガイドに沿って設定する。

ファイアウォールは、

- HTTPS トラフィックを許可する
- HTTPS トラフィックを許可する

にチェックを入れて、VMインスタンスを作成する。
![gcp-cloud-vm-fire.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/e43648e2-cbc4-970f-e10c-c804cbb79b4c.png)

それぞれのVMインスタンスで `SSH` 接続を行い、`Curl` コマンドでリクエストを送信。

`海外リージョン` でデプロイされたVMで、`Curl` コマンドを実行した際に、
`地理制限` が反映されていれば、`Cloud Armor` の設定は完了。
![gcp-cloud-vm-curl.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/46ef668b-1ddc-c2a0-f158-66645fea9625.png)

トラフィックの分散では、それぞれの条件を満たしていれば設定は完了。

`asia-northeast1` リージョンにデプロイされたVMで、
`Curl` コマンドを実行した際は、 `asia-northeast1` にトラフィックが分散。
![gcp-cloud-vm-curl-asia1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/46d05be8-a492-b528-c2b2-65c5205b92ec.png)

`asia-northeast2` リージョンにデプロイされたVMでは、
`Curl` コマンドを実行した際は、 `asia-northeast2` にトラフィックが分散。
![gcp-cloud-vm-curl-asia2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952807/426ee3f7-cfbd-2b05-4458-37cc1b4bfbad.png)


## 終わりに
今回の記事は、[SRE ディビジョンの新卒向け研修に取り組んだ話
](https://zenn.dev/cloud_ace/articles/e0247381ae971b)という記事で書かれていた内容から、その一部の構成として、
まだ、私があまり触れたことのない`Cloud Armor` に注目して、
自身の環境で『実際にやってみた』という内容でまとめました。

今回、`Cloud Armor` の設定では、地理制限のみがかけられていますが、
これ以外の設定として、自宅IPからのアクセスのみを許可する事や、
特定のIPアドレスからのリクエスト数が一定の閾値を超えた場合に
制限をかけたり、また、特定のIPアドレス範囲、HTTPヘッダーや、
その他のリクエスト属性に基づいてトラフィックを許可または拒否が可能で、
分散型サービス拒否（`DDoS`）攻撃の軽減、SQLインジェクションや
クロスサイトスクリプティング（`XSS`）などの一般的なウェブベースの
攻撃から、アプリケーションの保護などを行ってくれる優れ物みたいです。

`Cloud Armor` について、
軽く学習してみたいと考えていましたら、
参考にしていただけると幸いです。

あとで『じっくり読みたい』、『繰り返し読みたい』と
思ってくれましたら、『`ストック`』へ登録、
この記事が読まれている方にとって、
参考になる記事となりましたら、『`いいね`』を
付けていただけますと、励みになりますので、
よろしくお願いします。