# GCP - 基本情報

{{#include ../../../banners/hacktricks-training.md}}

## **リソース階層**

Google Cloudは、従来のファイルシステムに概念的に似た[リソース階層](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy)を使用しています。これにより、ポリシーや権限のための特定のアタッチメントポイントを持つ論理的な親/子ワークフローが提供されます。

高レベルでは、次のようになります：
```
Organization
--> Folders
--> Projects
--> Resources
```
仮想マシン（Compute Instanceと呼ばれる）はリソースです。リソースはプロジェクト内に存在し、他のCompute Instance、ストレージバケットなどと一緒に存在する可能性があります。

<figure><img src="../../../images/image (1) (1) (1) (1) (1) (1) (1).png" alt=""><figcaption><p><a href="https://cloud.google.com/static/resource-manager/img/cloud-hierarchy.svg">https://cloud.google.com/static/resource-manager/img/cloud-hierarchy.svg</a></p></figcaption></figure>

## **プロジェクトの移行**

**組織なしでプロジェクトを移行することが可能です**。必要な権限は`roles/resourcemanager.projectCreator`と`roles/resourcemanager.projectMover`です。プロジェクトが他の組織内にある場合、**最初にその組織から移動するためにGCPサポートに連絡する必要があります**。詳細については[**こちら**](https://medium.com/google-cloud/migrating-a-project-from-one-organization-to-another-gcp-4b37a86dd9e6)を確認してください。

## **組織ポリシー**

組織のクラウドリソースに対する中央集権的な管理を可能にします：

- 組織のリソースの使用方法に**制限を設定**するための中央集権的な管理。
- 開発チームがコンプライアンスの境界内に留まるための**ガードレール**を定義し、確立する。
- プロジェクトオーナーとそのチームがコンプライアンスを破る心配なく迅速に移動できるように支援します。

これらのポリシーは、**組織全体、フォルダー、またはプロジェクトに影響を与えるように作成できます**。ターゲットリソース階層ノードの子孫は**組織ポリシーを継承します**。

**組織ポリシーを定義するために、** [**制約**](https://cloud.google.com/resource-manager/docs/organization-policy/overview#constraints)を選択します。これは、Google CloudサービスまたはGoogle Cloudサービスのグループに対する特定の種類の制限です。**その制約を希望する制限で構成します**。

<figure><img src="../../../images/image (217).png" alt=""><figcaption><p><a href="https://cloud.google.com/resource-manager/img/org-policy-concepts.svg">https://cloud.google.com/resource-manager/img/org-policy-concepts.svg</a></p></figcaption></figure>

#### 一般的な使用例 <a href="#common_use_cases" id="common_use_cases"></a>

- ドメインに基づいてリソース共有を制限する。
- アイデンティティとアクセス管理サービスアカウントの使用を制限する。
- 新しく作成されたリソースの物理的な場所を制限する。
- サービスアカウントの作成を無効にする。

<figure><img src="../../../images/image (172).png" alt=""><figcaption></figcaption></figure>

組織のリソースに対する詳細な制御を提供する多くの制約があります。**詳細については、** [**すべての組織ポリシーサービス制約のリスト**](https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints)**を参照してください。**

### **デフォルトの組織ポリシー**

<details>

<summary>これらは、GCP組織を設定する際にGoogleがデフォルトで追加するポリシーです：</summary>

**アクセス管理ポリシー**

- **ドメイン制限付き連絡先：** 指定されたドメイン外のEssential Contactsにユーザーを追加することを防ぎます。これにより、選択したドメイン内の管理されたユーザーIDのみがプラットフォーム通知を受け取ることができます。
- **ドメイン制限付き共有：** 指定されたドメイン外のIAMポリシーにユーザーを追加することを防ぎます。これにより、選択したドメイン内の管理されたユーザーIDのみがこの組織内のリソースにアクセスできるようになります。
- **パブリックアクセス防止：** Cloud Storageバケットがパブリックに公開されるのを防ぎます。これにより、開発者がCloud Storageバケットを認証されていないインターネットアクセスに設定できなくなります。
- **均一なバケットレベルアクセス：** Cloud Storageバケット内のオブジェクトレベルのアクセス制御リスト（ACL）を防ぎます。これにより、Cloud Storageバケット内のすべてのオブジェクトに一貫してIAMポリシーを適用することでアクセス管理が簡素化されます。
- **OSログインを要求：** 新しいプロジェクトで作成されたVMにはOSログインが有効になります。これにより、個別のSSHキーを作成および管理することなく、IAMを使用してインスタンスへのSSHアクセスを管理できます。

**サービスアカウントの追加セキュリティポリシー**

- **自動IAM付与を無効にする：** デフォルトのApp EngineおよびCompute Engineサービスアカウントがプロジェクト作成時に自動的にEditor IAMロールを付与されるのを防ぎます。これにより、サービスアカウントが作成時に過剰な権限を持つIAMロールを受け取ることがありません。
- **サービスアカウントキーの作成を無効にする：** パブリックサービスアカウントキーの作成を防ぎます。これにより、永続的な資格情報が公開されるリスクが軽減されます。
- **サービスアカウントキーのアップロードを無効にする：** パブリックサービスアカウントキーのアップロードを防ぎます。これにより、漏洩または再利用されたキーのリスクが軽減されます。

**セキュアなVPCネットワーク構成ポリシー**

- **VMインスタンスの許可された外部IPを定義する：** パブリックIPを持つComputeインスタンスの作成を防ぎ、インターネットトラフィックにさらされる可能性があります。

* **VMネストされた仮想化を無効にする：** Compute Engine VM上でネストされたVMの作成を防ぎます。これにより、監視されていないネストされたVMのセキュリティリスクが低減されます。

- **VMシリアルポートを無効にする：** Compute Engine VMへのシリアルポートアクセスを防ぎます。これにより、Compute Engine APIを使用してサーバーのシリアルポートへの入力が防止されます。

* **Cloud SQLインスタンスの承認されたネットワークを制限する：** パブリックまたは非内部ネットワーク範囲がCloud SQLデータベースにアクセスするのを防ぎます。

- **IPアドレスのタイプに基づいてプロトコル転送を制限する：** 外部IPアドレスに対するVMプロトコル転送を防ぎます。

* **Cloud SQLインスタンスのパブリックIPアクセスを制限する：** パブリックIPを持つCloud SQLインスタンスの作成を防ぎ、インターネットトラフィックにさらされる可能性があります。

- **共有VPCプロジェクトの担保削除を制限する：** 共有VPCホストプロジェクトの偶発的な削除を防ぎます。

* **新しいプロジェクトの内部DNS設定をゾーンDNSのみに設定する：** サービスの可用性が低下するレガシーDNS設定の使用を防ぎます。

- **デフォルトネットワークの作成をスキップする：** デフォルトのVPCネットワークと関連リソースの自動作成を防ぎます。これにより、過剰な権限を持つデフォルトのファイアウォールルールを回避できます。

* **VPC外部IPv6の使用を無効にする：** 不正なインターネットアクセスにさらされる可能性のある外部IPv6サブネットの作成を防ぎます。

</details>

## **IAMロール**

これらはAWSのIAMポリシーのように、**各ロールには一連の権限が含まれています。**

しかし、AWSとは異なり、**ロールの中央リポジトリはありません**。その代わりに、**リソースはYプリンシパルにXアクセスロールを付与し、リソースへのアクセス権を持つ人を知る唯一の方法は、そのリソースに対して** `get-iam-policy` メソッドを使用することです。\
これは問題になる可能性があります。なぜなら、**プリンシパルがどの権限を持っているかを知る唯一の方法は、すべてのリソースに対して誰に権限を与えているかを尋ねることだからです**。ユーザーはすべてのリソースから権限を取得する権限を持っていない可能性があります。

IAMには**3種類の**ロールがあります：

- **基本/プリミティブロール**、これはIAM導入前に存在した**オーナー**、**エディター**、および**ビューア**ロールを含みます。
- **事前定義されたロール**、特定のサービスに対する詳細なアクセスを提供し、Google Cloudによって管理されます。多くの事前定義されたロールがあり、**それらが持つ権限をすべて確認できます** [**こちら**](https://cloud.google.com/iam/docs/understanding-roles#predefined_roles)。
- **カスタムロール**、ユーザーが指定した権限のリストに基づいて詳細なアクセスを提供します。

GCPには数千の権限があります。ロールが権限を持っているかどうかを確認するには、[**こちらで権限を検索**](https://cloud.google.com/iam/docs/permissions-reference)し、どのロールがそれを持っているかを確認できます。

また、[**こちらで事前定義されたロールを検索**](https://cloud.google.com/iam/docs/understanding-roles#product_specific_documentation) **各製品によって提供されます。** 一部の**ロール**はユーザーに付与できず、**サービスアカウントのみに付与されることに注意してください。**\
さらに、**権限**は**関連するサービスに付与されている場合にのみ**有効になります。

また、**カスタムロールが** [**特定の権限を使用できるかどうかを確認できます**](https://cloud.google.com/iam/docs/custom-roles-permissions-support)**。**

{{#ref}}
../gcp-services/gcp-iam-and-org-policies-enum.md
{{#endref}}

## ユーザー <a href="#default-credentials" id="default-credentials"></a>

**GCPコンソール**には**ユーザーやグループ**の管理はなく、それは**Google Workspace**で行われます。ただし、Google Workspaceで異なるアイデンティティプロバイダーを同期することは可能です。

Workspacesの**ユーザーとグループには** [**https://admin.google.com**](https://admin.google.com/) からアクセスできます。

**MFA**はWorkspacesユーザーに**強制**できますが、**攻撃者**はトークンを使用してGCPに**cli経由でアクセスでき、MFAによって保護されません**（ユーザーが生成するためにログインしたときにのみMFAによって保護されます：`gcloud auth login`）。

## グループ

組織が作成されると、いくつかのグループが**作成されることが強く推奨されます**。これらのいずれかを管理している場合、組織全体または重要な部分が侵害される可能性があります：

<table data-header-hidden><thead><tr><th width="299.3076923076923"></th><th></th></tr></thead><tbody><tr><td><strong>グループ</strong></td><td><strong>機能</strong></td></tr><tr><td><strong><code>gcp-organization-admins</code></strong><br><em>(チェックリストに必要なグループまたは個人アカウント)</em></td><td>組織に属する任意のリソースを管理します。このロールは慎重に割り当ててください。組織管理者はすべてのGoogle Cloudリソースにアクセスできます。代わりに、この機能は非常に特権が高いため、グループを作成するのではなく、個別のアカウントを使用することを検討してください。</td></tr><tr><td><strong><code>gcp-network-admins</code></strong><br><em>(チェックリストに必要)</em></td><td>ネットワーク、サブネット、ファイアウォールルール、およびCloud Router、Cloud VPN、クラウドロードバランサーなどのネットワークデバイスを作成します。</td></tr><tr><td><strong><code>gcp-billing-admins</code></strong><br><em>(チェックリストに必要)</em></td><td>請求アカウントを設定し、その使用状況を監視します。</td></tr><tr><td><strong><code>gcp-developers</code></strong><br><em>(チェックリストに必要)</em></td><td>アプリケーションの設計、コーディング、およびテストを行います。</td></tr><tr><td><strong><code>gcp-security-admins</code></strong><br></td><td>アクセス管理や<a href="https://cloud.google.com/resource-manager/docs/organization-policy/org-policy-constraints">組織制約ポリシー</a>を含む、組織全体のセキュリティポリシーを確立および管理します。Google Cloudセキュリティ基盤ガイドの<a href="https://cloud.google.com/architecture/security-foundations/authentication-authorization#users_and_groups">詳細</a>を参照してください。</td></tr><tr><td><strong><code>gcp-devops</code></strong></td><td>継続的インテグレーションとデリバリー、監視、システムプロビジョニングをサポートするエンドツーエンドのパイプラインを作成または管理します。</td></tr><tr><td><strong><code>gcp-logging-admins</code></strong></td><td></td></tr><tr><td><strong><code>gcp-logging-viewers</code></strong></td><td></td></tr><tr><td><strong><code>gcp-monitor-admins</code></strong></td><td></td></tr><tr><td><strong><code>gcp-billing-viewer</code></strong><br><em>(もはやデフォルトではありません)</em></td><td>プロジェクトの支出を監視します。典型的なメンバーは財務チームの一部です。</td></tr><tr><td><strong><code>gcp-platform-viewer</code></strong><br><em>(もはやデフォルトではありません)</em></td><td>Google Cloud組織全体のリソース情報を確認します。</td></tr><tr><td><strong><code>gcp-security-reviewer</code></strong><br><em>(もはやデフォルトではありません)</em></td><td>クラウドセキュリティをレビューします。</td></tr><tr><td><strong><code>gcp-network-viewer</code></strong><br><em>(もはやデフォルトではありません)</em></td><td>ネットワーク構成をレビューします。</td></tr><tr><td><strong><code>grp-gcp-audit-viewer</code></strong><br><em>(もはやデフォルトではありません)</em></td><td>監査ログを表示します。</td></tr><tr><td><strong><code>gcp-scc-admin</code></strong><br><em>(もはやデフォルトではありません)</em></td><td>Security Command Centerを管理します。</td></tr><tr><td><strong><code>gcp-secrets-admin</code></strong><br><em>(もはやデフォルトではありません)</em></td><td>Secret Managerでのシークレットを管理します。</td></tr></tbody></table>

## **デフォルトのパスワードポリシー**

- 強力なパスワードを強制する
- 8文字から100文字の間
- 再利用禁止
- 有効期限なし
- サードパーティプロバイダーを通じてWorkspaceにアクセスしている場合、これらの要件は適用されません。

<figure><img src="../../../images/image (20).png" alt=""><figcaption></figcaption></figure>

<figure><img src="../../../images/image (22).png" alt=""><figcaption></figcaption></figure>

## **サービスアカウント**

これらは、**リソース**が**持つことができる**プリンシパルであり、GCPと簡単に相互作用するためにアクセスできます。たとえば、VMに**添付されたサービスアカウントの**authトークンにメタデータからアクセスすることが可能です。\
**IAMとアクセススコープ**の両方を使用する際にいくつかの**競合**が発生する可能性があります。たとえば、サービスアカウントが`compute.instanceAdmin`のIAMロールを持っている場合でも、侵害したインスタンスには`https://www.googleapis.com/auth/compute.readonly`のスコープ制限がかかっている可能性があります。これにより、インスタンスに自動的に割り当てられたOAuthトークンを使用して変更を加えることができなくなります。

これはAWSの**IAMロール**に似ています。しかし、AWSとは異なり、**任意の**サービスアカウントは**任意のサービスに添付できます**（ポリシーを介して許可する必要はありません）。

使用を開始すると、実際に**GCPによって自動的に生成されるサービスアカウント**がいくつかあります。例えば：
```
PROJECT_NUMBER-compute@developer.gserviceaccount.com
PROJECT_ID@appspot.gserviceaccount.com
```
ただし、**カスタムサービスアカウント**を作成してリソースにアタッチすることも可能で、次のようになります：
```
SERVICE_ACCOUNT_NAME@PROJECT_NAME.iam.gserviceaccount.com
```
### **キーとトークン**

GCPにサービスアカウントとしてアクセスする主な方法は2つあります：

- **OAuthトークン経由**：これらはメタデータエンドポイントやHTTPリクエストを盗むことで得られるトークンで、**アクセススコープ**によって制限されます。
- **キー**：これらは公開鍵と秘密鍵のペアで、サービスアカウントとしてリクエストに署名したり、サービスアカウントとしてアクションを実行するためのOAuthトークンを生成したりすることができます。これらのキーは制限と管理が複雑なため危険です。そのため、GCPは生成しないことを推奨しています。
- サービスアカウントが作成されるたびに、**GCPはユーザーがアクセスできないサービスアカウント用のキーを生成します**（ウェブアプリケーションには表示されません）。[**このスレッド**](https://www.reddit.com/r/googlecloud/comments/f0ospy/service_account_keys_observations/)によると、このキーは**GCPによって内部的に使用され**、メタデータエンドポイントがアクセス可能なOAuthトークンを生成するためのアクセスを提供します。

### **アクセススコープ**

アクセススコープは、GCP APIエンドポイントにアクセスするために**生成されたOAuthトークンに添付されます**。これらはOAuthトークンの**権限を制限します**。\
つまり、トークンがリソースのオーナーに属していても、そのリソースにアクセスするためのスコープがトークンに含まれていない場合、トークンは**その権限を（悪用）するために使用できません**。

Googleは実際に[推奨しています](https://cloud.google.com/compute/docs/access/service-accounts#service_account_permissions)が、**アクセススコープは使用せず、IAMに完全に依存すること**です。ウェブ管理ポータルは実際にこれを強制しますが、カスタムサービスアカウントを使用してプログラム的にインスタンスにアクセススコープを適用することは依然として可能です。

**スコープ**が**割り当てられている**かどうかは、**クエリを実行することで確認できます：**
```bash
curl 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token=<access_token>'

{
"issued_to": "223044615559.apps.googleusercontent.com",
"audience": "223044615559.apps.googleusercontent.com",
"user_id": "139746512919298469201",
"scope": "openid https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/sqlservice.login https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/accounts.reauth",
"expires_in": 2253,
"email": "username@testing.com",
"verified_email": true,
"access_type": "offline"
}
```
前述の**scopes**は、データにアクセスするために**`gcloud`**を使用して**default**で生成されたものです。これは、**`gcloud`**を使用する際に最初にOAuthトークンを作成し、それを使用してエンドポイントに連絡するためです。

これらの中で最も重要なスコープは**`cloud-platform`**であり、基本的には**GCP内の任意のサービスにアクセス可能**であることを意味します。

**ここにあるすべての可能なスコープのリストを見つけることができます**[**all the possible scopes in here**](https://developers.google.com/identity/protocols/googlescopes)**.**

**`gcloud`**ブラウザ資格情報がある場合、他のスコープでトークンを**取得することが可能**です。次のようなことを行います:
```bash
# Maybe you can get a user token with other scopes changing the scopes array from ~/.config/gcloud/credentials.db

# Set new scopes for SDKs credentials
gcloud auth application-default login --scopes=https://www.googleapis.com/auth/userinfo.email,https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/sqlservice.login,https://www.googleapis.com/auth/appengine.admin,https://www.googleapis.com/auth/compute,https://www.googleapis.com/auth/accounts.reauth,https://www.googleapis.com/auth/admin.directory.user,https://www.googleapis.com/auth/admin.directory.group,https://www.googleapis.com/auth/admin.directory.domain,https://www.googleapis.com/auth/admin.directory.user

# Print new token
gcloud auth application-default print-access-token

# To use this token with some API you might need to use curl to indicate the project header with --header "X-Goog-User-Project: <project-name>"
```
## **Terraform IAMポリシー、バインディング、およびメンバーシップ**

terraformによって定義されたように、[https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam](https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/google_project_iam)を使用してGCPでterraformを使用する場合、リソースに対するプリンシパルのアクセスを付与する方法はいくつかあります：

- **メンバーシップ**: **プリンシパルを役割のメンバーとして設定**し、役割やプリンシパルに対する**制限なし**で行います。ユーザーを役割のメンバーとして設定し、同じ役割のメンバーとしてグループを設定し、さらにそれらのプリンシパル（ユーザーとグループ）を他の役割のメンバーとして設定できます。
- **バインディング**: 複数の**プリンシパルを役割にバインド**できます。これらの**プリンシパルは他の役割にバインドされたり、メンバーであったりすることができます**。ただし、役割にバインドされていないプリンシパルが**バインドされた役割のメンバーとして設定**されると、次回**バインディングが適用されると、メンバーシップは消えます**。
- **ポリシー**: ポリシーは**権威あるものであり**、役割とプリンシパルを示し、その後、**これらのプリンシパルは他の役割を持つことができず、これらの役割は他のプリンシパルを持つことができません**。そのポリシーが変更されない限り（他のポリシー、バインディング、またはメンバーシップでも）、したがって、ポリシーで役割またはプリンシパルが指定されると、そのすべての特権は**そのポリシーによって制限されます**。明らかに、プリンシパルにポリシーを変更するオプションや特権昇格の権限（新しいプリンシパルを作成し、新しい役割にバインドするなど）が与えられた場合、これを回避できます。

## 参考文献

- [https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/](https://about.gitlab.com/blog/2020/02/12/plundering-gcp-escalating-privileges-in-google-cloud-platform/)
- [https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy](https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy)

{{#include ../../../banners/hacktricks-training.md}}
