【Google Cloud】IAP×Cloud Load BalancingでWebアプリケーションを保護して公開しよう!
こんにちは。エヌデーデーの金子です。
皆様、開発環境のWebアプリケーションをインターネットから動かしたい時、ございませんでしょうか?
VM単体で動くミニマムなアプリであれば、インスタンスに外部IPを振って公開するのがお手軽です。
ですがクラウド上のインスタンスを外部公開してしまうと、大きなセキュリティリスクを生みます。
そこで便利なのがGoogle Cloudのリバースプロキシサービス、IAP(Identity-Aware Proxy)です。
IAPを適用することで、許可したGoogleアカウントのみ接続を許可するなんて設定が可能になります。
フルマネージドであるため構築・運用の手間が無く、基本機能は無料で使うことが出来ます。
今回はCompute Engineで動くWebアプリを、IAPで保護したうえで公開する方法をご紹介したいと思います。
構成
Compute EngineでIAPを有効にするには、ロードバランサが少なくとも1つ必要です。
ロードバランサに外部IPを振って公開し、VMは内部サブネットの中に閉じ込めます。
ユーザはインターネット経由(HTTPS)で外部公開したロードバランサにアクセスすると 、Googleアカウント認証が入ります。
使用想定されるユーザに適切なロールを割り当てておく事で、外部公開していないVMインスタンスにアクセス可能という構成です。
手順
事前準備
ドメインと外部IPアドレスを取得し、Cloud DNSで紐づけ
ロードバランサを外部公開するにあたって、外部IPアドレスとドメインが必要です。
どちらもGoogleのサービスで取得可能なので、先に取っておきます。
新しい静的外部 IP アドレスを予約する
ドメインを設定して登録する
※Cloud Domainsは2023年内にGoogleとしてのサービスを終了し、他の会社へ移管する予定なので、別のドメイン登録サービスの使用をおススメします。
ドメインと外部IPアドレスを取得したら、Cloud DNSでAレコードを作成します。
この記事ではドメイン:test.com IPアドレス:11.11.111.111 で設定している、と仮定します。
この作業を事前に行っておく事で、後述するロードバランサにSSL証明書を入れる作業がスムーズにいきます。
内部サブネットを作成
次にVMインスタンスとロードバランサを囲う専用サブネットを作成します。
既存のVPCネットワークと重複しないIP範囲を指定しましょう。
IP範囲は111.111.0.0/26を設定した、とします。
※外部HTTP(S)ロードバランサに設定するIP範囲に制限があるようで、プレフィックスは/26 以下を設定する必要があります。
ポイントは「限定公開のGoogleアクセス」を有効にすることです。
これを行うことで外部IPアドレスを持たないインスタンスでも、インターネットを介さずGoogleのサービスにアクセスすることが出来ます。
Compute EngineにVMインスタンスを作成
内部から構成していきたいので、Compute EngineにVMを作ります。
マシンタイプやブートディスクの設定は適切なものを選んでいきます。
ネットワークインタフェースでは、【 内部サブネットを作成】の項で設定した専用サブネットを指定します。
VMが出来たら、Webアプリケーションサーバ(※今回はTomcatを使用)やデータベースのインストールなど、サーバ内の設定を行っていきます。
この時VMからインターネットに繋げるとツールインストールが便利なので、一時的に外部IPアドレスを振ってFWルールを通しておくと良いかもしれません。
※最終的には内部サブネットに閉じ込めるので、VMの外部IPアドレスは外しておきます。
外部HTTP(S)ロードバランサを作成
Compute Engineの設定が終わったら、ロードバランサを構成していきます。
HTTP(S)ロードバランシングを選択し、接続とモードを設定します。
インターネットから接続するので「インターネットからVMまたはサーバレスサービスへ」、運用モードは適切なものを選択します。
今回は「グローバル外部アプリケーションロードバランサ」を選択しましたが、使わない機能が多いと感じたので開発環境であれば「従来のアプリケーションロードバランサ」で充足かな、と思います。
また、「従来の~」で作成するとフロントエンドの構成にてHTTPSリダイレクトを設定する事ができるようです。「グローバル外部」だとこの設定が出来ないので、HTTPのアクセスを許可しない形で対応しました。
フロントエンドを構成
フロントエンドにはHTTPSを設定します。
IPアドレスには【ドメインと外部IPアドレスを取得し、Cloud DNSで紐づけ】の項で取得した外部IPアドレスを設定します。
HTTPSを利用するにはSSLサーバ証明書が必要ですが、ロードバランサではGoogleマネージド証明書が使用できます。 【ドメインと外部IPアドレスを取得し、Cloud DNSで紐づけ】 の項で取得したドメインを指定し、ワンクリックで作成可能です。
※ここで存在しないドメインを指定すると、証明書発行のための審査がいつまで経っても終わらないので、ドメインは事前取得をおススメします。
証明書の状態はCertificate Managerから確認できます。ACTIVEになるまで多少時間がかかるケースもあるようなので、気長に待ちます。
証明書が有効になったら、フロントエンドの構成は終了です!
HTTPSリダイレクトを設定する場合は、HTTPの構成も追加します。
バックエンドを構成
次にバックエンドですが、これを構成するにはバックエンドサービスが必要です。
単体のVMを指定することは出来ないようです。
バックエンドサービスを作成するには、以下のバックエンドタイプの選択が必要になります。
今回は内部サブネットのVMインスタンスがエンドポイントとなるので、ゾーンNEGを選択し、作成します。
Compute Engineからネットワークエンドポイントグループ( NEG )を作成していきます。
サブネットには事前に作成したものを設定し、デフォルトポートには今回アプリケーションサーバとして使用するTomcatのデフォルト8080を設定します。
NEGを作成したらネットワークエンドポイントとしてVMインスタンスを追加します。
IPアドレスには、VMに振られた内部IPアドレス(サブネットで設定したIP範囲内)を設定します。
ここまで終えたら、ロードバランサのバックエンドサービス作成に戻ります。
「バックエンドタイプ」でゾーンNEGを指定し、「バックエンド」に作成したNEGを指定します。専用サブネット内の内部通信であるため、 プロトコルは HTTPで大丈夫です。
ヘルスチェックは必須なので適切なものを作成し、設定します。
VMの設定がうまくいっていれば、ヘルスチェックは成功する筈なのでステータスをチェックします。
以上で、バックエンドの構成が終了です!
ルーティングルールを構成
ロードバランサ構成の最後はルーティングルールの設定です。
といってもルーティングするバックエンドサービスは1つしかないので、単純です。
バックエンドサービスが複数ある場合は、適切なルーティングを構成します。
以上で、ロードバランサの構成が終了です。お疲れさまでした!
IAPを有効化し、ロールを設定
最後にIAPを設定し、外部アクセスから保護します。
「プロダクトとリソースの検索」でIdentity-Aware Proxyを検索し、APIを有効にします。
IAPの有効化は以下の手順で進めます。
- OAuth同意画面を構成
- OAuth認証情報の作成
- IAPアクセス権の設定
- IAPの有効化
認証情報まで作成したら、クライアントIDとシークレットが発行されます。
以下のコマンドを実行することで、ロードバランサのバックエンドサービスに対してIAPが有効になります。
gcloud compute backend-services update BACKEND_SERVICE_NAME
--iap=enabled,oauth2-client-id=ID,oauth2-client-secret=SECRET
--global
有効になったバックエンドサービスを選択し、アクセス許可するユーザを設定します。
※IAPを有効にするとデフォルトで継承されたIAM権限(Ownerなど)がついてきます。インターネット越しのリソースアクセスにはこれらとは別にIAPのロールが必要なので、注意してください。
プリンシパルの追加で許可したいユーザを入力し、ロールを付与します。アプリケーションにアクセス出来ればよいのであれば、IAP-secured Web App Userで充足かと思います。
ここまで終えたら、すべて設定完了です!
インターネット越しにドメイン名でアクセスして疎通確認を行ってみてください😎
まとめ
Webアプリケーションをアクセス保護した状態で公開できると、顧客に実際の画面を触ってもらう機会を提供できたり、 社内のセキュリティ環境に縛られることなく会社のマシン以外のデバイスから動作確認ができたりと、多くのメリットを享受することが出来ます。
この方式はVM自体は公開せず、秘匿されている状態であることもセキュリティの安心感が高いです。Google Cloudのサービスのみでこれだけお手軽に構築できてしまうので、クラウド上に開発用Webアプリの公開を検討している方は、是非試してみてはいかがでしょうか。