【Google Cloud】特定のVMインスタンスだけSSH接続を限定許可するIAM設計
はじめに
こんにちは、クラウドエースの梶尾です。
Google Cloud の運用設計を進める中で、特定の外部パートナーや運用担当者に、特定の VM インスタンスだけを触らせたいという要件が発生することがあります。
他のインスタンスへの操作は一律で禁止したい、というケースです。
ここで前提として知っておくべき Google Cloud の仕様があります。
実は、コンソール上で特定の VM だけを表示し、他の VM の名前を非表示にするような「画面レベルでの絞り込み」はできません。
プロジェクト内のすべての VM 一覧は、どうしても画面上に見えてしまいます。
しかし、一覧は見せるものの、指定した特定の VM 以外は一切操作も SSH 接続もできないという強力なアクセス制限をかけることは可能です。
今回は、標準の IAM 権限と IAP(Identity-Aware Proxy)を組み合わせて、安全に特定の VM へのアクセスだけを限定許可する構築手順を解説します。
前提条件
本手順を実施するにあたり、対象環境で以下の前提条件を満たしていることを確認してください。
-
OS Login の有効化
本設計は、SSH 鍵管理ではなく Google Cloud の IAM でログイン権限を統合管理する OS Login の利用を前提としています。[1]
※セキュリティのベストプラクティスとして、組織ポリシー(constraints/compute.requireOsLogin)等を用いてプロジェクト全体で OS Login を強制することが推奨されています。 -
対象 VM へのサービスアカウント設定
対象の VM インスタンスにサービスアカウント(デフォルトの Compute Engine サービスアカウント、またはカスタムサービスアカウント)がアタッチされていることを確認してください。
システムの全体像と注意点
実際の通信は、以下のように「IAPによるユーザー認証 ➔ ファイアウォールによるアクセス制御」という順番で左から右へと流れていきます。

この通信ルートを安全に構築するために、今回は以下の5つの手順に分けて設定を進めていきます。
- プロジェクト全体への共通権限(一覧表示)の付与
- 対象 VM のサービスアカウントへの権限付与
- 対象の VM インスタンス個別への限定権限の付与
- VPC ネットワークでのファイアウォールルールの作成
- IAP(Identity-Aware Proxy)でのトンネル接続権限の付与
ここで最も注意すべきなのは、IAM 権限の「継承」という仕様です。
よくある設定ミスとして、ステップ1のプロジェクト全体の階層で、誤って「Compute インスタンス管理者(roles/compute.instanceAdmin.v1)」を付与してしまうケースがあります。
Google Cloud の IAM 権限は上位組織から下位リソースへ継承されるため、プロジェクト全体でこの権限をつけてしまうと、プロジェクト内にあるすべての VM インスタンスのフルコントロール権限が有効になります。
その結果、ステップ3で特定の VM に個別権限を設定しても意味がなくなってしまいます。
特定の VM だけに操作を限定するためには、管理者権限はプロジェクト全体ではなく、必ず「対象の VM インスタンス個別(リソース階層)」に対して付与してください。[2]
構築手順
ステップ1:プロジェクト全体への共通権限(一覧表示)の付与
まずはコンソール上で VM インスタンスの一覧画面を表示させるため、最小限の閲覧権限をプロジェクト全体に対して付与します。
- Google Cloud コンソールの [IAM と管理] > [IAM] 画面を開きます。
- 画面上部の アクセス権を付与 をクリックします。
- 新しいプリンシパル に、対象ユーザー(作業担当者やパートナーのメールアドレス)を入力します。
- ロールに以下を選択して、保存 をクリックします。
-
Compute 閲覧者(
roles/compute.viewer):コンソールで VM インスタンスの一覧を表示するための権限
-
Compute 閲覧者(
ステップ2:対象 VM のサービスアカウントへの権限付与
次に、ユーザーが対象 VM を操作する際、その VM に紐づくサービスアカウントを利用できるようにします。
プロジェクト内のすべてのサービスアカウントへのアクセスを防ぐため、対象のサービスアカウントだけに直接権限を設定することがポイントです。
- [IAM と管理] > [サービス アカウント] 画面を開きます。
- 対象の VM インスタンスにアタッチされているサービスアカウントのメールアドレスをクリックします。
- 画面上部の 権限 タブを開き、アクセスを管理する をクリックします。
- ロールに以下を選択して、保存 をクリックします。
-
サービス アカウント ユーザー(
roles/iam.serviceAccountUser):VM に紐づくサービスアカウントを利用するための権限
-
サービス アカウント ユーザー(
ステップ3:対象のVMインスタンス個別への限定権限の付与
次に、操作を許可したい特定の VM に対して個別に権限を紐付けます。
プロジェクト全体の階層ではなく、特定のリソースに対して直接権限を設定することがポイントです。
- [Compute Engine] > [VM インスタンス] 画面へ移動します。
- アクセスを許可したい特定の VM の左側にあるチェックボックスにチェックを入れます。
- 画面右側に開く情報パネル内の 権限 タブを選択します。
- プリンシパルを追加 をクリックし、対象のアカウント名を入力します。
- ロールに以下の 2 つを選択して、保存 をクリックします。
- Compute OS 管理者 ログイン(
roles/compute.osAdminLogin)[3] -
Compute インスタンス管理者(v1)(
roles/compute.instanceAdmin.v1):このインスタンスに対する起動、停止、変更を許可するための権限
- Compute OS 管理者 ログイン(
ステップ4:VPCネットワークのファイアウォールルールの作成
次に、Identity-Aware Proxy(IAP)からの SSH 通信が、VM に正常に到達できるようにネットワークの通信経路を設定します。
- [VPC ネットワーク] > [ファイアウォール] 画面に移動し、ファイアウォール ルールを作成 をクリックします。
- 以下の設定値を入力し、最下部の 作成 をクリックします。
| 設定項目 | 設定値 |
|---|---|
| 名前 |
allow-ssh-from-iap (任意の名前) |
| ネットワーク | 対象の VM が所属する VPC ネットワークを選択 |
| 方向 / 処理 | イングレス(Ingress) / 許可(Allow) |
| ソースIPアドレスの範囲 |
35.235.240.0/20 ※Google の IAP 中継サーバー専用の固定IPアドレス帯です。[4] |
| プロトコルとポート | 「指定したプロトコルとポート」にチェックを入れ、tcp にチェックのうえ 22 と入力 |
ステップ5:IAP(Identity-Aware Proxy)でのトンネル接続権限の付与
最後に、ブラウザから安全に SSH 通信を中継するため、IAP 側の専用画面から VM 単位でのトンネルアクセス権限を付与します。このロールは Compute Engine 側ではなく、IAP の管理画面から設定する点に注意してください。
- コンソールの [セキュリティ] > [Identity-Aware Proxy] 画面を開きます。
- 上部の SSH と TCP のリソース タブを選択します。
- リソース一覧から、アクセスを許可したい特定の VM インスタンスの左側にあるチェックボックスにチェックを入れます(ステップ1でファイアウォールを作成しているため、エラーが出ずに正常に表示されます)。
- 画面右側に表示される情報パネルから プリンシパルを追加 をクリックします。
- ロールに以下を選択して、保存 をクリックします。
-
IAP-secured Tunnel User(
roles/iap.tunnelResourceAccessor):IAP 経由でトンネル接続を行うための権限
-
IAP-secured Tunnel User(
確認方法
設定が完了したら、権限を付与したユーザーアカウントでログインし、意図した通りの制限がかかっているかテストします。
-
VM インスタンス一覧の確認
Compute Engine の画面を開いた際、プロジェクト内にあるすべての VM が一覧として表示されていることを確認します(仕様通りの挙動です)。 -
特定 VM への SSH 接続テスト
アクセスを許可した特定の VM の横にある SSH ボタンをクリックします。別ウィンドウが立ち上がり、正常に OS へログインできれば成功です。 -
他の VM へのアクセス拒否テスト
許可を与えていない別の VM の SSH ボタンをクリックします。権限エラーなどによって接続が完全にブロックされることを確認します。
さいごに
コンソール上で他の VM 名が見えてしまう挙動は、Google Cloud の仕様上どうしても避けられません。
しかし、「名前が見えること」と「操作できること」は別問題です。
プロジェクト全体には一覧が見えるだけの最低限の権限(compute.viewer)だけを渡します。
その上で、サービスアカウントの利用権限、操作権限(compute.instanceAdmin)や OS ログイン、IAP の接続権限は、対象のリソース個別に対してのみ付与します。
これだけで、不要な権限昇格リスクを排除した実務上のアクセス制限が機能します。
何より、この方法を使えば、パッチ当てやアカウント管理などの運用コストがかさむ「踏み台サーバー」をわざわざ 1 台新規で構築して維持する必要がなくなります。
標準の IAM と IAP だけで完結するという極めてシンプルな構成ながら、外部パートナー等に対して最小権限の環境を安全に提供できる、実用的な設計です。
運用の現場で設計に悩む際の選択肢として、ぜひ参考にしてみてください。
-
組織のポリシーを使用して OS Login の一貫した使用を適用する: https://docs.cloud.google.com/compute/docs/connect/ssh-best-practices/login-access?hl=ja ↩︎
-
Compute Engine リソースに対する IAM ロールの管理: https://docs.cloud.google.com/compute/docs/access/managing-access-to-resources ↩︎
-
OS Login の設定: https://docs.cloud.google.com/compute/docs/oslogin/set-up-oslogin ↩︎
-
TCP 転送での IAP の使用(ファイアウォールルールの作成): https://docs.cloud.google.com/iap/docs/using-tcp-forwarding ↩︎
Discussion