SSH 認証情報を保護するためのベスト プラクティス


このドキュメントでは、SSH 認証情報を保護するためのベスト プラクティスについて説明します。

デフォルトでは、Compute Engine は公開鍵ベースの SSH 認証を使用します。ユーザーは、SSH 秘密鍵である「所持しているもの」によって認証されます。ユーザーの秘密鍵が適切に保護されていない場合、悪意のあるユーザーがこれらの鍵を使用して VM インスタンスにアクセスする可能性があります。

以降のセクションでは、鍵の漏洩を防ぎ、秘密鍵が漏洩した場合の影響を軽減するためのベスト プラクティスについて説明します。

このドキュメントでは、Google Cloud に固有のプラクティス、または Google Cloud で SSH を使用する場合に特に関連性の高いプラクティスに焦点を当てて説明します。このドキュメントでは、特定の SSH クライアントまたはサーバーの実装に関するベスト プラクティスについては説明しません。

SSH 秘密鍵をサービス アカウント キーと同様に扱う

一部の VM インスタンスには、サービス アカウントが関連付けられている場合があります。サービス アカウントを VM に関連付けると、これらの VM で実行されているワークロードは、メタデータ サーバーから有効期間の短いアクセス トークンをリクエストして、Google Cloud APIs とリソースにアクセスできるようになります。

SSH を使用して、サービス アカウントが割り当てられた VM に接続する場合は、メタデータ サーバーから有効期限の短いアクセス トークンをリクエストすることもできます。したがって、ユーザーに VM への SSH アクセス権を付与することは、割り当てられたサービス アカウントとして機能する権限をユーザーに付与することに似ています。そのため、SSH 秘密鍵、特にパスフレーズで保護されていない場合は、サービス アカウント キーと同様に扱う必要があります。どちらの種類の鍵も、漏洩すると、悪意のあるユーザーが Google Cloud リソースにアクセスできる可能性があります。

マシンユーザーにエフェメラル SSH 認証鍵を使用する

デプロイ パイプラインまたは自動化プロセスでは、デプロイの実行や構成変更の適用に VM インスタンスへの SSH アクセスが必要になる場合があります。これらのワークロードで長期間有効な SSH 鍵ペアを使用する代わりに、実行するたびに新しいエフェメラル SSH 鍵を使用します。

エフェメラル SSH 鍵を使用するには、デプロイ パイプラインまたは自動化プロセスで次の操作を行います。

  1. 鍵やシークレットを使用しない方法でサービス アカウントとして認証する(関連付けられたサービス アカウントWorkload Identity 連携の使用など)。
  2. ssh-keygen などのツールを使用して、一時的な SSH 認証鍵ペアを生成します。
  3. 公開鍵を Google Cloud に公開し、近い将来の有効期限を指定します(1 時間後など)。

    OS Login では、鍵を公開するときに鍵の有効期限を指定できます。同様に、プロジェクトまたは VM メタデータに SSH 公開鍵を公開するときに、有効期限を指定できます。

  4. 秘密鍵を使用して、VM インスタンスへの SSH 接続を確立します。

  5. 必要に応じて、公開鍵の公開を取り消し、秘密鍵を削除します。

例:

# Generate RSA key pair without passphrase
ssh-keygen -t rsa -f ephemeral_key -q -N "" -V 30m

# Publish key to the service account's OS Login profile, with 30 min expiry
gcloud compute os-login ssh-keys add --key-file ephemeral_key.pub --ttl 30m

# Look up the service account's UNIX username
USERNAME=$(gcloud compute os-login describe-profile --format "value(posixAccounts[0].username)")

# Authenticate using the service account's UNIX user and public key
ssh $USERNAME@VM whoami

# Remove key
gcloud compute os-login ssh-keys remove --key-file ephemeral_key.pub

エフェメラル SSH 秘密鍵は漏洩する可能性がありますが、短時間しか使用できません。したがって、エフェメラル SSH 鍵を使用すると、認証情報の漏洩リスクを軽減し、認証と認可の主な手段として Cloud IAM を使用できます。

IAP を使用して SSH 公開鍵認証を補完する

デフォルトでは、SSH 秘密鍵は Google 認証情報とは別に使用できます。ユーザーの SSH 秘密鍵が漏洩した場合、不正な行為者はその鍵を使用して、鍵がアクセスを許可されている VM インスタンスに接続し、認証を行うことができます。攻撃者がユーザーのユーザー名やパスワードを知っている必要はなく、Google の認証情報を所有している必要もありません。

2 段階認証プロセスGoogle Cloud サービスのセッション継続時間の制限などのセキュリティ管理は、認証情報の不正使用のリスクを軽減する効果的な方法ですが、これらの管理は Google の認証情報を必要とするリソースにのみ適用されます。

有効な Google の認証情報なしで SSH 認証鍵を使用できないようにするには、IAP を使用して SSH アクセスを管理し、ファイアウォール ポリシーを使用して、すべての SSH アクセスが IAP を介して実行されるようにします。

IAP はリバース プロキシとして機能し、Google の認証情報を使用して正常に認証された場合にのみ、VM インスタンスへの SSH 接続を確立できます。また、IAP を使用すると、ユーザーが接続できる VM を制限し、コンテキスト アウェア アクセスを適用できます。

多要素認証を使用する

IAP を使用して SSH アクセスを管理すると、不正な行為者が漏洩した認証情報を悪用して VM インスタンスにアクセスすることは難しくなりますが、不可能になるわけではありません。たとえば、不正な行為者がワークステーションに侵入して、SSH 秘密鍵とキャッシュに保存された gcloud CLI 認証情報の両方を見つけた場合、IAP の認証と認可のチェックに合格してユーザーの VM インスタンスに接続できる可能性があります。

多要素認証(MFA)を必須にするように Cloud Identity または Google Workspace を構成すると、このような認証情報の盗難による影響を軽減できます。

Cloud Identity または Google Workspace がプライマリ ID プロバイダである場合は、次の手順で MFA を適用します。

  1. 2 段階認証を適用するように Cloud Identity または Google Workspace を構成します。
  2. Google Cloud サービスのセッションの長さを制限して、キャッシュ内の認証情報を自動的に無効にします。これにより、ユーザーは定期的に再認証して MFA を実行する必要があります。

外部 IdP でシングル サインオンを使用する場合は、代わりに次の操作を行います。

  1. Google Cloud サービスのセッションの長さを制限するように Cloud Identity または Google Workspace を構成します。これにより、キャッシュ内の認証情報が自動的に無効になり、ユーザーは外部 IdP を使用して定期的に再認証を行う必要があります。
  2. 外部 IdP で多要素認証を必須とし、セッションの長さを制限して、Google Cloud セッションの有効期限が切れるたびにユーザーが多要素認証を実行するようにします。

多要素認証を SSH アクセスにも適用するには、次のいずれかを行う必要があります。

  1. IAP を使用してネットワーク アクセスを制御し、ユーザーが Google 認証情報を更新するために定期的に MFA を実行するようにします。
  2. 個々の VM インスタンスまたはプロジェクト全体で OS Login 2FA を有効にすると、ユーザーは SSH 接続を確立するたびに多要素認証を行う必要があります。

Compute インスタンス管理者か、VM インスタンスまたはプロジェクトの同等のロールを所有しているユーザーは、インスタンス メタデータを変更することで OS Login 2FA を無効にできます。したがって、Cloud Identity または外部 IdP で多要素認証を適用していない場合、OS Login 2FA の効果は限定的です。

エクスポート不可またはパスフレーズで保護された秘密鍵を使用する

多くの SSH クライアントでは、デフォルトで SSH 秘密鍵がディスク上にファイルとして保存されます。たとえば、gcloud compute ssh は初めて使用したときに SSH 認証鍵ペアを生成し、それをホーム ディレクトリに保存します。オペレーティング システムは、他のユーザーによるファイルへのアクセスを防ぐことができますが、不正な行為者がファイル システムの権限を回避できれば(たとえば、ディスクをコピーして別のマシンにマウントするなど)、鍵を別の場所にコピーして、ユーザーの知らないうちに使用できます。

一部の SSH クライアントでは、ファイルベースの鍵の使用を回避し、SSH 秘密鍵を管理するための代替オプションを提供しています。

  • ハードウェア保護キーの使用: 最新バージョンの OpenSSH では、FIDO2 セキュリティ キーを認証に使用できます。また、Cloud Identity または Google Workspace に登録されているセキュリティ キーのみを許可するように OS Login を構成できます。ハードウェア格納型キーを使用すると、秘密鍵マテリアルをパソコンのファイル システムに保存する必要がなくなります。
  • オペレーティング システムの鍵保管ツールを使用する: たとえば、IAP Desktop はファイルベースの鍵の使用を避け、代わりに Windows CNG を使用して SSH 鍵を保護します。

ハードウェア格納型キーまたはオペレーティング システム管理の鍵を使用できない場合は、パスフレーズを使用して SSH 秘密鍵を保護できます。パスフレーズで保護された SSH 鍵を使用するには、秘密鍵のコピーだけでなく、鍵のパスフレーズも知っている必要があります。

ホストキーを使用してホストを認証する

VM インスタンスへの SSH 接続を作成するときに、VM インスタンスの名前または IP アドレスで VM インスタンスを識別します。名前と IP アドレスは再割り当てと再利用が可能です。特定の VM インスタンスに関連付けられた名前が、翌日は別の VM インスタンスに関連付けられている場合もあります。不正な行為者が、VM インスタンスをスプーフィングするために、名前または IP アドレスを故意に再割り当てまたは再利用し、ユーザーをだまして、侵害された VM に接続させようとする可能性があります。

SSH クライアントは、SSH ホストキーを使用して、以前に信頼された VM インスタンスが別の VM インスタンスに置き換えられた状況を検出できます。VM の SSH ホストキーは最初の起動時に生成され、インスタンスの識別に使用されます。通常、SSH クライアントは最初の接続で VM のホストキーをリクエストして保存し、その後の接続で VM のホストキーが変更されていないことを確認します。

SSH ホストキーは、初回使用時の信頼スキームに基づいて機能します。不正な行為者が中間者(MITM)攻撃を実行し、クライアントが初めて使用したときに間違った VM に接続して信頼するようにした場合、SSH ホストキーの有効性が損なわれる可能性があります。ホストキーを取得する良い方法は、VM に初めて接続する前に、信頼できるサイドチャネルを介して取得する方法です。

プロジェクトでゲスト属性を有効にして、バックチャネル経由でホストキーを取得するように gcloud CLI に指示できます。これにより、gcloud CLI は VM に初めて接続する前に VM のホストキーを読み取り、ローカル コンピュータに保存します。

VM に個人の認証情報を残さない

gcloud CLI を認可すると、ツールは OAuth 更新トークンを取得してローカルのホーム ディレクトリに保存します。その後 gcloud CLI コマンドを実行すると、gcloud CLI は更新トークンを使用して自動的に認証を行います。

ローカル コンピュータには他のユーザーがアクセスできない場合がありますが、VM インスタンスの場合、VM に対する sudo 権限を持つ他のユーザーもホーム ディレクトリにアクセスできます。

不正な行為者が VM で sudo 権限を取得すると、他のユーザーのホーム ディレクトリで更新トークンなどの認証情報をスキャンし、これらの認証情報を使用して権限を昇格させたり、他のリソースへのアクセス権を拡張する(ラテラル ムーブメント)可能性があります。

SSH 経由で VM インスタンスに接続する場合は、個人の認証情報で gcloud CLI またはアプリケーションのデフォルト認証情報(ADC)を承認せず、代わりに gcloud CLI が VM に接続されたサービス アカウントを使用するようにします。同様に、個人の認証情報をホーム ディレクトリに保存する可能性のある他のツールを実行しないようにしてください。

保存されている OAuth 更新トークンが一定期間後に自動的に期限切れになるように、Google Cloud サービスのセッション継続時間を制限することで、リスクをさらに軽減できます。

SSH 秘密鍵をソースコード リポジトリに送信しない

Ansible などの一部の自動化ツールは、SSH を使用して VM インスタンスにアクセスして管理します。このようなツールは多くの VM インスタンス(とそれらに関連付けられているサービス アカウント)にアクセスできる可能性があるため、このようなツールで使用される SSH 秘密鍵は特に機密性が高い場合があります。

SSH 秘密鍵をソースコード リポジトリに送信すると、未承認のユーザーや不正な行為者が鍵にアクセスするリスクが高くなります。

  • 不正な行為者が公開のソース リポジトリにあるソースコードをスキャンし、鍵を盗み出す可能性があります。
  • 現在は非公開のソース リポジトリを使用していても、鍵の漏えいをチェックせずに公開リポジトリに切り替えることがないとは言えません。
  • 別のチームのメンバーが自分のワークステーションにソースコードのコピーを保存している可能性もあります。

これらのリスクを軽減するには、SSH 秘密鍵をソースコードとは別の安全な場所に保存します。また、可能であればエフェメラル SSH 鍵を使用します。

次のステップ