初めに
明けましておめでとうございます!Future筋肉エンジニアの渡邉です。年も明けたことなので切り替えて減量に入りました。三月末までを目安に体を絞ろうと思っています。
私は現在Google Cloudを利用しているプロジェクトに所属しており、Google Cloudのスキルアップにいそしんでいます。今回はGKE (Google Kubernetes Engine)でCloud IAP (Identity-Aware Proxy)を利用したWebアプリケーションのGoogleアカウント認証について記事を書こうと思います。
Identity-Aware Proxyとは
以下、公式ドキュメント引用
IAP を使用すると、HTTPS によってアクセスされるアプリケーションの一元的な承認レイヤを確立できるため、ネットワーク レベルのファイアウォールに頼らずに、アプリケーション レベルのアクセス制御モデルを使用できます。
簡単に言うとGoogleアカウントとCloud IAMの仕組みを用いてWebアプリケーションの認証をすることができます。
認証・承認フロー
![authenticate-flow.drawio.png](/images/20230113a/authenticate-flow.drawio.png)
公式ドキュメントはこちら
- Google Cloudリソースへのリクエスト(Cloud Load Balancing)します。
- IAPが有効になっている場合は、IAP認証サーバへ情報を送信します。(プロジェクト番号、リクエストURL、リクエストヘッダー、Cookie内のIAP認証情報など)
- IAP認証サーバがブラウザの認証情報をチェックします。
- 認証情報が存在しない場合は、OAuth2.0のGoogleアカウントログインフローにリダイレクトし、認証確認を実施する。認証トークンは今後のアクセスのためブラウザのCookieに保存されます。
- 認証情報が有効な場合、認証サーバは認証情報からユーザのID(メールアドレスとユーザID)を取得します。
- 認証サーバはこのIDからユーザのIAMロールをチェックし、ユーザがリソースにアクセスできる権限(IAP で保護されたウェブアプリ ユーザー)を持っているかをチェックします
- 権限を持っていれば、アクセスOKになり、なければNGになります。
全体アーキテクチャ図
以下が全体アーキテクチャ図になります。
GKE/NetworkなどのGoogle Cloudのリソース構築に関しては慣れ親しんでいるTerraformを利用して作成しました。OAuth同意画面に関しては外部公開する場合は、APIから作成することはできない (公式ドキュメント記載)ので、コンソール画面から設定しました。
![architecture.drawio.png](/images/20230113a/architecture.drawio.png)
Bastion初期設定
Public Subnetに作成したGCEインスタンスからGKEのコントロールプレーンに対してkubectlコマンドを実行したいので、
kubectlコマンドや、google-cloud-sdk-gke-gcloud-auth-pluginなどをインストールします。
以下、Bashスクリプトです。
|
manifestファイル
また、manifestファイルは以下を用意してkubectlコマンドを実行しk8sリソースをGKEに対して作成しました。
ここまでの設定で事前準備は完了です。
Deployment
NginxのPodを用意するため、Deploymentのmanifestを作成しました。
apiVersion: apps/v1 |
Service
IngressにはNodePortが必要になるので、Serviceのmanifestを作成しました。
apiVersion: v1 |
ManagedCertificate
クライアントとIngressで構築するHTTP(S)ロードバランサ間をHTTPSでアクセスするようにしたいので、Googleマネージド証明書のmanifestを作成しました。
domainsには、terraformで用意したHTTP(S)ロードバランサに設定したい外部IPアドレスにフリーなワイルドカードDNSサービスのnip.ioを利用したものを設定します。
apiVersion: networking.gke.io/v1 |
Ingress
インターネット上にNginxを公開するためにIngressを構築するmanifestを作成しました。
apiVersion: networking.k8s.io/v1 |
Cloud IAPなしでのアクセス確認
まず、Cloud IAPなしでのアクセス確認を行います。
Load Balancerに設定したドメインに対してアクセスを行うと、特に認証画面を経由することもなくアクセスすることができます。
Cloud IAPの設定を追加
上記の状態ではだれでもアクセスすることが可能なため、セキュアな状態ではありません。
ここでCloud IAPの設定を追加してみましょう。
OAuth同意画面の作成
OAuth同意画面はUser Typeを「外部」で作成します。
アプリ情報として、必須項目の以下を設定して「保存して次へ」をクリックします。
ほかの情報は任意のため設定しませんでした。
- アプリ名:GKE Application
- ユーザサポートメール:自身のメールアドレス
- デベロッパーの連絡先情報:自身のメールアドレス
![2-OAuth同意画面②.png](/images/20230113a/2-OAuth同意画面②.png)
![2-OAuth同意画面③.png](/images/20230113a/2-OAuth同意画面③.png)
スコープとテストユーザは任意情報のため設定しませんでした。
以下が設定完了したOAuth同意画面になります。
![2-OAuth同意画面④.png](/images/20230113a/2-OAuth同意画面④.png)
OAuth認証情報の作成
APIとサービスタブの「認証情報」をクリックします。
認証情報の作成プルダウンリストからOAuthクライアントIDをクリックします。
![3-OAuth認証情報①.png](/images/20230113a/3-OAuth認証情報①.png)
- アプリケーションの種類:ウェブアプリケーション
- OAuthクライアントIDの名前:GKE Application
を入力し、作成ボタンをクリックします。
![3-OAuth認証情報②.png](/images/20230113a/3-OAuth認証情報②.png)
作成ボタンをクリックするとOAuthクライアントIDとクライアントシークレットが生成されるので、JSONをダウンロードします。
![3-OAuth認証情報③.png](/images/20230113a/3-OAuth認証情報③.png)
作成したOAuthクライアントを再度クリックし、承認済みリダイレクトURIをダウンロードしたOAuthクライアントID(CLIENT_ID)に修正して保存します。
https://iap.googleapis.com/v1/oauth/clientIds/CLIENT_ID:handleRedirect |
![3-OAuth認証情報④.png](/images/20230113a/3-OAuth認証情報④.png)
IAPアクセス権の設定
Google Cloud ConsoleのIdentity-Aware Proxyにアクセスします。
アクセス権を付与するリソースの横にあるチェックボックスをオンにします。
![4-CloudIAPアクセス権設定①.png](/images/20230113a/4-CloudIAPアクセス権設定①.png)
IAPの有効化で「構成要件」を参照し、問題なければ「有効にする」をクリックします。
チェックボックスが「オン」になりました
右側のパネルから、「プリンシパルの追加」をクリックします。
IAPアクセスを許可したいGoogleアカウント(メールアドレス)または、Googleグループなどを指定して、IAMロール(IAP-secured Web App User)を付与してください。
![4-CloudIAPアクセス権設定④.png](/images/20230113a/4-CloudIAPアクセス権設定④.png)
ここまででOAuthの設定は完了です。
Kubernetes Secretの作成
GKEでCloud IAPを適用するためには、Kubernetes Secretを作成してBackendConfigに適用する必要があります。
先ほど作成してダウンロードしたOAuth認証情報のClient IDとClient Secretを指定してKubernetes Secretを作成します。
kubectl create secret generic oauth-secret --from-literal=client_id=xxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com \ |
Kubernetes Secretが作成されていることを確認します。
xxxxxxxxxxxxx@tky-bastion:~$ kubectl describe secret oauth-secret |
BackendConfigの作成
Kubernetes Secretで作成したSecretをBackendConfigに設定することでCloud IAPを適用することができます。
以下のmanifestファイルを用意します。
apiVersion: cloud.google.com/v1 |
kubectlコマンドでBackendConfigを作成します。
kubectl apply -f backendconfig.yaml |
BackendConfigが作成されていることを確認します。
xxxxxxxxxxxxx@tky-bastion:~/manifest$ kubectl get backendconfig |
サービスポートを BackendConfig に関連付けて、IAP の有効化をトリガーする必要があります。既存のService リソースにアノテーションを追加し、サービスのすべてのポートをデフォルトで BackendConfig にします。
apiVersion: v1 |
kubectl apply -f service.yaml |
以上で、Cloud IAPの設定は完了です。
Cloud IAPありでのアクセス確認
Cloud IAPの設定が完了したので、画面にアクセスしてCloud IAPが適用されているかを確認します。
Cloud IAP認証対象外アカウントでのアクセス確認
Load Balancerに設定したドメインに対してアクセスを行うと、Cloud IAPによるGoogleアカウントログイン画面にリダイレクトされます。
![5-IAPアクセスなし①.png](/images/20230113a/5-IAPアクセスなし①.png)
本GoogleアカウントはCloud IAPのアクセスできる権限(IAP で保護されたウェブアプリ ユーザー)を持っていないため、画面にアクセスすることはできません。
Cloud IAP認証対象アカウントでのアクセス確認
Load Balancerに設定したドメインに対してアクセスを行うと、Cloud IAPによるGoogleアカウントログイン画面にリダイレクトされます。
![6-IAPアクセスあり①.png](/images/20230113a/6-IAPアクセスあり①.png)
本GoogleアカウントはCloud IAPのアクセスできる権限(IAP で保護されたウェブアプリ ユーザー)を持っているため、画面にアクセスすることができました。
最後に
今回はGKE (Google Kubernetes Engine)でCloud IAP (Identity-Aware Proxy)を利用したGoogleアカウント認証について記事を書きました。
Google Cloudを利用していて、特定のGoogleアカウントにのみアクセスを許可したいケースはあるかと思いますので、その時にでも参考にしていただければ幸いです。