Serverless NEGを使用して、GAEにIPv4の固定IPアドレスでIP制限をする
はじめに
この記事は ミライトデザイン Advent Calendar 2021 の 23 日目の記事となっています。
前回は「docker-laravel の Docker 構成をちゃんと理解する【Dockerfile 編 - PHP】」という記事を書いてくれた takuma でした。
docker-compose 編 もあるので、そっちも見てみてください。
以前に IP 制限を GAE ( Google App Engine ) で実現したいケースがありました。
しかし、GAE は自動的に IPv6 に対応するそうで、半固定の IPv6 に対しては固定 IP で制限ができないという事象がありました。
色々方法はあると思いますが、今回の記事では Serverless NEG を使用し ロードバランサ経由 で GAE にアクセスすることで、 IP 制限の実現ができたのでそちらの紹介をします。
NEG とは
そもそも NEG というのは「Network Endpoint Group」の略です。
名前の通り 複数のネットワークエンドポイントをまとめたもの となっていて、ロードバランサのエンドポイントとして指定が可能となっています。
NEG にはいくつか種類があり、今回のケースでは Serverless NEG というものを使用します。
以下の画像は GKE ( Google Kubernetes Engine ) での画像ですが、イメージしやすいと思ったので持ってきました。
Container-native load balancing on GKE now generally available | Google Cloud Blog より引用
従来の GKE のロードバランサは iptables で再度負荷分散をするという 2 段階ロードバランシングだったのを、 NEG を使用することで直説負荷分散できるといった内容を紹介してくれています。
NEG とは何かという方にはイメージしやすいのではないでしょうか。
Serverless NEG とは
Serverless NEG というのは サーバーレスサービスに対して使用できる NEG です。
NEG は今まで GCE ( Google Compute Engine ) や GKE にしか使用できなかったようです。
しかし、 Serverless NEG の登場により「App Engine」「Cloud Functions」「Cloud Run」のサーバーレスサービスでも使用ができるようになりました。
そのため、ロードバランサのエンドポイントにサーバーレスサービスを指定し、ロードバランサで IPv4 を指定することで GAE には IPv4 でのアクセスとなり、本来やりたかった固定 IP の制限が可能になるということです。
環境構築手順
では実際に環境を作ってみましょう。
大きく手順としては以下の通りです。
- GAE をデプロイする
- 静的 IP アドレスを取得する
- Serverless NEG を作成する
- バックエンドサービスを作成する
- ロードバランサを設定する
GAE をデプロイする
GAE のアプリケーションがデプロイされている上で IP 制限をかけたいというユースケースのため、ここでは GAE のデプロイ詳細は省略します。
Laravel の例ですが、 IP の確認をするためにエンドポイントへ以下のアクションを追加しておくと GAE へのリクエスト IP の確認ができます。
public function ip(Request $request): array
{
return [
'ip' => $request->ip(),
'ips' => $request->ips(),
'client_ip' => $request->getClientIp(),
'client_ips' => $request->getClientIps(),
'X-Appengine-User-Ip' => $request->header('X-Appengine-User-Ip'),
];
}
静的 IP アドレスの作成
ロードバランサのエンドポイントに使用するため静的 IP アドレスを作成しておきます。
gcloud compute addresses create [IPアドレス論理名] \
--ip-version=IPV4 \
--global
以下のコマンドで予約されている IPv4 アドレスを控えときましょう。
gcloud compute addresses describe [IPアドレス論理名] \
--format="get(address)" \
--global
GUI 上でも作成されていることが確認できます。
Serverless NEG の作成
GAE 用の Serverless NEG を作成します。
なお、リージョンについては GAE と同じリージョンにする必要があります。
gcloud compute network-endpoint-groups create [ServerlessNEG論理名] \
--region=[リージョン名] \
--network-endpoint-type=serverless \
--app-engine-app \
--app-engine-service=default
作成されたことを以下のコマンドで確認します。
gcloud beta compute network-endpoint-groups list
NAME LOCATION ENDPOINT_TYPE SIZE
[ServerlessNEG論理名] [リージョン名] SERVERLESS 0
GUI 上でも作成されていることが確認できます。
バックエンドサービスの作成
バックエンドサービスを作成し、バックエンドとして先ほど作成した Serverless NEG を追加します。
gcloud compute backend-services create [バックエンドサービス論理名] \
--global
NAME BACKENDS PROTOCOL
[バックエンドサービス論理名] HTTP
バックエンドサービスに Serverless NEG を追加
gcloud compute backend-services add-backend [バックエンドサービス論理名] \
--global \
--network-endpoint-group=[ServerlessNEG論理名] \
--network-endpoint-group-region=[リージョン名]
バックエンドサービスが作成され、 Serverless NEG が追加されているかを以下のコマンドで確認しましょう。
gcloud beta compute backend-services list
NAME BACKENDS PROTOCOL LOAD_BALANCING_SCHEME HEALTH_CHECKS
[バックエンドサービス論理名] [リージョン名]/networkEndpointGroups/[ServerlessNEG論理名] HTTP EXTERNAL
GUI 上でも確認ができます。
ロードバランサーの設定
まずは受信リクエストをバックエンドサービスにルーティングするための URL マップを作成します。
gcloud compute url-maps create [ロードバランサ論理名] \
--default-service [バックエンドサービス論理名]
NAME DEFAULT_SERVICE
[ロードバランサ論理名] backendServices/[バックエンドサービス論理名]
ターゲットhttpプロキシを作成しロードバランサに追加
URL マップにリクエストをルーティングするターゲット HTTPS プロキシを作成します。
HTTP ロードバランサの場合、HTTP ターゲット プロキシを作成します。
gcloud compute target-http-proxies create [ターゲットhttpプロキシ論理名] \
--url-map=[ロードバランサ論理名]
NAME URL_MAP
[ターゲットhttpプロキシ論理名] [ロードバランサ論理名]
フロントエンド ( forwarding rule ) をロードバランサに追加
gcloud compute forwarding-rules create [フロントエンド論理名] \
--address=[控えていたIPアドレスを指定] \
--target-http-proxy=[ターゲットhttpプロキシ論理名] \
--global \
--ports=80
ロードバランサ・フロントエンドの確認
以下のコマンドで作成したものを確認しましょう。
$ gcloud compute forwarding-rules list
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET
[フロントエンド論理名] [IPアドレス] TCP [ターゲットhttpプロキシ論理名]
GUI でも確認します。
ロードバランサにリクエストしてみる
作成したロードバランサにリクエストをしてみましょう。
取得した IP アドレスを URL に入力してアクセスするとデプロイしたアプリケーションの画面が表示されます。
自分の場合は Laravel のアプリケーションをデプロイしたので、 Webcome ページが表示されます。
固定 IP でアクセスできるかを確認してみる
もともとデプロイしていたアプリケーションの IP を確認すると IPv6 でアクセスされていることが確認できます。
次に作成したロードバランサにアクセスして IPv4 でアクセスされていることを確認します。
GAE へアクセスされている IP を調べるために追加したエンドポイントを叩いて X-Appengine-User-Ip
の値を確認すると、固定 IP となっているかと思います。
おわりに
クライアントが IPv6 でアクセスしてきたとしても、 GAE には IPv4 でアクセスできていることが確認できたと思います。
GAE では自動で IPv6 に対応するため、 IPv4 の固定 IP で IP 制限が必要な場合は今回紹介した方法で試してみてください。
この後 DNS の設定や SSL の設定をすることで実用化できると思いますが、今回は省略します。
できれば余裕があるときに追記していけたらと思います。
参考
- Google App Engineのアプリは自動的にIPv6対応に - Publickey
- NEG とは何か. はじめに | by Yuki Furuyama | google-cloud-jp | Medium
- Google Cloud Serverless NEG | google-cloud-jp
- サーバーレス NEG の設定 | 負荷分散 | Google Cloud
- NEG(Network Endpoint Group)を使った負荷分散 - Carpe Diem
- Serverless NEG + GAE を試してみる | apps-gcp.com
- Serverless NEG(Network Endpoint Group)を設定しGAEと連携してみた - Qiita
Discussion