VM インスタンスへの安全な接続

Compute Engine でプロジェクトを開発する場合、以下のような状況では、インスタンスが公共のインターネットからアクセスされないようにする必要があります。

  • ウェブサービスがまだ開発中で、機能が不完全であるか、まだ HTTPS を使うように構成されていないために、外部ユーザーに公開する準備が整っていない。
  • インスタンスは、プロジェクト内の他のインスタンスによってのみ消費されるように設計されたサービスを提供している可能性がある。
  • 企業のオフィスやデータセンターなど、専用の相互接続オプションを通じてのみ、インスタンスに到達できる必要がある。

サービスが意図的にインターネットに接続されている場合でも、機密情報を守るため、サービスとの通信を対象のユーザー グループに制限し、SSH や HTTPS などの安全なチャネルを通じて行うことが重要です。

この記事では、外部 IP アドレスを持つ Compute Engine インスタンスや外部 IP アドレスを持たない Compute Engine インスタンスと安全に通信するための方法を紹介します。

外部 IP アドレスを持つマシン上のサービスの保護

外部 IP アドレスを持たないインスタンスへの接続

外部 IP アドレスを持つマシン上のサービスの保護

インスタンスにパブリック IP アドレスがある場合、公開を意図したサービスとトラフィックのみに到達可能であり、公開されているサービスで転送中の機密情報が保護されることが重要です。

ファイアウォール

まず行うべき防御は、ファイアウォールを使って、インスタンスに到達できる人を制限することです。ファイアウォール ルールを作成することで、ネットワークやターゲット マシンの特定のポートセットへのすべてのトラフィックを、特定のソース IP アドレスに制限できます。

ファイアウォールはスタンドアロン ソリューションではありません。トラフィックを特定のソース IP に制限しても、ログイン認証情報、リソースやファイルを作成または破棄するコマンド、ログなどの機密情報は保護されません。一般公開されたマシンで、外部 IP を使用する Compute Engine インスタンスなどのウェブサービスを実行する場合は、適切なセキュリティを確保するために、ホストとデプロイされたインスタンスの間の通信をすべて暗号化する必要があります。

また、ファイアウォールは常に適切なソリューションであるとは限りません。たとえば、ローミング ラップトップなど、静的な IP アドレスを持たない開発環境では、ファイアウォールは理想的ではありません。

HTTPS と SSL

本番環境用のウェブシステムでは、HTTPS/SSL を構成します。HTTPS/SSL を構成するには、HTTPS を終端するインスタンスをセットアップするか、HTTPS 負荷分散を構成します。HTTPS/SSL により当初の複雑さが増え、以下の作業を行う必要があります。

  • ドメイン名を登録します。
  • 認証局から SSL 証明書を取得します。
  • 証明書をロードバランサとその接続されたインスタンスに登録するか、SSL 終端するウェブサーバーやプロキシを、1 つ以上の Compute Engine インスタンス上で構成します。

SSL サービス ドメインを以前にセットアップしている場合は、Compute Engine でも同様の設定を簡単に行うことができます。そうでない場合は、ポート転送SOCKS プロキシなどの別のセキュリティ手段を使う方が簡単である可能性があります。

SSH 上のポート転送

gcloud コマンドライン ツールを使って特定のローカルポートでサーバーを起動します。これにより、SSH 接続を介してすべてのトラフィックをリモートホストに転送できます。

まず、安全な接続を確立する必要があるサービスを提供しているインスタンスとポートをメモします。次に、以下のコマンドを実行します。

gcloud compute ssh example-instance \
    --project my-project \
    --zone us-central1-a \
    -- -L 2222:localhost:8888

上記のコマンドで、パラメータは次のように定義されています。

  • example-instance は接続先のインスタンスの名前です。
  • my-project はユーザーの Google Cloud プロジェクト ID です。
  • us-central1-a は、インスタンスが稼働しているゾーンです。
  • 2222 は、リッスンするローカルポートです。
  • 8888 は接続先のリモートポートです。

これらの設定例では、ブラウザで http://localhost:2222/ を開くと、HTTP 接続でリモートホストに作成した SSH トンネルが使用され、指定したインスタンスに SSH 経由で接続します。接続後、暗号化された安全な SSH 接続により同じマシンのポート 8888 に接続します。

gcloud コマンドは SSH 接続を作成および維持します。このアプローチは、SSH セッションがアクティブな間だけ機能します。gcloud で作成された SSH セッションを終了するとすぐに、http://localhost:2222/ を使用したポート転送は終了します。

複数のポート転送ルールを作成する場合は、フラグを繰り返すことで 1 つのコマンドライン上で複数のルールを指定できます。

gcloud compute ssh example-instance \
    --project my-project \
    --zone us-central1-a \
    -- -L 2222:localhost:8888 -L 2299:localhost:8000

また、新たな gcloud コマンドを何度か実行して、個別のトンネルを作成することもできます。既存の接続にポート転送を追加または削除するには、その接続を終了して初めから再確立する必要があることに注意してください。

SSH 上の SOCKS プロキシ

クラウド環境にある複数のホストに接続する場合、ネットワークから直接検索するようにブラウザを変更するのが最も簡単な方法です。このアプローチでは、各ホストの IP アドレスを検索したり、各サービスのポートをオープンしたり、各ホスト / ポートペアについて SSH トンネルを作成する代わりに、短いホスト名を使用できます。

ここで使うアプローチは以下のとおりです。

  1. ネットワーク上のいずれかのホストへの単一の SSH トンネルをセットアップし、そのホスト上で SOCKS プロキシを作成します。
  2. その SOCKS プロキシホストを使用してすべての検索を行うようにブラウザの構成を変更します。

すべてのトラフィックがそのホストを使用してトンネリングされるため、ウェブを閲覧するときに、そのブラウザや特定のプロファイルを使用しないでください。この帯域幅はクラウド サービス専用にする必要があります。一般的に、別のブラウザ プロファイルを使用し、必要に応じて切り替えることをおすすめします。

SOCKS プロキシの起動

SOCKS プロキシを起動するには、次のコマンドを実行します。

gcloud compute ssh example-instance \
    --project my-project \
    --zone zone \
    --ssh-flag="-D" \
    --ssh-flag="NNNN" \
    --ssh-flag="-N"

以下を置き換えます。

  • example-instance: 接続先のインスタンスの名前。
  • my-project: Google Cloud プロジェクト ID
  • zone: インスタンスが実行されているゾーン(us-central1-a など)。
  • NNNN: リッスンするローカルポート(1080 など)。

ここでは、リモートポートを指定する必要がないことに注意してください。SOCKS プロキシは、特定のリモートポートにバインドしないため、SOCKS プロキシを使用して行ったすべての接続は、接続先のホストとの相対で解決されます。

SOCKS プロキシを使えば、インスタンスの短縮名を使うことで、プロキシ インスタンスと Compute Engine ネットワークを共有する任意のインスタンスに接続できます。また、特定のインスタンス上の任意のポートに接続できます。

このアプローチは、単純なポート転送による手法よりもはるかに柔軟ですが、プロキシを使用するようにウェブブラウザの設定を変更する必要があります。

次に、プロキシを使用するように Chrome または Firefox を構成します。

Chrome

Chrome はシステム全体のプロキシ設定をデフォルトで使用するため、コマンドライン フラグを使って異なるプロキシを指定する必要があります。デフォルトで Chrome を起動すると、すでに実行されているプロファイルのインスタンスが作成されます。Chrome を複数のコピーで同時に実行できるようにするには、一方はプロキシを使用し、それ以外はプロキシを使用しないため、新しいプロファイルを必要とします。

新しいプロファイルを使って Chrome を起動します。存在しない場合は新しいプロファイルが自動的に作成されます。

Linux:

/usr/bin/google-chrome \
    --user-data-dir="$HOME/chrome-proxy-profile" \
    --proxy-server="socks5://localhost:1080"

macOS:

"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \
    --user-data-dir="$HOME/chrome-proxy-profile" \
    --proxy-server="socks5://localhost:1080"

Windows:

"C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" ^
    --user-data-dir="%USERPROFILE%\chrome-proxy-profile" ^
    --proxy-server="socks5://localhost:1080"

localhost のポートは、以前 gcloud コマンドで使用した値を設定します(この例では 1080)。

Firefox

これらの設定を変更する前に、新しい Firefox プロファイルを作成することをおすすめします。新しいプロファイルを作成せずにホストがプロキシとして使われると、すべての Firefox インスタンスに影響し、それは多くの場合望ましい動作ではありません。

別のプロファイルを使って Firefox を実行した後、SOCKS プロキシを設定できます。

  1. [オプション] を開きます。
  2. [詳細設定] > [ネットワーク] > [設定] を順にクリックし、[接続設定] ダイアログを開きます。
  3. オプション [手動でプロキシを設定する] を選択します。
    1. [SOCKS ホスト] セクションで、ホストとして「localhost」と入力し、以前に gcloud コマンドを実行したときに選択したポートを入力します。
    2. [SOCKS v5] を選択します。
    3. [リモート DNS] をチェックボックスをオンにします。
    4. 他のエントリはすべて空白のままにします。
  4. [OK] をクリックし、[設定] ダイアログ ボックスを閉じます。

外部 IP アドレスを持たないインスタンスへの接続

外部 IP アドレスを持たないインスタンスにアクセスするには、そのインスタンスと同じネットワーク上にあるか、Identity-Aware Proxy の TCP 転送機能またはマネージド VPN ゲートウェイを使用する必要があります。ネットワーク内のインスタンスを、受信接続(踏み台インスタンス)または下り(外向き)ネットワーク(NAT ゲートウェイ)用の信頼できるリレーとしてプロビジョニングできます。そのような接続の設定が不要なより透過的な接続のためには、管理された VPN ゲートウェイ リソースを使用できます。

踏み台インスタンス

次の図に示すように、踏み台インスタンスは、プライベート ネットワーク インスタンスを含むネットワークへの外部に面するエントリ ポイントを提供します。

踏み台インスタンスのアーキテクチャは、プライベート インスタンスのネットワークへの外部に面するエントリ ポイントとして機能します。

このホストは、要塞化や監査のための単一の場所を提供します。また、SSH 通信を有効または無効にするために開始および停止できます。踏み台インスタンスを使用すると、外部 IP アドレスがないインスタンスに接続できます。このアプローチでは、開発環境に接続するだけでなく、追加のファイアウォール ルールを構成しないで外部アプリケーションのデータベース インスタンスを管理できます。

踏み台インスタンスの完全な強化は、本ドキュメントの範囲外ですが、実施する最初のステップには以下のものが挙げられます。

  • 要塞と通信できるソース IP の CIDR 範囲を制限します。
  • 踏み台インスタンスからのみプライベート インスタンスへの SSH トラフィックを許可するように、ファイアウォール ルールを構成します。

デフォルトでは、インスタンス上の SSH は、認証用に秘密鍵を使用するように構成されます。踏み台インスタンスを使用する場合、まず踏み台インスタンスにログインし、次にターゲット プライベート インスタンスにログインします。このように、踏み台インスタンスが「ジャンプ サーバー」と呼ばれる理由である 2 段階ログインがあるため、ターゲット マシンにアクセスする方法として、ターゲット マシンの秘密鍵を踏み台インスタンスに保存する代わりに ssh 転送を使用する必要があります。これは、踏み台インスタンスとターゲット インスタンスに同じ鍵ペアを使用する場合でも必要です。踏み台インスタンスは、鍵ペアの公開鍵にしか直接アクセスできないためです。

踏み台インスタンスを使用して Google Cloud ネットワーク上の他のインスタンスに接続する方法については、踏み台インスタンスを介した接続をご覧ください。

ssh 転送などの方法で外部 IP アドレスを持たないインスタンスに接続する方法については、外部 IP アドレスを持たないインスタンスへの接続をご覧ください。

TCP 転送での IAP

SSH と IAP の TCP 転送機能を使用すると、SSH 接続が HTTPS にラップされます。IAP の TCP 転送機能は、それをリモート インスタンスに送信します。

IAP を使用してリモート インスタンスに接続する方法については、IAP を TCP 転送に使用するをご覧ください。

VPN

Cloud VPN では、既存のネットワークを IPsec 経由で Google Cloud ネットワークに接続し、VPN ゲートウェイ デバイスにアクセスできます。これにより、各自の構内から Compute Engine インスタンスのプライベート IP インターフェースへの、トラフィックの直接ルーティングが可能になります。公開リンク経由で Google に転送される途中のトラフィックは暗号化されます。

Compute Engine で VPN を使用するためのセットアップ、構成、使用方法については、Cloud VPN のドキュメントをご覧ください。

インスタンスの外部 IP アドレスではなく、既存の VPN 経由で Google Cloud ネットワーク上のインスタンスに接続する方法については、外部 IP アドレスを持たないインスタンスへの接続をご覧ください。

NAT ゲートウェイを使ったトラフィックの送信

インスタンスに外部 IP アドレスが割り当てられていない場合、他の Google Cloud サービスを含め、外部サービスに直接接続できません。これらのインスタンスが公共のインターネット上のサービスに到達できるようにするには、ネットワーク上のすべてのインスタンスの代わりにトラフィックをルーティングできる、NAT ゲートウェイ マシンをセットアップして構成できます。単一インスタンスは高可用性ではなく、複数のインスタンスの高スループットのトラフィックをサポートすることはできません。

インタラクティブ シリアル コンソール アクセス

インスタンスに外部 IP アドレスがなくても、トラブルシューティングやメンテナンスを目的としてインスタンスを操作することが必要になる場合があります。前述したように、踏み台インスタンスをセットアップすることは 1 つの方法ですが、ニーズに見合うよりも多くのセットアップが必要になる可能性があります。外部 IP アドレスを持たないインスタンスをトラブルシューティングする場合は、シリアル コンソール上でインタラクティブ アクセスを有効にすることを検討してください。これにより、SSH を使ってインスタンスのシリアル コンソールを操作し、シリアル コンソールに対してコマンドを実行できます。

詳しくは、シリアル コンソールを使った操作をご覧ください。

HTTPS および SSL プロキシ ロードバランサ

HTTPS および SSL プロキシ ロードバランサのバックエンドであるインスタンスには、ロードバランサを介してアクセスするための外部 IP アドレスは不要です。これらのリソースに直接アクセスするには、外部 IP アドレスを持たないインスタンスへの接続に記載されている方法を使用する必要があります。

詳細については、それらのロードバランサに関するロードバランサのドキュメントをご覧ください。

Google Cloud のその他の機能を試す。チュートリアルをご覧ください。