本文の内容は、2022年9月27日にAlejandro Villanuevaが投稿したブログ(https://sysdig.com/blog/gcp-security-best-practices/)を元に日本語に翻訳・再構成した内容となっております。
解決すべき問題があり、Google Cloud Platformを利用し、GCPセキュリティのベストプラクティスに従って、ソリューションを構築し、ホストすることにした、とします。その場合、アカウントを作成し、コーヒーを淹れてワークステーションに座り、設計、コーディング、ビルド、デプロイを行う準備は万端だ、と思うでしょう。ただし…そうではありません。
もし、運用性、安全性、信頼性、パフォーマンス、そしてコスト効率に優れたソリューションを望むなら、あなたが調整しなければならないツマミや、実行に移すべきプラクティスがたくさんあるのです。まず第一に、これを行うのに最適なタイミングは、設計やエンジニアリングを始める前の、まさに今です。
Google Cloud Platform 責任共有モデル
Google Cloud の製品およびサービスの範囲は、従来の IaaS(Infrastructure as a Service)から PaaS(Platform as a Service)、SaaS(Software as a Service)まで多岐にわたります。図に示すように、ユーザーとクラウド事業者の間の従来の責任分界は、選択するサービスによって変化します。少なくとも、セキュリティに対する共通の責任として、パブリッククラウドプロバイダーは、強固で安全な基盤を提供できるようにする必要があります。また、プロバイダーは、ユーザー自身が責任共有モデルの一部を理解し、実行できるよう支援する必要があります。

始める前に、Google Cloud Platformセキュリティのベストプラクティスの初期設定を行いましょう
まず、注意事項です:コーポレートアカウント以外は絶対に使用しないでください。
その代わりに、完全に管理されたコーポレート Googleアカウントを使用して、Cloud Platformリソースへのアクセスの可視性、監査、および制御を向上させます。個人アカウントなど、組織外のメールアカウントを業務で使用しないでください。
Cloud Identity はスタンドアロンの Identity-as-a-Service (IDaaS) であり、Google Cloud ユーザーは Google Workspace が提供する多くの ID 管理機能にアクセスできます。Google Workspaceは、Googleが提供する安全なクラウドネイティブコラボレーションおよび生産性アプリケーションのスイートです。クラウドアイデンティティ管理レイヤーを通じて、Google Cloud Platform(GCP)を含む組織のメンバーに対して、さまざまなGoogleソリューションへのアクセスを有効または無効にすることができます。
また、Cloud Identityにサインアップすると、ドメインの組織ノードが作成されます。これにより、Google Cloud のリソース階層を通じて、企業の構造やコントロールを Google Cloud リソースにマッピングすることができます。
さて、多要素認証(MFA)を有効にすることは、最も重要なことです。セキュリティファーストの考え方を持ちたいなら、システムで作成するすべてのユーザーアカウントでこれを行い、特に管理者にとっては極めて重要です。MFAは、強力なパスワードとともに、ユーザーのアカウントを不正アクセスから保護するための最も効果的な方法です。
それでは、GCPセキュリティのベストプラクティスを掘り下げてみましょう。
Google Cloud Platformセキュリティベストプラクティス
このセクションでは、最も一般的なGCPサービスを順を追って説明し、それぞれに採用すべき2ダース(ここでは数十が好ましい)のベストプラクティスを提供します。Google Cloud Platformのセキュリティベストプラクティスをオープンソースで実現する – Cloud Custodianは、クラウドセキュリティポスチャー管理(CSPM)ツールです。CSPMツールは、クラウドの設定を評価し、よくある設定ミスを特定します。また、クラウドのログを監視して、脅威や設定の変更を検出します。
では、サービスごとに見ていきましょう。
High Risk
🟥🟥🟥 |
Medium Risk
🟨🟨 |
Low Risk
🟩 |
|
IAM | (2)全ユーザーのMFAを有効化
|
(1)IAMポリシーの確認
|
|
KMS | (5)一般に公開しない |
(6) KMSの暗号鍵のローテーション |
|
Cloud Storage | (7) 一般には公開しない |
(8)バケット単位でアクセス可能 |
|
VPC | (9)VPCのフローログを有効にする |
||
Compute Engine | (12)重要なVMはCSEKで暗号化 |
(10)ブロックプロジェクト全体のSSH鍵の有効化 (11)シリアルポートへの接続を有効にしない
|
|
GKE | (13)シークレットの暗号化を有効にする
|
||
Cloud Logging | (16) Cloud Audit Loggingが設定されていることを確認する
|
(17) sinkが設定されていること
|
|
Cloud SQL | (21) 一般に公開しない |
(20) すべての着信接続にSSLを有効化
|
|
BigQuery | (24) 一般には公開しない |
アイデンティティとアクセス管理(IAM)
GCP Identity and Access Management (IAM)は、クラウドリソースへの最小権限アクセス制御の実施を支援します。IAMを使用すると、リソースを使用するための認証(サインイン)および権限(パーミッション)を持つユーザーを制限できます。IAMのために実装したいGCPセキュリティのベストプラクティスをいくつか紹介します:
1.個人用メールアカウントのIAMポリシーを確認する🟨🟨
Google Cloud Platformのプロジェクトごとに、そのプロジェクトにアクセスを許可されているアカウントをリストアップします。gcloud projects get-iam-policy PROJECT_ID
また、各フォルダーで追加されたアカウントもリストアップします:
gcloud resource-manager folders get-iam-policy FOLDER_ID
そして、組織のIAMポリシーをリストアップします:
gcloud organizations get-iam-policy ORGANIZATION_ID
組織ドメイン外のメールアカウントには、IAMポリシーで許可を与えないようにします。これは、Googleが所有するサービスアカウントを除きます。
デフォルトでは、組織のドメイン外の電子メールアドレスはその Google Cloud デプロイメントにアクセスできませんが、Google Cloud Platform プロジェクト、フォルダー、または組織の IAM ポリシーに任意のユーザー電子メール アカウントを追加することが可能です。これを防ぐには、組織ポリシー内でドメイン制限付き共有を有効にします:
gcloud resource-manager org-policies allow --organization=ORGANIZATION_ID iam.allowedPolicyMemberDomains=DOMAIN_ID
以下は、個人アカウントの使用を検出するためのCloud Custodianルールです:
- name: personal-emails-used description: | Use corporate login credentials instead of personal accounts, such as Gmail accounts. resource: gcp.project filters: - type: iam-policy key: "bindings[*].members[]" op: contains-regex value: .+@(?!organization\.com|.+gserviceaccount\.com)(.+\.com)*
2.すべてのユーザーアカウントで MFA が有効になっていることを確認する🟥🟥🟥
多要素認証は、ユーザーを認証するために複数のメカニズムを必要とします。これにより、盗まれた資格情報や脆弱な資格情報を悪用する攻撃者からユーザー ログインが保護されます。デフォルトでは、多要素認証は設定されていません。Google Cloud Platform のプロジェクト、フォルダ、または組織ごとに、各アカウントの多要素認証が設定されていることを確認し、設定されていない場合は、設定します。
3.管理者アカウントのセキュリティ キーの強制を確認 🟥🟥🟥
組織管理者ロールを持つ GCP ユーザーは、組織内で最高レベルの特権を持ちます。これらのアカウントは、最強の二要素認証で保護する必要があります。Security Key Enforcement(セキュリティキーの強制)。管理者は、SMSやワンタイムパスワード(OTP)などの弱い二要素ではなく、セキュリティキーを使用してログインするようにします。セキュリティキーは、Google組織の管理者アカウントにアクセスするために使用される実際の物理的なキーです。コードではなく、暗号化された署名を送信するため、ログインが偽造されることはありません。
組織管理者権限を持つユーザーを特定する:
gcloud organizations get-iam-policy ORGANIZATION_ID
ロール “roles/resourcemanager.organizationAdmin” を与えられたメンバーを探し、各アカウントでSecurity Key Enforcementが有効になっていることを手動で確認します。有効になっていない場合は、深刻に考えてすぐに有効にしてください。デフォルトでは、組織管理者は Security Key Enforcement が有効になっていません。
組織管理者がセキュリティキーへのアクセスを失った場合、ユーザーは自分のアカウントにアクセスできなくなる可能性があります。このため、バックアップのセキュリティキーを構成することが重要です。
4. user-managed service account キーの使用を防止する 🟨🟨
キーにアクセスできる人は、サービスアカウントを通じてリソースにアクセスできます。GCP 管理下のキーは、App Engine や Compute Engine などの Cloud Platform サービスで使用されます。これらのキーはダウンロードすることができません。Googleがキーを保持し、ほぼ毎週自動的にローテーションします。一方、user-managed キーは、ユーザーが作成、ダウンロード、管理するもので、有効期限は作成後10年です。
user-managed キーは、ソースコードで公開したり、ダウンロード・ディレクトリに残したり、サポートブログやチャンネルで誤って公開するなど、一般的な開発手法によって容易に漏洩する可能性があります。
すべてのサービスアカウントをリストアップしましょう:
gcloud iam service-accounts list
ユーザが管理するサービスアカウントを特定するために、そのようなアカウントの電子メールの末尾が以下のようになっています。
iam.gserviceaccount.com
.各ユーザーが管理するサービスアカウントについて、そのユーザーが管理するキーの一覧を表示します:
gcloud iam service-accounts keys list --iam-account=SERVICE_ACCOUNT --managed-by=user
キーはリストアップされないはずです。リストに表示されるキーがあれば、削除してください:
gcloud iam service-accounts keys delete --iam-account=SERVICE_ACCOUNT KEY_ID
ユーザーが管理するサービスアカウントのキーを削除すると、対応するキーを使用しているアプリケーションとの通信が切断されることがありますので、ご注意ください。
予防策として、サービスアカウントのキー作成も無効にしておくとよいでしょう。
その他、GCPセキュリティIAMのベストプラクティスは以下の通りです:
- サービスアカウントにAdmin権限を持たせないようにします。
- IAMユーザーには、プロジェクトレベルでService Account User または Service Account Token Creator のロールを割り当ててはなりません。
- サービスアカウント用の User-managed/ external キー(許可されている場合、#4参照)は、90日以内ごとにローテーションされるべきです。
- サービスアカウントに関連する役割をユーザーに割り当てる際には、職務の分離を徹底します。
- KMS 関連の役割をユーザに割り当てる際は、職務の分離を徹底します。
- プロジェクトのためにAPIキーを作成すべきではありません。
- APIキーは、指定されたHostとAppのみが使用できるように制限されるべきです。
- APIキーは、アプリケーションがアクセスする必要のあるAPIのみに制限されるべきです。
- APIキーは、90日以内ごとにローテーションされるべきです。
キー管理サービス(KMS)
GCP Cloud Key Management Service(KMS)は、クラウドホスティングによるキー管理サービスで、onpremと同じようにクラウドサービスの対称および非対称の暗号鍵を管理することができます。AES 256、RSA 2048、RSA 3072、RSA 4096、EC P256、EC P384の暗号鍵の作成、使用、ローテーション、破棄を行うことができます。KMSのために絶対に実装したいGoogle Cloud Platformのセキュリティベストプラクティスをいくつか紹介します:
5. 匿名または公開でアクセス可能なクラウドKMSキーがないか確認する 🟥 🟥 🟥
allUsers
または allAuthenticatedUsers
に権限を付与することで、誰でもデータセットにアクセスできるようになります。機密データがその場所に保存されている場合、そのようなアクセスは好ましくないかもしれません。この場合、Cloud KMS暗号化キーへの匿名および/または公開アクセスが許可されていないことを確認します。デフォルトでは、Cloud KMSは
allUsers
や allAuthenticatedUsers
へのアクセスを許可していません。すべてのCloud KMSキーをリストアップします:
gcloud kms keys list --keyring=KEY_RING_NAME --location=global --format=json | jq '.[].name'
KMSキーのIAMポリシーバインディングを削除して、
allUsers
と allAuthenticatedUsers
へのアクセスを削除します:gcloud kms keys remove-iam-policy-binding KEY_NAME --keyring=KEY_RING_NAME --location=global --member=allUsers --role=ROLE gcloud kms keys remove-iam-policy-binding KEY_NAME --keyring=KEY_RING_NAME --location=global --member=allAuthenticatedUsers --role=ROLE
以下は、匿名または一般にアクセス可能なクラウドKMS鍵の存在を検出するためのCloud Custodian rule です:
- name: anonymously-or-publicly-accessible-cloud-kms-keys description: | It is recommended that the IAM policy on Cloud KMS cryptokeys should restrict anonymous and/or public access. resource: gcp.kms-cryptokey filters: - type: iam-policy key: "bindings[*].members[]" op: intersect value: ["allUsers", "allAuthenticatedUsers"]
6. KMS 暗号化キーが 90 日以内の期間でローテーションされるようにする 🟩
キーは、ローテーション期間を指定して作成することができます。これは、新しいキーのバージョンが自動的に生成されるまでの時間です。キーはデータのあるコーパスを保護するために使用されるので、ファイルの集まりは同じキーを使用して暗号化することができ、そのキーの復号化権を持つユーザーはこれらのファイルを復号化することができます。そのため、ローテーションの周期を特定の時間に設定する必要があります。GCPセキュリティのベストプラクティスは、このローテーション期間を90日以内に設定することです。
gcloud kms keys update new --keyring=KEY_RING --location=LOCATION --rotation-period=90d
デフォルトでは、KMS暗号化キーは90日ごとにローテーションされます。これを変更したことがなければ、問題ありません。
Cloud Storage
Google Cloud Storageでは、”バケット “と呼ばれるネームスペースに任意の量のデータを保存することができます。このバケットは、あなたのデータを手に入れようとする攻撃者にとって魅力的なターゲットなので、その保護には細心の注意を払う必要があります。以下は、GCPセキュリティのベストプラクティスの一部です:
7. Cloud Storageバケットが匿名または公開でアクセスできないようにする 🟥🟥🟥
匿名またはパブリックアクセスを許可すると、誰でもバケットのコンテンツにアクセスする許可が与えられます。機密データを保存している場合、このようなアクセスは好ましくないかもしれません。したがって、バケットへの匿名または公開アクセスが許可されていないことを確認します。プロジェクト内のすべての バケット をリストアップします:
gsutil ls
上記コマンドで返された各バケットの IAM ポリシーを確認します。
gsutil iam get gs://BUCKET_NAME
allUsers
または allAuthenticatedUsers
をメンバーとして含むロールは存在してはいけません。もしそうでない場合は、次のようにして削除してください:gsutil iam ch -d allUsers gs://BUCKET_NAME gsutil iam ch -d allAuthenticatedUsers gs://BUCKET_NAME
また、ドメイン制限付き共有組織ポリシーを設定することで、ストレージバケットが一般に公開されないようにしたい場合もあります。
8. Cloud Storageバケットでバケットレベルの統一アクセスが有効になっていることを確認する 🟨🟨
Cloud Storageは、バケットやオブジェクトへのアクセス許可をユーザーに付与するために、2つのシステムを提供しています。Cloud Identity and Access Management (Cloud IAM)とAccess Control Lists (ACL)です。これらのシステムは並行して動作します。ユーザーがクラウドストレージリソースにアクセスするためには、どちらかのシステムだけが権限を付与する必要があります。Cloud IAM は Google Cloud 全体で使用され、バケットとプロジェクト レベルで異なる権限を付与することができます。ACL は Cloud Storage でのみ使用され、権限のオプションは限られていますが、オブジェクト単位で権限を付与することができます(fine-grained)。
バケットレベルの統一アクセス機能を有効にすると、すべてのCloud Storageリソース(バケットとオブジェクト)でACLが無効になり、Cloud IAMを介した排他的アクセスが可能になります。
この機能は、Cloud Storageリソースへのアクセス権付与方法を集約・簡略化するためにも利用されます。
バケットレベルの統一的なアクセスを有効にすると、Storageバケットがパブリックにアクセスできない場合、バケット内のどのオブジェクトもパブリックにアクセスできないことが保証されます。
プロジェクト内のすべてのバケットをリストアップします:
gsutil ls
上記のコマンドで返された各バケットに対して、バケットレベルの統一的なアクセスが有効であることを確認します:
gsutil uniformbucketlevelaccess get gs://BUCKET_NAME/
バケットレベルの統一的なアクセスが有効になっている場合、以下のようなレスポンスが返されます:
Uniform bucket-level access setting for gs://BUCKET_NAME/: Enabled: True LockedTime: LOCK_DATE
バケツに対して有効になっていない場合は、次のようにして有効にできます:
gsutil uniformbucketlevelaccess set on gs://BUCKET_NAME/
また、Organization Policy を設定することで、新しいバケットにはバケットレベルの統一的なアクセスが有効であることを強制することができます。
これは、ユニフォームアクセスが有効になっていないバケットをチェックするための、Cloud Custodian ruleです:
- name: check-uniform-access-in-buckets description: | It is recommended that uniform bucket-level access is enabled on Cloud Storage buckets. resource: gcp.bucket filters: - not: - type: value key: "iamConfiguration.uniformBucketLevelAccess.enabled" value: true
Virtual Private Cloud (VPC)
Virtual Private Cloudは、クラウドベースのリソースやサービスに対して、グローバルでスケーラブルかつ柔軟なネットワーキングを提供します。App Engine、Compute Engine、Google Kubernetes Engine(GKE)にネットワーク機能を提供するため、セキュリティには十分な注意が必要です。これは、GCPセキュリティのベストプラクティスの1つです:
9. VPCサブネットのVPC Flow Logsを有効にする 🟨🟨
デフォルトでは、新しいVPCネットワーク サブネットが作成されると、VPC Flow Logs機能は無効化されます。VPCフローログを有効にすると、Virtual Private Cloud(VPC)サブネットとのネットワークトラフィックデータの収集が開始され、ネットワークの使用状況、ネットワークトラフィックコストの最適化、ネットワークのフォレンジック、リアルタイムのセキュリティ分析が可能になります。Google Cloud VPCネットワークの可視性とセキュリティを高めるために、ビジネスクリティカルまたはプロダクションVPCサブネットごとにFlow Logsを有効にすることを強くお勧めします。
gcloud compute networks subnets update SUBNET_NAME --region=REGION --enable-flow-logs
Compunte Engine
Compunte Engineは、Googleのインフラストラクチャー上で仮想マシンを作成し実行できる、セキュリティとカスタマイズ可能なコンピュートサービスを提供します。できるだけ早く実装すべきGCPセキュリティのベストプラクティスをいくつか紹介します。
10. VMインスタンスに対して “Block Project-wide SSH keys” が有効になっていることを確認する 🟨🟨
プロジェクト全体のSSHキーを使用して、GCPプロジェクト内で実行されているすべてのGoogle Cloud VMインスタンスにログインすることができます。プロジェクト全体でSSHキーを使用すると、SSHキーの管理が容易になりますが、漏洩した場合、プロジェクト内のすべてのVMインスタンスに影響を与えるセキュリティリスクとなります。そのため、特定のSSHキーを使用し、万が一漏洩した場合の攻撃対象を減らすことを強くお勧めします。デフォルトでは、Block Project-Wide SSH Keysセキュリティ機能は、Google Compute Engineインスタンスでは有効になっていません。
Block Project-Wide SSH Keys を使用するには、メタデータの値を TRUE に設定します:
gcloud compute instances add-metadata INSTANCE_NAME --metadata block-project-ssh-keys=true
以下は、このブロックがないインスタンスをチェックするためのCloud Custodianのサンプルルールです:
- name: instances-without-project-wide-ssh-keys-block description: | It is recommended to use Instance specific SSH key(s) instead of using common/shared project-wide SSH key(s) to access Instances. resource: gcp.instance filters: - not: - type: value key: name op: regex value: '(gke).+' - type: metadata key: '"block-project-ssh-keys"' value: "false"
11.VMインスタンスで “Enable connecting to serial ports” が有効になっていないことを確認する 🟨🟨
Google Cloud の仮想マシン(VM)インスタンスには、4 つの仮想シリアル ポートがあります。シリアルポートとのインタラクションは、入力と出力が完全にテキストモードである点でターミナルウィンドウの使用に似ており、グラフィカルインターフェースやマウスサポートはありません。インスタンスのオペレーティングシステム、BIOS、およびその他のシステムレベルのエンティティは、多くの場合、シリアルポートに出力を書き込み、コマンドやプロンプトへの応答などの入力を受け入れることができます。これらのシステムレベルのエンティティは、通常、最初のシリアルポート(ポート1)を使用し、これはしばしば対話型シリアルコンソールと呼ばれます。
対話型シリアルコンソールは、IPホワイトリストのようなIPベースのアクセス制限をサポートしません。インスタンスで対話型シリアルコンソールを有効にすると、クライアントは任意のIPアドレスから接続を試みることができます。これにより、正しいSSHキー、ユーザー名、プロジェクトID、ゾーン、インスタンス名を知っている人なら誰でもそのインスタンスに接続することができます。したがって、Google Cloud Platformのセキュリティベストプラクティスを遵守するために、対話型シリアルコンソールのサポートを無効にする必要があります。
gcloud compute instances add-metadata INSTANCE_NAME --zone=ZONE --metadata serial-port-enable=false
また、f
Disable VM serial port access organization policy
により、VMの対話型シリアルポートアクセスを有効にしないようにすることができます。12. 重要なVMのVMディスクがCSEK (Customer-Supplied Encryption Keys)で暗号化されているようにする🟥🟥🟥
デフォルトでは、Compute Engineサービスは、停止中において全データを暗号化します。クラウドサービスは、ユーザーまたはアプリケーションからの追加アクションなしで、このタイプの暗号化を管理します。しかし、インスタンスディスクの暗号化を完全に制御したい場合は、独自の暗号化キーを提供することができます。
これらのカスタムキーは、CSEK (Customer-Supplied Encryption Keys) とも呼ばれ、インスタンスデータの暗号化と復号化に使用されるGoogle生成のキーを保護するためにGoogle Compute Engineで使用されます。Compute Engine サービスは CSEK をサーバー上に保存しないため、必要なキーを指定しない限り保護されたデータにアクセスすることはできません。
少なくとも、ビジネスクリティカルなVMは、VMディスクをCSEKで暗号化する必要があります。
デフォルトでは、VMディスクはGoogleが管理するキーで暗号化されています。Customer-Supplied Encryption Keysでは暗号化されません。
現在、既存のディスクの暗号化を更新する方法はありませんので、
Encryption
を Customer supplied
に設定して新しいディスクを作成する必要があります。ここで注意しなければならないことがあります:⚠️ 暗号化キーを紛失した場合、データを復元することはできません。
gcloud compute toolで、インスタンス作成時に
--csek-key-file
フラグを使用してディスクを暗号化します。RSAでラップされたキーを使用する場合は、gcloud betaコンポーネントを使用します:gcloud beta compute instances create INSTANCE_NAME --csek-key-file=key-file.json
スタンドアロンの永続ディスクを暗号化するには、以下を使用します:
gcloud beta compute disks create DISK_NAME --csek-key-file=key-file.json
キーを生成し、管理するのはあなたの義務です。RFC4648標準のbase64でエンコードされた256bitの文字列であるキーをCompute Engineに提供する必要があります。
key-file.json
のサンプルは以下のようになります:[ { "uri": "https://www.googleapis.com/compute/v1/projects/myproject/zones/us- central1-a/disks/example-disk", "key": "acXTX3rxrKAFTF0tYVLvydU1riRZTvUNC4g5I11NY-c=", "key-type": "raw" }, { "uri": "https://www.googleapis.com/compute/v1/projects/myproject/global/snapshots/my -private-snapshot", "key": "ieCx/NcW06PcT7Ep1X6LUTc/hLvUDYyzSZPPVCVPTVEohpeHASqC8uw5TzyO9U+Fka9JFHz0mBib XUInrC/jEk014kCK/NPjYgEMOyssZ4ZINPKxlUh2zn1bV+MCaTICrdmuSBTWlUUiFoDD6PYznLwh8 ZNdaheCeZ8ewEXgFQ8V+sDroLaN3Xs3MDTXQEMMoNUXMCZEIpg9Vtp9x2oeQ5lAbtt7bYAAHf5l+g JWw3sUfs0/Glw5fpdjT8Uggrr+RMZezGrltJEF293rvTIjWOEB3z5OHyHwQkvdrPDFcTqsLfh+8Hr 8g+mf+7zVPEC8nEbqpdl3GPv3A7AwpFp7MA==" "key-type": "rsa-encrypted" } ]
その他、Compute EngineのGCPセキュリティベストプラクティスは以下の通りです:
- インスタンスがデフォルトのサービスアカウントを使用するように構成されていないことを確認します。
- インスタンスが、すべてのクラウドAPIにフルアクセスできるデフォルトのサービスアカウントを使用するように構成されていないことを確認します。
- プロジェクトで oslogin が有効になっていることを確認します。
- インスタンスで IP 転送が有効になっていないことを確認します。
- ComputeインスタンスがShielded VMを有効にして起動されていることを確認します。
- Compute インスタンスがパブリック IP アドレスを持っていないことを確認します。
- App Engine アプリケーションが HTTPS 接続を強制することを確認します。
Google Kubernetes Engine サービス (GKE)
Google Kubernetes Engine(GKE)は、Googleインフラストラクチャーを使用してコンテナ化されたアプリケーションをデプロイ、管理、スケーリングするためのマネージド環境を提供します。GKE環境は、複数のマシン(具体的には、Compute Engineインスタンス)がグループ化され、クラスターを形成しています。GCPセキュリティのベストプラクティスをGKEで続けていきましょう。13. GKEクラスターでアプリケーション層におけるシークレットの暗号化を有効にする 🟥🟥🟥
アプリケーション層におけるシークレットの暗号化は、etcd
に保存されたKubernetesのシークレットなどの機密データに対して追加のセキュリティ層を提供します。この機能により、Cloud KMS が管理する暗号化キーを使用してアプリケーション層でデータを暗号化し、 etcd
のオフライン コピーにアクセスする攻撃者からデータを保護することができます。GKEクラスターでアプリケーション層におけるシークレットの暗号化を有効にすることは、機密データを保存するアプリケーションにおけるセキュリティのベストプラクティスと考えられています。CMKを保存するためのキーホルダーを作成します:
gcloud kms keyrings create KEY_RING_NAME --location=REGION --project=PROJECT_NAME --format="table(name)"
ここで、前のステップで作成したKMSキーホルダー内に新しいCloud KMS Customer-Managed Key (CMK)を作成します:
gcloud kms keys create KEY_NAME --location=REGION --keyring=KEY_RING_NAME --purpose=encryption --protection-level=software --rotation-period=90d --format="table(name)"
そして最後に、適切なサービスアカウントにCloud KMS “CryptoKey Encrypter/Decrypter” ロールを割り当ててください:
gcloud projects add-iam-policy-binding PROJECT_ID --member=serviceAccount:service-PROJECT_NUMBER@container-engine-robot.iam.gserviceaccount.com --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
最後のステップは、前のステップで作成したCloud KMS Customer-Managed Key (CMK) を使って、選択したクラスターのアプリケーション層シークレットの暗号化を有効にすることです:
gcloud container clusters update CLUSTER --region=REGION --project=PROJECT_NAME --database-encryption-key=projects/PROJECT_NAME/locations/REGION/keyRings/KEY_RING_NAME/cryptoKeys/KEY_NAME
14. customer-managedキーによるGKEクラスターノード暗号化の有効化 🟥🟥🟥
GKEデータの暗号化/復号化プロセスをより詳細に制御するために、Google Kubernetes Engine(GKE)クラスターノードがcustomer-managed キー(CMK)で暗号化されていることを確認します。Cloud Key Management Service (Cloud KMS) を使用して、独自のcustomer-managed キー (CMK) を作成および管理することができます。Cloud KMSは、安全で効率的な暗号キー管理、制御されたキーローテーション、および失効メカニズムを提供します。この時点で、CMKやcustomer-managed キーを保管するキーホルダーを既にお持ちのはずです。ここでもそれらを使用することになります。
GKEクラスターノードの暗号化を有効にするには、ノードプールを再作成する必要があります。これには、識別子パラメーターとして再作成するクラスターノードプールの名前を使用し、カスタム出力フィルタリングを使用して、選択したノードプールで利用可能な構成情報を記述します。
gcloud container node-pools describe NODE_POOL --cluster=CLUSTER_NAME --region=REGION --format=json
ここで、前のステップで返された情報を使用して、customer-managed キー(CMK)で暗号化された新しいGoogle Cloud GKEクラスターノードプールを作成します:
gcloud beta container node-pools create NODE_POOL --cluster=CLUSTER_NAME --region=REGION --disk-type=pd-standard --disk-size=150 --boot-disk-kms-key=projects/PROJECT/locations/REGION/keyRings/KEY_RING_NAME/cryptoKeys/KEY_NAME
新しいクラスターノードプールが正常に機能したら、元のノードプールを削除して、Google Cloud アカウントへの請求の追加を停止できます。
⚠️新しいプールではなく、古いプールを削除するように十分注意してください!
gcloud container node-pools delete NODE_POOL --cluster=CLUSTER_NAME --region=REGION
15. GKEクラスターへのネットワークアクセスを制限する 🟥 🟥 🟥 🟥
インターネットへの露出を制限するために、Google Kubernetes Engine (GKE) クラスターが承認済みネットワークで構成されていることを確認します。承認済みネットワークでは、HTTPSを使用してクラスターマスターエンドポイントにアクセスするために、特定のIPアドレスやIPアドレス範囲をホワイトリスト化することができます。承認済みネットワークを追加すると、ネットワークレベルの保護とGKEクラスターにさらなるセキュリティの利点を提供することができます。承認済みネットワークは、安全なネットワークから発信されたものなど、特定の信頼できるIPアドレスのセットへのアクセスを許可します。これにより、クラスターの認証または承認メカニズムが脆弱な場合に GKE クラスターへのアクセスを保護できます。
選択したGKEクラスターに承認済みネットワークを追加して、定義した信頼できるIPアドレス/IP範囲からのクラスターマスタへのアクセスを許可します:
gcloud container clusters update CLUSTER_NAME --zone=REGION --enable-master-authorized-networks --master-authorized-networks=CIDR_1,CIDR_2,...
先ほどのコマンドでは、複数のCIDR(最大50)をカンマで区切って指定することができます。
上記は GKE の最も重要なベスト プラクティスです。これに従わないとリスクが高くなりますが、従う必要があるセキュリティのベスト プラクティスは他にもあります。
- GKEクラスターノードの自動修復を有効にする。
- GKEクラスターノードの自動アップグレードを有効にする。
- GKEクラスターノードの整合性監視を有効にする。
- GKEクラスターノードのセキュアブートを有効にする。
- シールドされたGKEクラスターノードを使用する。
Cloud Logging
Cloud Loggingは、Google CloudやAmazon Web Servicesのログデータやイベントを保存、検索、分析、監視、警告できるようにするフルマネージドサービスです。150以上の一般的なアプリケーションコンポーネント、オンプレミスシステム、ハイブリッドクラウドシステムからログデータを収集することができます。Cloud Loggingに焦点を当てたGCPセキュリティのベストプラクティスは、他にもあります。
16. プロジェクトからのすべてのサービスとすべてのユーザーに対して、Cloud Audit Loggingが適切に構成されていることを確認する 🟥🟥🟥
Cloud Audit Logging は、プロジェクト、フォルダー、組織ごとに 2 つの監査ログを維持します。管理者アクティビティとデータアクセス。管理者アクティビティログには、リソースの構成またはメタデータを変更するAPIコールまたは他の管理アクションのログエントリが含まれています。これらは、すべてのサービスに対して有効であり、設定することはできません。一方、データアクセス監査ログは、ユーザーが提供するデータを作成、変更、または読み取るAPIコールを記録します。これらはデフォルトでは無効になっており、有効にする必要があります。
ユーザーデータの変更(改ざん)だけでなく、ユーザー活動の追跡を記録できるように、効果的なデフォルトの監査設定を行うことが推奨されます。ログは、すべてのユーザーについて取得する必要があります。
このためには、プロジェクトのポリシーを編集する必要があります。まず、
yaml
ファイルとしてダウンロードします。gcloud projects get-iam-policy PROJECT_ID > /tmp/project_policy.yaml
ここで、
/tmp/project_policy.yaml
を編集して、監査ログ構成のみを次のように追加または変更します。auditConfigs: - auditLogConfigs: - logType: DATA_WRITE - logType: DATA_READ service: allServices
監査ロギングがすべてのユーザーに対して有効であるべきなので、
exemptedMembers
が設定されていないことに注意してください。最後に、新しい変更内容でポリシーを更新します:gcloud projects set-iam-policy PROJECT_ID /tmp/project_policy.yaml
⚠️データアクセスの監査ログを有効にすると、追加ログの使用料がプロジェクトに請求される場合があります。
17. すべてのログエントリーにsinksが設定されていることを確認します🟨🟨
また、すべてのログエントリのコピーをエクスポートするsinkを作成することをお勧めします。こうすることで、複数のプロジェクトからログを集約し、セキュリティ情報およびイベント管理(SIEM)にエクスポートすることができます。エクスポートには、エクスポートするログエントリーを選択するフィルタを作成し、Cloud Storage、BigQuery、またはCloud Pub/Subで宛先を選択する必要があります。フィルタとエクスポート先はsinkと呼ばれるオブジェクトに保持されます。すべてのログエントリーがsinkにエクスポートされるようにするには、フィルターが設定されていないことを確認します。
すべてのログエントリーをGoogle Cloud Storageバケットにエクスポートするsinkを作成するには、次のコマンドを実行します:
gcloud logging sinks create SINK_NAME storage.googleapis.com/BUCKET_NAME
これでバケットにイベントがエクスポートされますが、代わりにCloud Pub/SubやBigQueryを使用するとよいかもしれません。
これは、sinkがフィルタなしで構成されていることを確認するための、Cloud Custodian ルールの例です:
- name: check-no-filters-in-sinks description: | It is recommended to create a sink that will export copies of all the log entries. This can help aggregate logs from multiple projects and export them to a Security Information and Event Management (SIEM). resource: gcp.log-project-sink filters: - type: value key: filter value: empty
18. バケットロックを使用して、ログバケットの保持ポリシーが設定されていることを確認する 🟨🟨🟨
ログ バケットの保持ポリシーを有効にすると、クラウド ストレージ バケットに保存されたログが上書きされたり、誤って削除されたりするのを防ぐことができます。前のベスト プラクティスに従って、ログ sinkとして使用されるすべてのストレージ バケットに保持ポリシー を設定し、バケット ロックを構成することが推奨されます。ストレージバケット宛のすべてのsinkを一覧表示するには:
gcloud logging sinks list --project=PROJECT_ID
上記の各ストレージバケットについて、保持ポリシーを設定し、ロックします:
gsutil retention set TIME_DURATION gs://BUCKET_NAME gsutil retention lock gs://BUCKET_NAME
⚠️バケットロックは不可逆的な動作です。一度バケットをロックすると、そのバケットからリテンションポリシーを削除したり、リテンション期間を短くすることはできません。
19. customer-managedキーによるログ ルーターの暗号化を有効にする 🟥🟥🟥
Google Cloud Logs Router のデータが CMK (customer-managed key) で暗号化されていることを確認し、データの暗号化および復号化プロセスを完全に制御できるようにするとともに、コンプライアンス要件を満たすようにします。CMKのIAMポリシーにバインドするポリシーを追加して、必要なサービスアカウントにCloud KMS “CryptoKey Encrypter/Decrypter” ロールを割り当てたいと思います。ここでは、#13 で作成したキーリングと CMK を使用します。
gcloud kms keys add-iam-policy-binding KEY_ID --keyring=KEY_RING_NAME --location=global --member=serviceAccount:[email protected] --role=roles/cloudkms.cryptoKeyEncrypterDecrypter
Cloud SQL
Cloud SQLは、MySQL、PostgreSQL、SQL Server用のフルマネージドリレーショナルデータベースサービスです。豊富な拡張機能コレクション、設定フラグ、開発者エコシステムを備えた、ご存知のリレーショナルデータベースを、自己管理の煩わしさなしに実行できます。GCPセキュリティのベストプラクティスは、Cloud SQLにフォーカスしています:
20. Cloud SQLデータベースインスタンスが、すべての着信接続にSSLを使用するよう要求していることを確認する 🟨🟨
SQLデータベース接続は、盗聴されると認証情報、データベースクエリ、クエリ出力などの機密データを漏えいする可能性があります(MITM)。セキュリティ上の理由から、PostgreSQL、MySQL第1世代、およびMySQL第2世代のインスタンスに接続する際は、常にSSL暗号化を使用することをお勧めします。インスタンスにSSL暗号化を強制するには、コマンドを実行します:
gcloud sql instances patch INSTANCE_NAME --require-ssl
また、MySQL第1世代インスタンスは、この設定を有効にするために再起動する必要があります。
このCloud Custodian rule は、SSLが強制されていないインスタンスをチェックすることができます:
- name: cloud-sql-instances-without-ssl-required description: | It is recommended to enforce all incoming connections to SQL database instance to use SSL. resource: gcp.sql-instance filters: - not: - type: value key: "settings.ipConfiguration.requireSsl" value: true
21. クラウド SQL データベースインスタンスが世界中に公開されていないことを確認する 🟥🟥🟥
データベース サーバー インスタンスの攻撃対象領域を最小限に抑えるために、信頼できる/既知の必要な IP のみをホワイトリストに登録して接続する必要があります。 許可されたネットワークには、世界中のどこからでもインスタンスへのアクセスを許可する0.0.0.0/0
に構成された IP/ネットワークが含まれていてはなりません。 許可されたネットワークは、パブリック IP を持つインスタンスにのみ適用されることに注意してください。gcloud sql instances patch INSTANCE_NAME --authorized-networks=IP_ADDR1,IP_ADDR2...
新しいSQLインスタンスが任意のIPアドレスからの着信接続を受け入れるように設定されないようにするには、Restrict Authorized Networks on Cloud SQL instances Organization Policy(クラウドSQLインスタンスの許可されたネットワークを制限する)を設定します。
22. Cloud SQLデータベースインスタンスがパブリックIPを持たないようにする🟨🟨
組織の攻撃対象領域を減らすために、Cloud SQL データベースはパブリック IP を持たないようにします。プライベート IP は、ネットワーク セキュリティの向上とアプリケーションの低遅延を実現します。すべてのインスタンスについて、そのパブリックIPを削除し、代わりにプライベートIPを割り当てます:
gcloud beta sql instances patch INSTANCE_NAME --network=VPC_NETWORK_NAME --no-assign-ip
新しいSQLインスタンスがパブリックIPアドレスで構成されるのを防ぐには、Restrict Public IP access on Cloud SQL instances Organizationポリシーを設定します。
23. Cloud SQLデータベースインスタンスに自動バックアップが設定されていることを確認する 🟨🟨
バックアップは、失われたデータを取得したり、そのインスタンスの問題から回復するために、クラウド SQL インスタンスを復元する方法を提供します。自動バックアップは、損失や損傷から保護する必要があるデータを含むすべてのインスタンスに対して設定される必要があります。この推奨事項は、SQL Server、PostgreSql、MySql generation 1、およびMySql generation 2のインスタンスに適用されます。次のコマンドを使用して、すべてのクラウドSQLデータベースインスタンスをリストアップします:
gcloud sql instances list
すべてのクラウドSQLデータベースインスタンスの自動バックアップを有効にします:
gcloud sql instances patch INSTANCE_NAME --backup-start-time [HH:MM]
backup-start-timeパラメータは、UTC±00タイムゾーンで24時間単位で指定し、4時間のバックアップウィンドウの開始時刻を指定します。バックアップは、このバックアップウィンドウの間であればいつでも開始することができます。
デフォルトでは、Cloud SQLインスタンスに自動バックアップは設定されていません。自動バックアップが設定されていない限り、どのCloud SQLインスタンスでもデータのバックアップは不可能です。
他にもMySQL、PostgreSQL、SQL Serverに特化したCloud SQLのベストプラクティスがありますが、前述の4つが最も重要であることは間違いないでしょう。
BigQuery
BigQuery は、インメモリ BI エンジンと機械学習が組み込まれた、サーバーレスでかつ、スケーラブルで費用対効果の高いクラウド データ ウェアハウスです。他のセクションと同様に、GCP セキュリティのベスト プラクティスを挙げていきます。24.BigQueryのデータセットが匿名または公開でアクセスできないようにする 🟥🟥🟥
BigQueryデータセットのIAMポリシーで匿名アクセスやパブリックアクセスを許可しないようにします。allUsers
や allAuthenticatedUsers
に権限を付与すれば、誰でもデータセットにアクセスできるようになります。データセットに機密データが保存されている場合、このようなアクセスは好ましくないかもしれません。したがって、データセットへの匿名アクセスや公開アクセスは許可しないようにしましょう。そのためには、データセットの情報を編集する必要があります。まず、その情報をローカルのファイルシステムに取り込む必要があります:
bq show --format=prettyjson PROJECT_ID:DATASET_NAME > dataset_info.json
次に、
dataset_info.json
のアクセスセクションで、 allUsers
や allAuthenticatedUsers
を含むすべてのロールを削除するためにデータセット情報を更新してください。最後に、データセットを更新します:
bq update --source=dataset_info.json PROJECT_ID:DATASET_NAME
Domain restricted sharing organization policyを設定することで、BigQueryのデータセットが一般に公開されないようにすることができます。
コンプライアンス標準とベンチマーク
GCP環境を安全に保つために、すべての検出ルールを設定し、維持することは、継続的な作業であり、大きな時間を要します。この継続的な作業のガイドとなるロードマップがない場合は、なおさらそうです。クラウド環境を効果的に保護するために必要な要件はすべて、その業界に関連するコンプライアンス標準に従った方がよいでしょう。
インフラストラクチャーの保護とセキュリティ標準への準拠は継続的に行われるため、CIS Google Cloud Platform Foundation Benchmark などのベンチマークを定期的に実行して、システムを監査し、不適合があればレポートするのもよいでしょう。
まとめ
クラウドに移行すると、新しい可能性が広がりますが、その一方で、Google Cloud Platformのセキュリティに関するベストプラクティスを新たに習得する必要があります。新しいクラウド・サービスを利用する際には、それぞれに潜在的な危険性があるため、注意が必要です。
幸いなことに、FalcoやCloud Custodianのようなクラウドネイティブのセキュリティツールは、これらのGoogle Cloud Platformセキュリティのベストプラクティスを案内し、コンプライアンス要件を満たす手助けをしてくれるのです。
Secure DevOps on Google Cloud with Sysdig
Google Cloudとの提携により、共同利用者がクラウドサービスやコンテナをより効果的に保護できるよう支援できることをうれしく思います。Sysdig Secureのクラウドセキュリティ機能は、Google Cloudのコンテナサービスの可視化、セキュリティ、コンプライアンスを実現します。これには、GKE、Anthos、Cloud Run、Cloud Build、Google Container Registry、Artifact Registryのイメージスキャン、ランタイムセキュリティ、コンプライアンス、フォレンジックなどが含まれます。
クラウド、ワークロード、コンテナを一元管理することで、攻撃の検出と対応にかかる時間を短縮することができます。
Google Cloudのアカウント1つに対して、クラウドセキュリティのポスチャー管理を無料で永久に開始することができます。これには、CISベンチマークに対する毎日のチェック、Cloud Audit Logsと連携したクラウド脅威の検出、月250回までのインライン・コンテナ・イメージ・スキャンが含まれます。無料版はGoogle Cloud Marketplaceから入手できます。Sysdig 製品の無料トライアルはこちらをご覧ください。