24の Google Cloud Platform(GCP)セキュリティベストプラクティス

SHARE:

解決すべき課題があり、そのために Google Cloud Platform(GCP)を採用し、セキュリティベストプラクティスに従ってソリューションの構築とホスティングを始めることにしました。アカウントを作成し、コーヒーを淹れてワークステーションに腰を下ろし、アーキテクチャ設計、コーディング、ビルド、デプロイに取り掛かる準備は整っています。――しかし、実際にはまだ準備万端ではありません。

ソリューションを本番環境で安全に稼働させ、信頼性・性能・コスト効率のすべてを満たすには、数多くの設定や実践すべき手順があります。そして、それらに着手する最適なタイミングはまさに今――設計や実装を始める前の、この瞬間なのです。


Google Cloud Platform(GCP)の共有責任モデル

Google Cloud の製品やサービスは、従来型の IaaS(Infrastructure as a Service)から PaaS(Platform as a Service)、さらに SaaS(Software as a Service)に至るまで幅広く提供されています。図に示すとおり、ユーザーとクラウドプロバイダの責任範囲は、利用するサービスモデルによって変化します。

最低限、公的クラウドプロバイダは堅牢かつ安全な基盤を提供することで、セキュリティに関する共通の責任を担う必要があります。また、プロバイダは利用者が共有責任モデルにおける自らの役割を正しく理解し、それを実装できるよう支援しなければなりません。

Shared responsibility model


Google Cloud Platform のセキュリティベストプラクティスを設定する

まず最初に注意点です。非企業アカウントは決して使用しないでください。

代わりに、完全に管理された企業用 Google アカウントを使用することで、Cloud Platform リソースへのアクセスに対する可視性、監査、制御を改善します。個人アカウントなど、組織外のメールアカウントを業務目的に使用してはいけません

Cloud Identity はスタンドアローンの IDaaS(Identity-as-a-Service)であり、Google Cloud ユーザーに対して Google Workspace が提供する多くのアイデンティティ管理機能へのアクセスを可能にします。これは、Google による安全なクラウドネイティブのコラボレーションおよび生産性向上アプリケーション群です。Cloud Identity 管理レイヤーを通じて、組織のメンバーに対して Google Cloud Platform(GCP)を含むさまざまな Google ソリューションへのアクセスを有効化または無効化することができます。

Cloud Identity にサインアップすると、ドメインのための組織ノードも作成されます。これにより、企業構造と制御を Google Cloud リソース階層にマッピングすることが可能になります。

次に、MFA(多要素認証)を有効化することは最も重要な事項です。特に管理者にとって、セキュリティ第一の考え方を持つのであれば、システム内で作成するすべてのユーザーアカウントに対してこれを実施してください。MFA は強力なパスワードと組み合わせることで、不正アクセスからユーザーアカウントを保護する最も効果的な方法です。

準備が整ったところで、GCP セキュリティベストプラクティスに入りましょう。


GCP セキュリティの手順案内


このセクションでは、最も一般的な GCP サービスを順に見ていき、それぞれに採用すべき 2 ダース(私たちは「ダース」が好きです)のベストプラクティスを紹介します。

オープンソースを活用して Google Cloud Platform のセキュリティベストプラクティスを実現する ― Cloud CustodianCloud 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_IDCode language: Perl (perl)


また、各フォルダに追加されているアカウントも一覧にします。

gcloud resource-manager folders get-iam-policy FOLDER_IDCode language: Perl (perl)


また、組織の IAM ポリシーを一覧にします。

gcloud organizations get-iam-policy ORGANIZATION_IDCode language: Perl (perl)

IAM ポリシーにおいて、組織ドメイン外のメールアカウントに権限を付与してはいけません。これは Google が所有するサービスアカウントを除きます。

デフォルトでは、組織のドメイン外のメールアドレスは、その組織の Google Cloud デプロイメントにアクセスできません。しかし、任意のユーザーのメールアカウントを Google Cloud Platform のプロジェクト、フォルダ、または組織の IAM ポリシーに追加することが可能です。これを防ぐために、組織ポリシー内で Domain Restricted Sharing(ドメイン制限共有)を有効にしてください。

gcloud resource-manager org-policies allow --organization=ORGANIZATION_ID iam.allowedPolicyMemberDomains=DOMAIN_IDCode language: Perl (perl)


こちらは、個人アカウントの使用を検出するための 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)*Code language: Perl (perl)

2. すべてのユーザーアカウントに対して MFA が有効になっていることを確認する  🟥

多要素認証(MFA)は、ユーザーを認証するために複数の仕組みを必要とします。これにより、盗まれた認証情報や弱い認証情報を悪用する攻撃者からユーザーログインを保護します。デフォルトでは、多要素認証は設定されていません。

各 Google Cloud Platform プロジェクト、フォルダ、または組織において、各アカウントに対して多要素認証が設定されていることを確認し、もし設定されていない場合は有効化してください。

3.
管理者アカウントに対してセキュリティキーの強制を確実にする 🟥

GCP において Organization Administrator ロールを持つユーザーは、組織内で最も高いレベルの権限を持ちます。

これらのアカウントは、最も強力な二要素認証の形式 ― セキュリティキーの強制 ― によって保護されるべきです。管理者が SMS やワンタイムパスワード(OTP)のような弱い二次要素ではなく、セキュリティキーを使ってログインするようにしてください。セキュリティキーは、Google 組織管理者アカウントにアクセスするために使用される実際の物理キーです。コードの代わりに暗号化された署名を送信するため、ログインがフィッシングされることはありません。

Organization Administrator 権限を持つユーザーを特定します:

gcloud organizations get-iam-policy ORGANIZATION_IDCode language: Perl (perl)

「roles/resourcemanager.organizationAdmin」ロールが付与されているメンバーを探し、その後、各アカウントに対してセキュリティキーの強制が有効になっていることを手動で確認してください。もし有効化されていない場合は、重大な問題として扱い、直ちに有効にしてください。デフォルトでは、Organization Administrator に対してセキュリティキーの強制は有効になっていません。

もし組織管理者がセキュリティキーへのアクセスを失った場合、そのユーザーは自分のアカウントにアクセスできなくなる可能性があります。このため、バックアップのセキュリティキーを構成しておくことが重要です。

4. ユーザー管理のサービスアカウントキーの使用を防止する 🟨

キーにアクセスできる者は誰でも、そのサービスアカウントを通じてリソースにアクセスできます。GCP 管理キーは App Engine や Compute Engine などの Cloud Platform サービスによって使用されます。これらのキーはダウンロードできません。Google がキーを保持し、ほぼ毎週自動的にローテーションします。

一方で、ユーザー管理キーはユーザーによって作成され、ダウンロードされ、管理されますが、有効期限は作成から 10 年後です。

ユーザー管理キーは、ソースコードに埋め込まれる、ダウンロードディレクトリに放置される、サポートブログやチャンネルで誤って公開されるといった一般的な開発慣行によって、容易に侵害される可能性があります。

すべてのサービスアカウントを一覧にします:

gcloud iam service-accounts listCode language: Perl (perl)


ユーザー管理のサービスアカウントを特定します。そのようなアカウントのメールアドレスは

iam.gserviceaccount.com.


で終わります。
各ユーザー管理サービスアカウントについて、ユーザーによって管理されているキーを一覧にします:

gcloud iam service-accounts keys list --iam-account=SERVICE_ACCOUNT --managed-by=userCode language: Perl (perl)


キーは一覧に表示されてはいけません。もしリストにキーが表示された場合は、それを削除してください:

gcloud iam service-accounts keys delete --iam-account=SERVICE_ACCOUNT KEY_IDCode language: Perl (perl)

ユーザー管理のサービスアカウントキーを削除すると、対応するキーを使用しているアプリケーションとの通信が壊れる可能性があることに注意してください。

予防策として、サービスアカウントキーの作成も無効にしておくとよいでしょう。

その他の GCP セキュリティ IAM ベストプラクティスには以下が含まれます:

  • サービスアカウントに管理者権限を付与してはいけません。
  • IAM ユーザーに対して、プロジェクトレベルで Service Account User または Service Account Token Creator ロールを割り当ててはいけません。
  • サービスアカウントのユーザー管理/外部キー(#4 参照)が許可されている場合、それらは 90 日ごと、またはそれ以下の間隔でローテーションする必要があります。
  • サービスアカウント関連のロールをユーザーに割り当てる際には、職務分離を徹底してください。
  • KMS 関連のロールをユーザーに割り当てる際にも、職務分離を徹底してください。
  • プロジェクトに対して API キーを作成してはいけません。
  • API キーは、指定されたホストおよびアプリによってのみ使用できるよう制限する必要があります。
  • API キーは、アプリケーションがアクセスする必要のある API のみに制限する必要があります。
  • API キーは 90 日ごと、またはそれ以下の間隔でローテーションする必要があります。

Key Management Service (KMS)

GCP Cloud Key Management Service (KMS) はクラウドホスト型のキー管理サービスであり、オンプレミスと同様の方法でクラウドサービス向けの対称鍵および非対称鍵を管理することができます。AES 256、RSA 2048、RSA 3072、RSA 4096、EC P256、EC P384 の暗号鍵を作成、使用、ローテーション、破棄することができます。

KMS に関して必ず実装すべき Google Cloud Platform セキュリティベストプラクティスには以下のものがあります:

5. 匿名または公開でアクセス可能な Cloud 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'Code language: Perl (perl)


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=ROLECode language: Perl (perl)


以下は、匿名または公開でアクセス可能な 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"]Code language: Perl (perl)

6. KMS 暗号鍵が 90 日以内の期間でローテーションされるようにする 🟩

キーは指定されたローテーション期間で作成することができます。これは、新しいキーのバージョンが自動的に生成されるまでの時間です。キーはあるデータ集合を保護するために使用されるため、一連のファイルを同じキーで暗号化でき、そのキーに対して復号権限を持つユーザーはそれらのファイルを復号できます。したがって、ローテーション期間が特定の時間に設定されていることを確認する必要があります。

GCP セキュリティベストプラクティスとして、このローテーション期間を 90 日以内に設定することが推奨されます:

gcloud kms keys update new --keyring=KEY_RING --location=LOCATION --rotation-period=90dCode language: Perl (perl)


デフォルトでは、KMS 暗号鍵は 90 日ごとにローテーションされます。これを一度も変更していない場合は、そのままで問題ありません。

Cloud Storage

Google Cloud Storage では、「バケット」と呼ばれる名前空間に任意の量のデータを保存できます。これらのバケットは、データを入手しようとする攻撃者にとって魅力的な標的となるため、それらを保護する際には細心の注意を払う必要があります。

以下は実装すべき GCP セキュリティベストプラクティスの一部です:

7. Cloud Storage バケットが匿名または公開でアクセス可能になっていないことを確認する 🟥

匿名または公開アクセスを許可すると、誰でもバケットの内容にアクセスできるようになります。機密データを保存している場合、そのようなアクセスは望ましくありません。したがって、バケットへの匿名または公開アクセスが許可されていないことを確認してください。

プロジェクト内のすべてのバケットを一覧にします:

gsutil lsCode language: Perl (perl)

上記のコマンドで返された各バケットについて、IAM ポリシーを確認します:

gsutil iam get gs://BUCKET_NAMECode language: Perl (perl)

いかなるロールにも、メンバーとして allUsers または allAuthenticatedUsers を含めてはいけません。もし含まれている場合は、次のコマンドで削除してください:

gsutil iam ch -d allUsers gs://BUCKET_NAME
gsutil iam ch -d allAuthenticatedUsers gs://BUCKET_NAMECode language: Perl (perl)

また、Domain Restricted Sharing 組織ポリシーを設定することで、Storage バケットが公開アクセス可能になるのを防ぐこともできます。

8. Cloud Storage バケットで一律のバケットレベルアクセスを有効にする 🟨

Cloud Storage では、ユーザーにバケットやオブジェクトへのアクセス権限を付与するために 2 つの仕組みを提供しています。Cloud Identity and Access Management(Cloud IAM)とアクセス制御リスト(ACL)です。これらの仕組みは並行して動作します。ユーザーがクラウドストレージリソースにアクセスするためには、いずれか一方の仕組みが権限を付与すれば十分です。

Cloud IAM は Google Cloud 全体で使用されており、バケットレベルやプロジェクトレベルで異なる権限を付与できます。ACL は Cloud Storage のみによって使用され、権限オプションは限定的ですが、オブジェクトごと(きめ細かいレベル)に権限を付与することができます。

一律のバケットレベルアクセスを有効にすると、すべての Cloud Storage リソース(バケットとオブジェクト)において ACL が無効化され、Cloud IAM を通じたアクセスのみに限定されます。

この機能は、クラウドストレージリソースへのアクセス権限付与方法を統合し、簡素化するためにも利用されます。一律のバケットレベルアクセスを有効化することで、もしストレージバケットが公開アクセス不可であれば、そのバケット内のオブジェクトも公開アクセス不可であることが保証されます。

プロジェクト内のすべてのバケットを一覧にします:

gsutil lsCode language: Perl (perl)

上記のコマンドで返された各バケットについて、一律のバケットレベルアクセスが有効になっていることを確認します:

gsutil uniformbucketlevelaccess get gs://BUCKET_NAME/Code language: Perl (perl)

一律のバケットレベルアクセスが有効になっている場合、応答は次のようになります:

Uniform bucket-level access setting for gs://BUCKET_NAME/:
    Enabled: True
    LockedTime: LOCK_DATECode language: Perl (perl)

バケットで有効になっていない場合は、次のコマンドで有効にできます:

gsutil uniformbucketlevelaccess set on gs://BUCKET_NAME/Code language: Perl (perl)

また、組織ポリシーを設定することで、新しいバケットが必ず一律のバケットレベルアクセスを有効にするよう強制することもできます。

以下は、一律アクセスが有効化されていないバケットをチェックするための 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: trueCode language: Perl (perl)

Virtual Private Cloud (VPC)

Virtual Private Cloud は、クラウドベースのリソースやサービスのために、グローバルでスケーラブルかつ柔軟なネットワーキングを提供します。これは App Engine、Compute Engine、または Google Kubernetes Engine(GKE)にネットワーキング機能を提供するため、それらを保護する際には細心の注意を払う必要があります。

これは実装すべき GCP セキュリティベストプラクティスの 1 つです:

9. VPC サブネットに対して VPC フローログを有効にする 🟨


デフォルトでは、新しい VPC ネットワークサブネットが作成されたとき、VPC フローログ機能は無効になっています。有効にすると、VPC フローログは Virtual Private Cloud(VPC)サブネットとの間でやり取りされるネットワークトラフィックデータを収集し、ネットワーク利用状況、ネットワークトラフィックコストの最適化、ネットワークフォレンジック、リアルタイムの析に役立てます。

Google Cloud VPC ネットワークの可視性とセキュリティを高めるために、ビジネスクリティカルまたは本番環境の VPC サブネットごとにフローログを有効にすることが強く推奨されます。

gcloud compute networks subnets update SUBNET_NAME --region=REGION --enable-flow-logsCode language: Perl (perl)

Compute Engine

Compute Engine は、Google のインフラストラクチャ上で仮想マシンを作成し実行できる、セキュリティとカスタマイズ性を備えたコンピュートサービスを提供します。

できるだけ早く実装すべき GCP セキュリティベストプラクティスがいくつかあります:

10. VM インスタンスに対して「プロジェクト全体の SSH キーをブロック」を有効にする 🟨

プロジェクト全体の SSH キーを使用すると、GCP プロジェクト内で実行中のすべての Google Cloud VM インスタンスにログインできます。プロジェクト全体で SSH キーを使用することは、SSH キーの管理を容易にしますが、漏洩した場合、プロジェクト内のすべての VM インスタンスに影響を及ぼすセキュリティリスクとなります。そのため、特定の SSH キーを代わりに使用することが強く推奨されます。これにより、キーが侵害された場合の攻撃対象領域を減らすことができます。

デフォルトでは、Google Compute Engine インスタンスに対して「プロジェクト全体の SSH キーをブロック」セキュリティ機能は有効になっていません。

プロジェクト全体の SSH キーをブロックするには、メタデータ値を TRUE に設定します:

gcloud compute instances add-metadata INSTANCE_NAME --metadata block-project-ssh-keys=trueCode language: Perl (perl)


以下は、このブロックが有効になっていないインスタンスをチェックするための 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"Code language: Perl (perl)

11. VM インスタンスで「シリアルポートへの接続を有効にする」が有効になっていないことを確認する 🟨

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=falseCode language: Perl (perl)

また、「VM シリアルポートアクセスを無効化」組織ポリシーを利用することで、VM がインタラクティブシリアルポートアクセスを有効にするのを防ぐことができます。

12. 重要な VM のディスクが顧客提供の暗号鍵(CSEK)で暗号化されていることを確認する 🟥

デフォルトでは、Compute Engine サービスは保存データをすべて暗号化します。

クラウドサービスは、この種類の暗号化をユーザーやアプリケーションからの追加の操作なしに管理します。しかし、インスタンスディスクの暗号化を完全に制御したい場合は、自分自身の暗号鍵を提供することができます。

これらのカスタムキーは、顧客提供暗号鍵(CSEK)として知られており、インスタンスデータの暗号化および復号に使用される Google 生成のキーを保護するために Google Compute Engine によって使用されます。Compute Engine サービスは CSEK をサーバーに保存せず、必要なキーを指定しない限り保護されたデータにアクセスすることはできません。

少なくとも、ビジネスクリティカルな VM では、VM ディスクを CSEK で暗号化しておく必要があります

デフォルトでは、VM ディスクは Google 管理キーで暗号化されており、顧客提供暗号鍵では暗号化されていません。

現在、既存ディスクの暗号化を更新する方法はないため、新しいディスクを「Customer supplied」に設定して作成する必要があります。ここで注意が必要です:

⚠️ 暗号鍵を失った場合、データを復元することはできません。
gcloud compute ツールでは、インスタンス作成時に –csek-key-file フラグを使用してディスクを暗号化します。RSA でラップされたキーを使用している場合は、gcloud beta コンポーネントを使用します:

gcloud beta compute instances create INSTANCE_NAME --csek-key-file=key-file.jsonCode language: Perl (perl)

スタンドアロンの永続ディスクを暗号化するには、次を使用します:

gcloud beta compute disks create DISK_NAME --csek-key-file=key-file.jsonCode language: Perl (perl)

鍵を生成し管理するのはあなたの責任です。Compute Engine に対しては、RFC 4648 標準の base64 でエンコードされた 256 ビットの文字列である鍵を提供する必要があります。

サンプルの 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"
  }
]Code language: Perl (perl)

Compute Engine に関するその他の GCP セキュリティベストプラクティスには以下が含まれます:

  • インスタンスがデフォルトのサービスアカウントを使用するように構成されていないことを確認する。
  • インスタンスがすべての Cloud API へのフルアクセスを持つデフォルトのサービスアカウントを使用するように構成されていないことを確認する。
  • プロジェクトに対して OS Login が有効になっていることを確認する。
  • インスタンスで 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)"Code language: Perl (perl)

次に、前のステップで作成した KMS キーリング内に、新しい Cloud KMS 顧客管理キー(CMK)を作成します:

gcloud kms keys create KEY_NAME --location=REGION --keyring=KEY_RING_NAME --purpose=encryption --protection-level=software --rotation-period=90d --format="table(name)"Code language: Perl (perl)

最後に、適切なサービスアカウントに 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.cryptoKeyEncrypterDecrypterCode language: Perl (perl)

最終ステップは、前の手順で作成した Cloud KMS 顧客管理キー(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_NAMECode language: Perl (perl)

14. 顧客管理キーを使用して GKE クラスターノードの暗号化を有効にする 🟥

GKE データの暗号化/復号プロセスをより制御できるようにするために、Google Kubernetes Engine(GKE)クラスターノードが顧客管理キー(CMK)で暗号化されていることを確認してください。Cloud Key Management Service(Cloud KMS)を使用して、自分自身の顧客管理キー(CMK)を作成および管理することができます。Cloud KMS は、安全で効率的な暗号鍵管理、制御された鍵ローテーション、および失効メカニズムを提供します。

この時点で、CMK を保存するキーリングと顧客管理キーがすでに存在しているはずです。ここでもそれらを使用します。

GKE クラスターノードの暗号化を有効にするには、ノードプールを再作成する必要があります。そのためには、再作成したいクラスターノードプールの名前を識別パラメータとして使用し、選択されたノードプールで利用可能な構成情報を記述するためにカスタム出力フィルタリングを使用します:

gcloud container node-pools describe NODE_POOL --cluster=CLUSTER_NAME --region=REGION --format=jsonCode language: Perl (perl)

次に、前のステップで返された情報を使用して、顧客管理キー(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_NAMECode language: Perl (perl)

新しいクラスターノードプールが正常に動作するようになったら、元のノードプールを削除して、Google Cloud アカウントに請求が追加されるのを停止できます。

⚠️ 必ず、新しいプールではなく古いプールを削除するように注意してください!

gcloud container node-pools delete NODE_POOL --cluster=CLUSTER_NAME --region=REGIONCode language: Perl (perl)

15. GKE クラスターへのネットワークアクセスを制限する 🟥

インターネットへの公開を制限するために、Google Kubernetes Engine(GKE)クラスターがマスター承認ネットワークで構成されていることを確認してください。マスター承認ネットワークを使用すると、特定の IP アドレスや IP アドレス範囲をホワイトリストに登録し、HTTPS を使用してクラスターのマスターエンドポイントにアクセスできるようにすることができます。

マスター承認ネットワークを追加することで、ネットワークレベルでの保護と 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,...Code language: Perl (perl)

前のコマンドでは、カンマで区切って複数の CIDR(最大 50 個)を指定できます。

上記は、GKE における最も重要なベストプラクティスです。これらを順守しないことは高いリスクを伴いますが、従うべきその他のセキュリティベストプラクティスもあります:

  • GKE クラスターノードに対して自動修復を有効にする。
  • GKE クラスターノードに対して自動アップグレードを有効にする。
  • GKE クラスターノードに対して整合性モニタリングを有効にする。
  • GKE クラスターノードに対してセキュアブートを有効にする。
  • シールドされた GKE クラスターノードを使用する。

Cloud Logging は、Google Cloud および Amazon Web Services からのログデータやイベントを保存、検索、分析、監視、およびアラートすることを可能にするフルマネージドサービスです。150 を超える一般的なアプリケーションコンポーネント、オンプレミスシステム、ハイブリッドクラウドシステムからログデータを収集することができます。

Cloud Logging に焦点を当てた、さらに多くの GCP セキュリティベストプラクティスがあります:

16. プロジェクト内のすべてのサービスおよびすべてのユーザーに対して Cloud Audit Logging が適切に構成されていることを確認する 🟥

Cloud Audit Logging は、各プロジェクト、フォルダ、組織に対して 2 種類の監査ログを維持します:

Admin ActivityData Access。Admin Activity ログには、リソースの構成やメタデータを変更する API 呼び出しやその他の管理アクションのログエントリが含まれます。これらはすべてのサービスに対して有効化されており、構成を変更することはできません。一方で、Data Access 監査ログは、ユーザー提供データを作成、変更、または読み取る API 呼び出しを記録します。これらはデフォルトでは無効化されており、有効化する必要があります。

デフォルトの監査設定を効果的に構成し、ユーザーアクティビティの追跡やユーザーデータの変更(改ざん)を記録できるようにすることが推奨されます。ログはすべてのユーザーに対して取得されるべきです。

そのために、プロジェクトのポリシーを編集する必要があります。まず、yaml ファイルとしてダウンロードします:

gcloud projects get-iam-policy PROJECT_ID > /tmp/project_policy.yamlCode language: Perl (perl)

次に、/tmp/project_policy.yaml を編集し、監査ログの構成のみを次の内容に追加または変更します:

auditConfigs:
- auditLogConfigs:
  - logType: DATA_WRITE
  - logType: DATA_READ
  service: allServicesCode language: Perl (perl)

監査ログはすべてのユーザーに対して有効化されるべきであるため、exemptedMembers は設定されていないことに注意してください。最後に、新しい変更内容でポリシーを更新します:

gcloud projects set-iam-policy PROJECT_ID /tmp/project_policy.yamlCode language: Perl (perl)

⚠️ Data Access 監査ログを有効にすると、追加のログ使用に対してプロジェクトに課金される可能性があります。

#17 すべてのログエントリに対してシンクが構成されていることを確認する 🟨

すべてのログエントリのコピーをエクスポートするシンクを作成することも必要です。これにより、複数のプロジェクトからログを集約し、それらをセキュリティ情報イベント管理(SIEM)にエクスポートできます。

エクスポートには、エクスポートするログエントリを選択するフィルタを作成し、Cloud Storage、BigQuery、または Cloud Pub/Sub 内の宛先を選択することが含まれます。フィルタと宛先は「シンク」と呼ばれるオブジェクトに保持されます。すべてのログエントリがシンクにエクスポートされることを保証するために、フィルタが構成されていないことを確認してください。

すべてのログエントリを Google Cloud Storage バケットにエクスポートするシンクを作成するには、次のコマンドを実行します:

gcloud logging sinks create SINK_NAME storage.googleapis.com/BUCKET_NAMECode language: Perl (perl)

これはイベントをバケットにエクスポートしますが、代わりに 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: emptyCode language: Perl (perl)

18. ログバケットの保持ポリシーが Bucket Lock を使用して構成されていることを確認する 🟨

ログバケットに保持ポリシーを有効化することで、クラウドストレージバケットに保存されたログが上書きされたり、誤って削除されたりするのを防ぐことができます。前のベストプラクティスに従い、ログシンクとして使用されるすべてのストレージバケットに保持ポリシーを設定し、バケットロックを構成することが推奨されます。

ストレージバケットを宛先とするすべてのシンクを一覧表示するには:

gcloud logging sinks list --project=PROJECT_IDCode language: Perl (perl)

上で一覧表示した各ストレージバケットについて、保持ポリシーを設定し、ロックします:

gsutil retention set TIME_DURATION gs://BUCKET_NAME
gsutil retention lock gs://BUCKET_NAMECode language: Perl (perl)

⚠️ バケットロックは不可逆的な操作です。一度バケットをロックすると、その保持ポリシーを削除したり、保持期間を短縮したりすることはできません。

19. 顧客管理キーを使用してログルーター暗号化を有効にする🟥

Google Cloud Logs Router のデータが顧客管理キー(CMK)で暗号化されていることを確認し、データの暗号化および復号プロセスを完全に制御できるようにするとともに、コンプライアンス要件を満たすようにしてください。

ポリシーを追加し、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.cryptoKeyEncrypterDecrypterCode language: Perl (perl)

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-sslCode language: Perl (perl)

さらに、この構成を有効にするためには、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: trueCode language: Perl (perl)

21. Cloud SQL データベースインスタンスが全世界に公開されていないことを確認する 🟥

データベースサーバーインスタンスの攻撃対象領域を最小限に抑えるために、信頼された/既知の必要な IP のみをホワイトリストに登録して接続できるようにするべきです。許可されたネットワークに、インスタンスへのアクセスを世界中のどこからでも可能にする 0.0.0.0/0 のような IP/ネットワークを設定してはいけません。許可されたネットワークは、パブリック IP を持つインスタンスにのみ適用されることに注意してください。

gcloud sql instances patch INSTANCE_NAME --authorized-networks=IP_ADDR1,IP_ADDR2...Code language: Perl (perl)


新しい SQL インスタンスが任意の IP アドレスからの受信接続を受け付けるように構成されるのを防ぐために、Cloud SQL インスタンスに対して Restrict Authorized Networks 組織ポリシーを設定してください。

22. Cloud SQL データベースインスタンスがパブリック IP を持たないことを確認する 🟨

組織の攻撃対象領域を減らすために、Cloud SQL データベースはパブリック IP を持つべきではありません。プライベート IP は、ネットワークセキュリティを向上させ、アプリケーションのレイテンシーを低減します。

各インスタンスについて、そのパブリック IP を削除し、代わりにプライベート IP を割り当ててください。

gcloud beta sql instances patch INSTANCE_NAME --network=VPC_NETWORK_NAME --no-assign-ipCode language: Perl (perl)


新しい SQL インスタンスがパブリック IP アドレスで構成されるのを防ぐために、Cloud SQL インスタンスに対して Restrict Public IP access 組織ポリシーを設定してください。

23. Cloud SQL データベースインスタンスが自動バックアップで構成されていることを確認する 🟨

バックアップは、失われたデータを取得したり、そのインスタンスの問題から復旧したりするために Cloud SQL インスタンスを復元する方法を提供します。自動バックアップは、損失や破損から保護する必要があるデータを含むすべてのインスタンスに対して設定する必要があります。この推奨事項は、SQL Server、PostgreSQL、MySQL 第 1 世代、および MySQL 第 2 世代のインスタンスに適用されます。

次のコマンドを使用して、すべての Cloud SQL データベースインスタンスを一覧表示します:

gcloud sql instances listCode language: Perl (perl)

すべての Cloud SQL データベースインスタンスに対して自動バックアップを有効にします:

gcloud sql instances patch INSTANCE_NAME --backup-start-time [HH:MM]Code language: Perl (perl)

backup-start-time パラメータは 24 時間形式で UTC±00 タイムゾーンに基づいて指定され、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.jsonCode language: Perl (perl)

次に、dataset_info.json のアクセスセクションで、allUsers または allAuthenticatedUsers を含むすべてのロールを削除するようにデータセット情報を更新します。

最後に、データセットを更新します:

bq update --source=dataset_info.json PROJECT_ID:DATASET_NAMECode language: Perl (perl)

BigQuery データセットが公開アクセス可能になるのを防ぐために、Domain Restricted Sharing 組織ポリシーを設定してください。

コンプライアンス標準とベンチマーク

すべての検出ルールを設定し、GCP 環境を安全に維持することは継続的な作業であり、大きな時間を要することがあります。ガイドとなるロードマップがない場合は、なおさらです。

自分の業界に関連するコンプライアンス標準に従う方がよいでしょう。これらはクラウド環境を効果的に保護するために必要な要件をすべて提供してくれるからです。

インフラを保護し、セキュリティ標準に準拠することは継続的な性質を持つため、CIS Google Cloud Platform Foundation Benchmark のようなベンチマークを定期的に実行することも検討するとよいでしょう。これにより、システムを監査し、発見された不適合を報告してくれます。

結論

クラウドに移行することは新しい可能性の世界を開きますが、それは同時に新しい一連の Google Cloud Platform セキュリティベストプラクティスを学ぶことも必要とします。

活用する新しいクラウドサービスごとに、注意すべき潜在的な危険があります。

幸いなことに、Falco Cloud Custodian のようなクラウドネイティブセキュリティツールは、これらの Google Cloud Platform セキュリティベストプラクティスを導いてくれ、コンプライアンス要件を満たすのに役立ちます。