【GCPでセキュリティの柱を築く】VPC Service Controlsをデバッグし許可内容を定義する
こんにちは。クラウドアーキテクトの山下です。
今回はVPC Service Controlsのドライランモードとデバッグ方法について紹介していきます。
VPC Service Controlsはそのシンプルさのトレードオフとして境界外との通信を簡単に全遮断と出来てしまうデメリットもあります。そのため、コンソールを操作したり外部のSaaSや境界外部のGoogleCloudサービスとの通信が行えず、運用に支障、最悪の場合システム停止に繋がってしまいかねません。
これを未然に防ぎつつ、最小の許可設定でアクセスさせるための構成を考えるので役に立つのがドライランモードとトラブルシューティングです。この機能を使う事でVPC Service Controlsのデメリットを抑える事が可能です。
DryRunモードとデバッグ方法
前提
-
VPC Service Controlsは組織レベルの設定のため組織スコープでVPC Service Controlsの操作権限を有している方で実施する必要があります。
-
VPC Service Controlsを事前にドライランモードで作成する必要があります。
※一度、自動適用モードで作成してしまうと後からドライランモードに戻す事が出来ないので注意
ドライランモードでの作成
- VPC Service Controlsでドライランモードを選び、新しい境界を選択し境界を設定していきます。
境界を設定した上で定常運用、想定される操作を一通り実施する
ドライランモードは疑似的な境界を作成していて、実際の境界で発生するアクセス拒否が裏で実行されています。そのため、運用の中で発生する操作を一通り実施する事で境界が適切に設定されているのかを試験する事が出来ます。
境界のデバッグを行う
境界を作成して一定期間経過したら、VPC Service Controlsの画面内の監査ログを選択します。
ポップアップが表示され、確認を選択します。メッセージに記載の通り、dryRun=trueとなる境界のログを検索します。
この操作によって、Cloud Loggingのログエクスプローラーに遷移します。
ここで境界に関わるログを確認することができますが、このままでは得体情報が得られません。というのも、範囲が組織となっており境界を構成するプロジェクトではないためです。
この時にクエリ画面に表示された以下のクエリを控えて、境界に設定したプロジェクトでログエクスプローラーの画面に行きます。そこでまた、同じクエリ文をペーストしクエリを実行します。
resource.type="audited_resource" severity="ERROR" protoPayload.metadata.dryRun=true
直近の1時間程度しか結果が出ないため、操作を行なった日時を含むよう範囲を設定します。エラーが発生している場合、以下のようなエラーログが一覧表示されます。
ログの中から一つ選択し、エラーメッセージのJSONフィールドについて確認していきます。
protoPayload: {}内のmetadata: {}に含まれるviolationReason:が違反している内容を示しています。ログの内容を読み取って違反内容の詳細を割り出すこともできなくはないのでですが、これだけでは若干分かりにくいです。
原因を簡潔に確認できるトラブルシュートを行うために”vpcServiceControlsUniqueId:”に表示された長い文字列をここでは控えます。
値をクリックすると以下のようなメニューが表示されるので値をコピーを選択します。
境界内外への通信エラー内容を確認する
再び組織のVPC Service Controlsに移動し、今度はメニューのトラブルシューティングを選択します。
そこで以下のような画面が表示されるため、一意の識別子の入力欄に控えたvpcServiceControlsUniqueId:の値をペーストし、トラブルシューティングをクリックします。
以下のようにエラー内容の詳細が表示されます。
この中の違反内容の中身を見ていきます。違反の内容としては以下の内容となります。
違反の理由 | 違反内容の概要 |
---|---|
リクエストの属性 | |
(プリンシパル) | “誰が”アクセスしてきているのか |
※Googleアカウント/グループ,ServiceAccountのどれか | |
リクエストの属性 | |
(IPアドレス) | “どこから”アクセスしてきているのか |
対象のリソース | “どのAPIに対して”アクセスしているのか |
今回のケースでは以下の図のようにプロジェクトBなどの境界外部のServiceAccount(=プリンシパル)が、許可されていないアドレスから(=どこから)IAMサービスのAPIに対して(=どのAPIに対して)アクセスを試みているために拒否されているのが分かりました。
エラーのサンプルとデバッグ
他にもGoogleドキュメントでは以下のようなトラブルシューティングのサンプルが提供されています。エラーログに表示されたViolationReasonから対象となっているエラーを以下のドキュメントから探し概要をまずは把握しましょう。
その上で、違反内容の”誰が”、”どこから”、”どのAPIに対して”通信しているのかをトラブルシューティングやログから判断しましょう。
一見複雑ですが、実態はシンプルです。以下の観点で違反内容を特定していきましょう。
- 境界に対するIngress(内向き)なのかEgress(外向き)なのか
- 送信元は誰なのか(Googleアカウント/グループ、ServiceAccount)
- 送信元アドレスは何なのか(IPアドレス)
- 送信先APIは何なのか(Compute,IAM…などAPI全般)
デバッグから許可を追加する
さきほどのサンプルを基に許可の方法を定義していきます。
今回は、境界外部のServiceAccount(=プリンシパル)が、許可されていないアドレスから(=どこから)IAMサービスのAPIに対して(=どのAPIに対して)アクセスを試みているために拒否されていました。
許可する方法は大きく3つあります。これら全てではなく、ユースケースに合わせてどれかを選択します。
1.制限付きサービスから対象のAPIを外す
一番極端ですが、対象のAPIだけを境界から外しアクセス自由にする方法です。これにより、境界から外され全公開となるため拒否されなくなります。
今回の場合はIAM APIを保護するサービスから削除します。
不特定多数からアクセスを受け入れるようなユースケースがあり、ネットワークではなく認証認可でのみ制御をかける場合に有用な方法です。しかし、セキュリティレベルは下がるため余程の事情がない限りはあまりお勧めできません。
2.アクセスレベルに追加する
IPアドレスや地域など特定の条件を満たした場合にアクセスを許可するやり方です。AccessContextManagerであらかじめアクセス条件を作成する必要があります。違反の理由の”どこから”を解消する方法です。
特定のアドレスからしかアクセスしないことが分かっているような場合には有用です。例えば、特定の端末やネットワークに属する機器からしかアクセスさせたくない場合には有用です。マネジメントコンソールだけではなく、プロジェクトへのアクセスもさらに制限することができます。
ただし、アクセス元のアドレスが一定でないようなケースでは意図せず拒否となってしまうため注意です。
3.Ingress通信で許可を加える
From属性にアクセスする特定のプリンシパル(=”誰が”)を設定し、To属性に特定のプロジェクトの特定のサービス(=”どのAPIに対して”)の設定を行えます。さらにAPIに対しての操作も細かく設定できます。
別のGoogleCloudプロジェクトからアクセスされるような場合にはIPアドレスを確定できないのでこの設定方法が有用です。プロジェクトにアクセスするGoogleアカウント/グループをIPアドレスで制限できない場合もこちらで設定が行えます。ただし、プリンシパル(=”誰が”)までしか制限できないため、より細く制限したい場合はソース欄でアクセス元(=”どこから”)を制限することも出来ます。
DryRunから適用へ
デバッグと許可を追加して通信上問題がないと判断出来たらいよいよ適用に移ります。VPC Service Controlsの境界を選択し、ドライラン構成の適用を選択します。すると、境界はドライランから適用済みに変化し実際に通信制限が行われるようになります。
適用された後もドライラン構成も残り続けます。そして、裏では引き続きエラーログが集められています。適用後に何か問題があった場合は、同様のやり方でデバッグと許可設定を追加していきましょう。
Discussion