Access Context Manager と VPC Service Controls で特定IPアドレスからの API アクセスのみ許可してみた
実現したいこと
Google Cloud API へのアクセスは、IAM によりユーザやサービスアカウントによる制御が可能ですが、社内開発環境からのアクセスのみを許可し、それ以外からのアクセスは拒否するといったケースも多いと思います。
今回は以下の図のように、特定のプロジェクトの Cloud Storage に VPC Service Controls でサービス境界を設定し、Access Context Manager で設定したアクセスレベルをアタッチし、ローカル開発環境の特定の IP アドレスからの API アクセスのみを許可する構成の検証をしました。
VPC Service Controls と Access Context Manager
VPC Service Controls (VPC-SC) は Google Cloud への API アクセスを制御し、リソース公開対象を厳密に設定することによりデータ漏洩等のリスク軽減に寄与することができるサービスです。
Google Cloud プロジェクト内で サービス境界 という API アクセスを制御するための境界を設定し、サービス境界内の通信を許可、サービス境界外からの通信は「特定ユーザや特定アドレス」からのみ許可し、それ以外は拒否といったコントロールが可能です。
この、「特定ユーザや特定アドレス」といったルールの定義を Access Context Manager の アクセスポリシー と アクセスレベル で行います。
先ほどの図のように Access Context Manager のアクセスポリシーを VPC-SC に適用し、アクセスポリシーに設定されたアクセスレベルを VPC-SC のサービス境界にアタッチできます。
少しややこしいのが、アクセスポリシーは組織レベルで1つだけ設定し、プロジェクト単位の VPC-SC に適用するには組織からプロジェクトやフォルダにアクセスポリシーを委任する(プロジェクトやフォルダ単位でスコープ指定されたアクセスポリシーを作成する)必要があります。
やってみた
本作業はプロジェクトレベルのオーナー権限で実施していますが、組織レベルでの権限付与も必要となりますのでこちらは後述します。
プロジェクト単位で VPC-SC を設定するには以下の作業が必要です。
- 組織レベルのアクセスポリシーを設定(未設定の場合)
- アクセスポリシーをプロジェクトに委任
- Access Context Manager でアクセスレベルを設定
- プロジェクトで VPC-SC を設定しアクセスレベルをアタッチ
1. 組織レベルのアクセスポリシーを設定(未設定の場合)
本作業を実施するためには組織リソースでの作業が必要となります。Access Context manager の設定のために以下の IAM ロールを付与します。
- Access Context Manager 管理者
roles/accesscontextmanager.policyAdmin
- 組織閲覧者
roles/resourcemanager.organizationViewer
組織レベルのアクセスポリシーは Cloud Console から設定できないため、 今回は Cloud Shell から gcloud コマンドで設定します。
一点注意です。gcloud access-context-manager
コマンドを使って設定していきますが、あるプロジェクト経由で gcloud コマンドを実行する必要があります。そのため、Cloud Shell のプロンプトにプロジェクト名が記載されていない場合(Cloud Console で組織リソースを開いている状態で Cloud Shell を起動したとき)は、以下コマンドでプロジェクトを指定してください。なおgcloud access-context-manager
コマンドを実行するプロジェクトで Access Context Manager API(accesscontextmanager.googleapis.com
)の有効化も必要となるため、Access Context Manager と VPC-SC を設定するプロジェクトを選択するのが良いでしょう。
$ gcloud config set project <PROJECT ID>
組織レベルのアクセスポリシーが設定されているかを確認します。組織レベルのアクセスポリシーは組織に対して1つしか設定できないため、既に設定されている場合は作成の手順は不要です。 Context Manager API が有効化されていない場合はコマンド実行時に有効化することも可能です。
$ gcloud access-context-manager policies list \
--organization <ORGANIZATION ID>
Listed 0 items.
以下コマンドで組織レベルのアクセスポリシーを作成します。今回は POLICY_NAME を org-default-policy
としました。
$ gcloud access-context-manager policies create \
--organization <ORGANIZATION_ID> --title <POLICY_TITLE>
$ gcloud access-context-manager policies list \
--organization <ORGANIZATION ID>
NAME: 519214720979
ORGANIZATION: <ORGANIZATION ID>
SCOPES:
TITLE: org-default-policy
ETAG: b6b0128265436ff9
ここからは Cloud Console で操作していきます。設定した組織レベルのアクセスポリシーを Cloud Console でも見てみます。
プロジェクトセレクタから組織リソースを選択し、[セキュリティ] -> [VPC Service Controls] を選択し、[ポリシーを管理する]をクリックします。(Access Context Manager API で設定したのに VPC Service Controls の項目で管理するのはややこしいですね)
先ほど設定した org-default-policy
が設定されていることがわかります。
本設定の詳細は以下をご参照ください。
2. アクセスポリシーをプロジェクトに委任
プロジェクト単位やフォルダ単位でアクセスポリシーを設定するために、組織リソースにてスコープ指定されたアクセスポリシーを作成します。これによりアクセス制御のためのポリシー管理をプロジェクトやフォルダなどのスコープ指定されたリソースに委任することができます。
先ほどの画面で [+作成] をクリックします。
アクセスポリシーのタイトル、アクセスポリシーのスコープに含めるプロジェクトやフォルダの追加、委任するアクセスポリシーの管理者と IAM ロールを設定します。少なくとも1人の Access Context Manager 管理者が必要となります。
設定後、[アクセスポリシーを設定] をクリックします。
本設定の詳細は以下をご参照ください。
3. Access Context Manager でアクセスレベルを設定
次に、特定の IP アドレスからのみアクセスを許可するルールを定義するアクセスレベルを Access Context Manager から設定していきます。
[セキュリティ] -> Access Context Manager を選択し、[+アクセスレベルを作成] をクリックします。
アクセスレベルのタイトルを設定し、条件を TRUE 、IP サブネットワークを CIDR表記 で指定して [保存] をクリックします。
作成したアクセスレベルが以下のように確認できます。
4. プロジェクトで VPC-SC を設定しアクセスレベルをアタッチ
今度はプロジェクトリソースで VPC-SC のサービス境界を設定します。サービス境界には、先ほど設定したアクセスレベルをアタッチし、特定の IP アドレスからの API アクセスだけを許可するようにします。
プロジェクトセレクタからプロジェクトを選択し、[セキュリティ] -> [VPC Service Controls] をクリックします。
[VPC Service Control ポリシー:] に先ほど組織から委任したアクセスポリシーが適用されていることがわかります。
[自動適用モード] の [+新しい境界] を設定します。
[詳細]では、境界のタイトルを設定し、境界のタイプを[標準境界(デフォルト)]にします。
[保護するリソース]では、[+ADD RESOURCES] をクリックし対象プロジェクトを選択します。
[制限付きサービス]では、[サービスを追加] からサービス境界に含める=アクセス制限したい API を選択します。今回は Cloud Storage API
のみを選択しました。
[VPC のアクセス可能なサービス]、[アクセスレベル] の設定はスキップし、[上り(内向き)ポリシー] を設定します。
設定は以下の通りとします。
- API クライアントの FROM 属性
- ID : 任意の ID
- ソース : アクセスレベル
- アクセスレベルを選択します : 作成したアクセスレベルを選択
- GCP サービス / リソースの TO 属性
- プロジェクト : Selected projects
- プロジェクト(ID または 番号)を追加 : プロジェクトを選択
- サービス : Selected Services
- 選択したサービス : Cloud Storage API
- メソッド : All methods
[下り(外向き)ポリシー] の設定もスキップし、[境界を作成] をクリックします。
以下のように作成されたサービス境界が確認できます。
本設定の詳細は以下をご参照ください。
では、動作確認をしてみます。ローカル開発環境から非公開の Google Cloud Storage バケットにアクセスしてみます。
$ gcloud auth login
$ gcloud config set project <PROJECT ID>
$ gsutil ls gs://<BUCKET NAME>
gs://<BUCKET NAME>/sensitive_data.txt
では、ローカル開発環境の IP アドレスを変更して再度アクセスしてみます。
gsutil ls gs://<BUCKET NAME>
AccessDeniedException: 403 Request is prohibited by organization's policy. vpcServiceControlsUniqueIdentifier: ASEKcK6iQYDCxqSnfQgXBFD9mIoKab6N3bdUQtu0tj1zUk92InBufsPCs3Scf-1W3XIhVuxZ8eUk20x3
VPC-SC によりアクセス拒否されたログが確認できました。
おわりに
社内のセキュリティ制限により、パブリッククラウドにアクセスする送信元 IP アドレスを制限するケースは非常に多いと思います。IAM による制御に加え Access Context Manager と VPC-SC を組み合わせることで、同一ユーザであっても社内開発環境以外からはアクセスさせないといった制限が可能となります。
しかし、Access Context Manager のアクセスポリシーやアクセスレベル、VPC-SC のサービス境界がどのように設定がリンクしているかわかりにくい部分もあるため本ブログを記載してみました。ご参考にしていただけると幸いです。