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

まず始める前の初期設定におけるベストプラクティス
まず、注意していただきたいことがあります。非企業アカウントは絶対に使用しないでください。代わりに、完全に管理された企業のGoogleアカウントを使用して、クラウドプラットフォームのリソースへのアクセスの可視性、監査、およびコントロールを向上させてください。また、個人アカウントなど、組織外のメールアカウントをビジネス目的で使用しないでください。
Cloud Identity はスタンドアロンの Identity-as-a-Service(IDaaS)であり、Google ワークスペースが提供するアイデンティティ管理機能の多くを Google Cloud ユーザーが利用できるようにします。これは、Google が提供するセキュアなクラウドネイティブ コラボレーションおよび生産性アプリケーションのスイートです。クラウド アイデンティティ管理層を通じて、Google Cloud Platform (GCP)を含む様々なGoogleソリューションへのアクセスを、組織のメンバーに対して有効または無効にすることができます。また、Cloud Identityにサインアップすると、ドメインの組織ノードが作成されます。これにより、Google Cloud のリソース階層を介して、企業構造やコントロールを Google Cloud リソースにマッピングすることができます。
さて、多要素認証(MFA)の有効化は最も重要なことです。セキュリティを第一に考えるのであれば、システムに作成するすべてのユーザーアカウントに対してこの設定を行う必要があります。MFAと強力なパスワードは、不正なアクセスからユーザーのアカウントを保護する最も効果的な方法です。
それでは、Google Cloud Platformのセキュリティのベストプラクティスをご紹介していきましょう。
Google Cloud Platformのセキュリティベスト プラクティス
このセクションでは、最も一般的なGCPサービスについて説明し、それぞれに採用すべき20数個(ここでは数十個とします)のベストプラクティスを提供します。オープンソースでGCPセキュリティのベストプラクティスを実現する – Cloud Custodianは、Cloud Security Posture Management (CSPM)ツールです。CSPMツールは、クラウドの構成を評価し、よくある構成上のミスを特定します。また、クラウドのログを監視して、脅威や構成の変更を検出します。
それでは、サービスごとに見ていきましょう。
アイデンティティ&アクセスマネジメント(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ユーザーは、組織内で最高レベルの権限を持っています。これらのアカウントは、最強の2ファクター認証で保護する必要があります:セキュリティキーエンフォースメント。管理者は、SMSやワンタイムパスワード(OTP)のような弱い二要素ではなく、セキュリティキーを使用してログインするようにします。セキュリティキーは、Google組織の管理者アカウントにアクセスするための実際の物理的な鍵です。セキュリティキーは、コードではなく暗号化された署名を送信するため、ログインがフィッシングされないことを保証します。組織管理者権限を持つユーザーを特定する:
gcloud organizations get-iam-policy ORGANIZATION_ID
”roles/resourcemanager.organizationAdmin”というロールが付与されているメンバーを探し、各アカウントでセキュリティキーエンフォースメントが有効になっているかどうかを手動で確認します。有効になっていない場合は、すぐに有効にしてください。デフォルトでは、組織管理者に対してセキュリティキーエンフォースメントは有効ではありません。
組織管理者がセキュリティキーにアクセスできなくなった場合、ユーザーは自分のアカウントにアクセスできなくなる可能性があります。このような理由から、バックアップ用のセキュリティキーを設定することが重要です。
#4 ユーザーが管理するサービスアカウントの鍵の使用を防止する(中リスク)
鍵にアクセスできる人は、サービスアカウントを介してリソースにアクセスできます。GCPで管理された鍵は、App EngineやCompute EngineなどのCloud Platformサービスで使用されます。これらの鍵はダウンロードできません。Googleが鍵を保持し、ほぼ毎週自動的にローテーションします。一方、ユーザー管理鍵は、ユーザーが作成、ダウンロード、管理するもので、有効期限は作成から10年です。
ユーザー管理鍵は、ソースコードで公開したり、ダウンロードディレクトリに置いておいたり、サポートブログやチャンネルで誤って公開してしまうなど、一般的な開発手法では簡単に漏洩してしまいます。
すべてのサービスアカウントをリストアップします:
gcloud iam service-accounts list
ユーザーが管理するサービスアカウントを識別するには、そのアカウントのEメールの末尾が
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
ユーザーが管理するサービスアカウントキーを削除すると、対応するキーを使用しているアプリケーションとの通信ができなくなることがありますのでご注意ください。
防止策として、サービスアカウントキーの作成も無効にすることをお勧めします。
その他、IAMのベストプラクティスとして:
- サービスアカウントはAdmin権限を持つべきではない。
- IAMユーザーは、プロジェクトレベルでService Account UserまたはService Account Token Creatorロールを割り当ててはならない。
- サービスアカウント用のユーザ管理/外部キーは、(許可されている場合、#4 を参照)90 日以内にローテートすべきである。
- サービスアカウントに関連する役割をユーザに割り当てる際には、職務の分離を徹底すべきである。
- KMS 関連の役割をユーザに割り当てる際には、義務の分離を実施すること。
- API キーは、プロジェクトのために作成してはならない。
- API キーは、指定したホストおよびアプリのみが使用できるように制限する必要があります。
- API キーは、アプリケーションがアクセスを必要とする API のみに制限する必要があります。
- API キーは 90 日以内にローテーションすること。
鍵管理サービス(KMS)
GCP Cloud Key Management Service (KMS)は、クラウドで提供される鍵管理サービスで、onpremと同様にクラウドサービスの対称・非対称暗号鍵を管理することができます。KMSでは、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
以下は、匿名または公開でアクセス可能なCloud KMSキーの存在を検出するためのCloud Custodianルールです:
- 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日以内にローテーションされていることを確認する (低リスク)
鍵は、ローテーション期間を指定して作成することができます。これは、新しいバージョンの鍵が自動的に生成されるまでの期間です。鍵は、あるデータのコーパスを保護するために使用されるので、複数のファイルの集合体を同じ鍵で暗号化することができ、その鍵の復号権を持つユーザーはそれらのファイルを復号することができます。そのため、ローテーション期間を特定の時間に設定する必要があります。ベストプラクティスは、このローテーション期間を90日以内に設定することです:
gcloud kms keys update new --keyring=KEY_RING --location=LOCATION --rotation-period=90d
デフォルトでは、KMS 暗号化キーは 90 日ごとにローテーションされます。これを変更しなければ、問題ありません。
クラウドストレージ
Google Cloud Storageでは、”バケット “と呼ばれるネームスペースに任意の量のデータを保存することができます。このバケットは、データを手に入れようとする攻撃者にとって格好の標的となるため、安全性の確保には細心の注意を払う必要があります。GCPのベストプラクティスをいくつかご紹介します:
#7 クラウドストレージのバケットに匿名またはパブリックアクセスできないようにする(高リスク)
匿名やパブリックアクセスを許可すると、誰でもバケットのコンテンツにアクセスできることになります。機密データを保存している場合、このようなアクセスは好ましくないかもしれません。そのため、バケットへの匿名またはパブリックアクセスが許可されていないことを確認してください。プロジェクト内のすべてのBucketをリストアップします:
gsutil ls
上記コマンドで返された各バケットのIAM Policyを確認します:
gsutil iam get gs://BUCKET_NAME
いかなるロールも、メンバーとしてallUsersまたはallAuthenticatedUsersを含んではいけません。そうでない場合は、次のようにして削除してください:
gsutil iam ch -d allUsers gs://BUCKET_NAME gsutil iam ch -d allAuthenticatedUsers gs://BUCKET_NAME
また、ドメイン制限付き共有の組織ポリシーを設定することで、Storageのバケットが一般にアクセスできないようにすることもできます。
#8 クラウドストレージのバケットに、バケットレベルでの統一されたアクセスが有効になっていることを確認する(中リスク)
Cloud Storageには、バケットやオブジェクトへのアクセス権限をユーザーに付与するための2つのシステムがあります。Cloud IAM(Cloud Identity and Access Management)とACL(Access Control Lists)です。これらのシステムは並行して動作します。ユーザーがクラウドストレージリソースにアクセスするためには、どちらか一方のシステムだけがパーミッションを付与する必要があります。Cloud IAM は Google Cloud 全体で使用されており、バケットレベルとプロジェクトレベルで異なる権限を付与することができます。ACL は Cloud Storage でのみ使用され、パーミッションのオプションは限られていますが、オブジェクトごとにパーミッションを付与することができます(きめ細かな設定が可能)。
バケットレベルの統一的なアクセス機能を有効にすると、すべてのCloud Storageリソース(バケットとオブジェクト)のACLが無効になり、Cloud IAMによる排他的なアクセスが可能になります。
この機能は、クラウドストレージリソースへのアクセスを許可する方法を統合し、簡素化するためにも使用されます。バケットレベルでの均一なアクセスを可能にすることで、ある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を設定して、新しいバケットにはバケットレベルのアクセスを統一するように強制することもできます。
これは、uniform-accessが有効になっていないバケットをチェックするCloud Custodianルールです:
- 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
VPC
#9 VPCサブネットのVPCフローログを有効にする(中リスク)
デフォルトでは、新しいVPCネットワークサブネットが作成されると、VPCフローログの機能は無効になります。VPCフローログを有効にすると、仮想プライベートクラウド(VPC)サブネットとの間のネットワークトラフィックデータの収集が開始され、ネットワークの使用状況、ネットワークトラフィックコストの最適化、ネットワークフォレンジック、リアルタイムのセキュリティ分析が可能になります。Google Cloud VPCネットワークの可視性とセキュリティを向上させるために、ビジネスクリティカルなVPCサブネットや本番環境のVPCサブネットごとにフローログを有効にすることを強くお勧めします。
gcloud compute networks subnets update SUBNET_NAME --region=REGION --enable-flow-logs
コンピュートエンジン
#10 VM インスタンスで「Block Project-wide SSH keys」が有効になっていることを確認する(中リスク)
プロジェクト全体の SSH キーを使用して、GCP プロジェクト内で実行されているすべての Google Cloud VM インスタンスにログインすることができます。プロジェクト全体でSSHキーを使用すると、SSHキーの管理が容易になりますが、漏洩した場合は、プロジェクト内のすべてのVMインスタンスに影響を与えるセキュリティリスクとなります。そのため、代わりに特定のSSH鍵を使用して、万が一漏洩した場合の攻撃対象を減らすことを強く推奨します。デフォルトでは、Google Compute Engineインスタンスのセキュリティ機能「Block Project-Wide SSH Keys」は有効になっていません。
プロジェクト全体の SSH キーをブロックするには、メタデータの値を 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インスタンスの ’シリアルポートへの接続を有効にする’ が有効になっていないことを確認する(中リスク)
Google Cloudの仮想マシン(VM)インスタンスには、4つの仮想シリアルポートがあります。シリアルポートでの操作は、入力と出力が完全にテキストモードであるという点でターミナルウィンドウの使用に似ており、グラフィカルなインターフェースやマウスのサポートはありません。オペレーティングシステム、BIOS、その他のシステムレベルのエンティティは、シリアルポートに出力を書き込み、コマンドやプロンプトへの応答などの入力を受け付けることができます。これらのシステムレベルのエンティティは、通常、最初のシリアルポート(ポート1)を使用し、これはしばしば対話型シリアルコンソールと呼ばれます。
対話型シリアルコンソールは、IPホワイトリストのようなIPベースのアクセス制限には対応していません。インスタンスで対話型シリアルコンソールを有効にすると、クライアントはどのIPアドレスからでもコンソールに接続することができます。これにより、正しいSSHキー、ユーザー名、プロジェクトID、ゾーン、インスタンス名を知っている誰もが、そのインスタンスに接続することができます。そのため、セキュリティのベストプラクティスを遵守するために、対話型シリアルコンソールのサポートを無効にする必要があります。
gcloud compute instances add-metadata INSTANCE_NAME --zone=ZONE --metadata serial-port-enable=false
また、Disable VM serial port access organization policyにより、VMの対話型シリアルポートアクセスが有効にならないようにすることができます。
#12 重要なVMのVMディスクをCustomer-Supplied Encryption Keys (CSEK)で確実に暗号化する(高リスク)
デフォルトでは、ComputeEngineサービスは保存されているすべてのデータを暗号化します。クラウドサービスは、ユーザーやアプリケーションが追加の操作をすることなく、このタイプの暗号化を管理します。しかし、インスタンスのディスク暗号化を完全に制御したい場合は、独自の暗号化キーを提供することができます。
これらのカスタム キーは、Customer-Supplied Encryption Keys(CSEK)とも呼ばれ、Google Compute Engine によって、インスタンス データの暗号化および復号化に使用される Google が生成したキーを保護するために使用されます。Compute Engine サービスは CSEK をサーバー上に保存せず、必要な鍵を指定しない限り保護されたデータにアクセスできません。
少なくとも、ビジネスクリティカルなVMは、CSEKで暗号化されたVMディスクを持つべきです。
デフォルトでは、VM ディスクは Google が管理する鍵で暗号化されます。Customer-Supplied Encryption Keyでは暗号化されません。
現在のところ、既存のディスクの暗号化を更新する方法はありませんので、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
鍵を生成して管理するのはあなたの義務です。RFC 4648標準のbase64でエンコードされた256ビットの文字列である鍵を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" } ]
その他のGCP Compute Engineのベストプラクティスは以下の通りです:
- インスタンスがデフォルトのサービスアカウントを使用するように設定されていないことを確認する。
- インスタンスが、すべてのクラウド API へのフルアクセスが可能なデフォルトのサービスアカウントを使用するように構成されていないことを確認する。
- OSLOGIN がプロジェクトで有効になっていることを確認する。
- インスタンスでIPフォワーディングが有効になっていないことを確認してください。
- ComputeインスタンスがShielded VMを有効にして起動されていることを確認してください。
- ComputeインスタンスがパブリックIPアドレスを持たないようにする。
- App EngineアプリケーションがHTTPS接続を強制するようにします。
Google Kubernetes Engineサービス(GKE)
Google Kubernetes Engine (GKE) は、Google インフラストラクチャーを使用してコンテナ化されたアプリケーションをデプロイ、管理、およびスケーリングするためのマネージド環境を提供します。GKE環境は、複数のマシン(具体的にはCompute Engineインスタンス)をグループ化してクラスターを構成します。#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 顧客が管理する鍵を使ったGKEクラスタノードの暗号化を有効にする(高リスク)
GKEデータの暗号化/復号化プロセスをよりコントロールするために、Google Kubernetes Engine (GKE)のクラスターノードを顧客管理キー(CMK)で暗号化してください。Cloud Key Management Service(Cloud KMS)を使用して、独自の顧客管理キー(CMK)を作成・管理することができます。クラウドKMSは、安全で効率的な暗号鍵管理、制御された鍵のローテーション、および失効メカニズムを提供します。この時点では、CMKや顧客管理キーを保管するキーホルダーをすでにお持ちのはずです。ここでもそれらを使用します。
GKEクラスターノードの暗号化を有効にするには、ノードプールを再作成する必要があります。このためには、再作成するクラスターノードプールの名前を識別子パラメータとして使用し、カスタム出力フィルタリングを使用して、選択したノードプールで利用可能な構成情報を記述します:
gcloud container node-pools describe NODE_POOL --cluster=CLUSTER_NAME --region=REGION --format=json
次に、前の手順で返された情報を使用して、顧客管理キー(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種類以上の一般的なアプリケーションコンポーネント、オンプレミスシステム、ハイブリッドクラウドシステムからログデータを収集することができます。#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 すべてのログエントリにシンクが設定されていることを確認する (中リスク)
また、すべてのログエントリーのコピーをエクスポートするシンクも作成しておきましょう。これにより、複数のプロジェクトのログを集約し、SIEM(Security Information and Event Management)にエクスポートすることができます。エクスポートには、エクスポートするログエントリーを選択するフィルターの作成と、Cloud Storage、BigQuery、またはCloud Pub/Subでの宛先の選択が必要です。フィルターとエクスポート先は、シンクと呼ばれるオブジェクトに保持されます。すべてのログ エントリーがシンクにエクスポートされるようにするには、フィルターが設定されていないことを確認します。
すべてのログ エントリーを Google Cloud Storage のバケットにエクスポートするシンクを作成するには、次のコマンドを実行します:
gcloud logging sinks create SINK_NAME storage.googleapis.com/BUCKET_NAME
これでイベントがバケットにエクスポートされますが、代わりにCloud Pub/SubやBigQueryを使用することもできます。
これは、シンクがフィルターなしで構成されていることをチェックするための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 バケットロックを使用してログバケットの保持ポリシーが設定されていることを確認する(中リスク)
ログバケットの保持ポリシーを有効にすると、クラウドストレージのバケットに保存されたログが上書きされたり、誤って削除されたりするのを防ぐことができます。前述のベストプラクティスに従って、ログシンクとして使用されるすべてのストレージバケットに保持ポリシーを設定し、バケットロックを構成することを推奨します。ストレージバケットに向けられたすべてのシンクを一覧表示するには、次のようにします:
gcloud logging sinks list --project=PROJECT_ID
上記の各ストレージバケットに対して、リテンションポリシーを設定し、ロックします:
gsutil retention set TIME_DURATION gs://BUCKET_NAME gsutil retention lock gs://BUCKET_NAME
⚠️ バケットロックは元に戻らない操作です。一度バケットをロックしてしまうと、そのバケットからリテンションポリシーを削除したり、リテンション期間を短くすることはできません。
#19 顧客が管理する鍵でログルーターの暗号化を有効にする(高リスク)
Google Cloud Logs Routerのデータが顧客管理キー (CMK)で暗号化されていることを確認し、データの暗号化と復号化のプロセスを完全に制御できるようにするとともに、コンプライアンス要件を満たすようにします。必要なサービスアカウントにCloud KMSの“CryptoKey Encrypter/Decrypter” ロールを割り当てるために、CMKのIAMポリシーにバインドするポリシーを追加する必要があります。ここでは、#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
#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ルールは、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 Cloud SQL データベースインスタンスが世界に公開されていないことを確認する(中リスク)
データベースサーバーインスタンスの攻撃対象を最小化するために、信頼できる/既知の必要なIPのみをホワイトリストに登録して接続する必要があります。許可されたネットワークには、世界のどこからでもインスタンスへのアクセスを可能にするIP/ネットワークが0.0.0.0/0
に設定されていてはなりません。許可されたネットワークは、パブリック IP を持つインスタンスにのみ適用されることに注意してください。gcloud sql instances patch INSTANCE_NAME --authorized-networks=IP_ADDR1,IP_ADDR2...
新しいSQLインスタンスが任意のIPアドレスからの着信接続を受け入れるように設定されないようにするには、「Restrict Authorized Networks on Cloud SQL instances Organization Policy」を設定します。
#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データベースインスタンスに自動バックアップが設定されているか(中リスク)
バックアップは、失われたデータを取得したり、インスタンスの問題から回復するために、Cloud SQLインスタンスを復元する方法を提供します。自動バックアップは、損失や損傷から保護する必要のあるデータを含むすべてのインスタンスに設定されるべきです。この推奨事項は、SQL Server、PostgreSql、MySql 世代 1、MySql 世代 2 のインスタンスに適用されます。以下のコマンドを使用して、すべてのCloud SQL データベース インスタンスをリストアップします:
gcloud sql instances list
すべてのCloud 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エンジンと機械学習を内蔵した、サーバーレスで拡張性が高く、コストパフォーマンスの高いクラウドデータウェアハウスです。#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のようなベンチマークを定期的に実行すると、システムを監査し、不適合があれば報告してくれます。
まとめ
クラウドに移行することで、新たな可能性が広がりますが、その一方で、新たなセキュリティのベストプラクティスを学ぶ必要があります。新しいクラウドサービスを利用する際には、それぞれに潜在的な危険性があることを認識する必要があります。
幸運なことに、Falcoやcloud-custodianのようなクラウドネイティブのセキュリティツールは、これらのセキュリティのベストプラクティスをガイドし、コンプライアンス要件を満たすのに役立ちます。
Sysdigが提供するGoogle Cloudにおける Secure DevOps
Sysdigは、Google Cloudのパートナーとして、共同ユーザーのクラウドサービスやコンテナのセキュリティをより効果的に確保できるよう支援できることを嬉しく思います。Sysdig Secureのクラウドセキュリティ機能は、Google Cloudのコンテナサービスの可視化、セキュリティ、コンプライアンスを実現します。これには、GKE、Anthos、Cloud Run、Cloud Build、Google Container Registry、Artifact Registryのイメージスキャン、ランタイムセキュリティ、コンプライアンス、フォレンジックが含まれます。
クラウド、ワークロード、コンテナを一元的に把握することで、攻撃の検知や対応にかかる時間を短縮することができます。
Google Cloudアカウントの1つを対象に、クラウドセキュリティポスチャーの管理を永久に無料で始められます。これには、CISベンチマークに対する毎日のチェック、クラウド監査ログと合わせたクラウド脅威の検知、月に250イメージまでのインラインコンテナイメージスキャンが含まれます。無料版は、Google Cloud Marketplaceから入手できます。詳しくはこちらをご覧ください。