はじめに
例えばですが、IPアドレス制限を行っているWebサイト(ex. SaaSのコンソール)に対して、VPNやプロキシを利用し、IPアドレスを固定した上でアクセスしたいケースはままあると思います。
AWSであればClient VPNがあるので、開発ほぼ無しでユースケースを満たすことができますが、Google Cloud(GCP) の公式VPNサービスとしては拠点間VPNしかありません。
(BeyondCorpな世界を目指している以上クライアントVPNはアンチシナジーなのでしょうか。要出典)
GCPで「安全に」「開発少なく(なるべくマネージドで)」「IPアドレス制限で守ったリソースにアクセスする」仕組みを作る場合どうすれば良いでしょうか🤔
ソリューション
主な方法として、マーケットプレイスのクライアントVPNを導入する方法とIdentity-Aware Proxyを利用する方法が考えられます。
1. マーケットプレイスのOpenVPN Access Serverを利用する
ひとつめは、マーケットプレイスを利用してクライアントVPNを導入する方法です。
マーケットプレイスはGoogleから認証を受けたパートナー企業がソフトウェアパッケージを提供するサービスです。
Google Cloud Marketplace は Google Cloud(GCP) の管理コンソールで提供されているカタログサービスです。
Google Cloud Marketplace を使うことで Google Cloud(GCP) 上で利用できる様々なソリューションを検索し、必要に応じてデプロイ(初期設定をして利用可能な状態にすること)まで実行することができます。難しい操作は必要なく、わずか数クリックの作業で必要な処理が完了します。
Google Cloud Marketplace とは?料金体系、メリット、できることまで徹底解説!
前述の通り、GCP公式サービスのクライアントVPNはありませんが、OpenVPN Inc.が提供するOpenVPN Access Server(OpenVPNにGUIベースの管理画面が追加されたソフトウェア)がマーケットプレイス上にあります。
マーケットプレイスをポチるとDeployment Managerのテンプレートが走り、OpenVPN Access Serverが載ったGCEインスタンスがデプロイされます。
人数がスケールすると有料(2アカウントまで無料)ですが、GCPでクライアントVPNを手に入れたい場合の筆頭候補になると思います。
2. iap-connectorを利用する
ふたつめはiap-connectorを利用し、保護したいリソースの前にIdentity-Aware Proxy(IAP)を設置する方法です。
Identity-Aware Proxy(IAP)
まずはIAPのざっくりした概要です。
IAPという用語はGCP固有のものではなく、例えば次に示すのはすべてわかるゼロトラスト大全に記載のIAPの説明です。
アイデンティティー認識型プロキシー(IAP)は、ユーザーとアプリケーションの間に入って通信を仲介するプロキシーである。「アイデンティティー認識型」と呼ばれるのは、ユーザーがアプリケーションにアクセスするたびに、アイデンティティ&アクセス管理(IAM)と連携して認可をやり直すためだ。
IAPはざっくり言うと、ゼロトラストな世界におけるアクセス制御を行うプロキシの総称です。
IAPで保護されたリソースにアクセスを行うと、リクエストの正当性に関する検証が走りアクセスの可否が判断されるようになります。
PomeriumというIAPのOSSがあったりもします。
GCPにおけるIAPは「ゼロトラスト用語としてのIAP」をGCPサービス化したものです。
GAEやLoad Balancing、GCE、Cloud Run(β版)とマネージドに統合されており、デプロイしたWebアプリの前にコマンドひとつでIAPを設置できます。
例えばIAPを設置したGAE上のWebアプリにアクセスすると、「Google Sign-in」即ちGoogleの認証画面が挟まるようになります。
この認証は、事前に許可したアカウント(プリンシパル)だけが通過できます。
GCP Identity-Aware Proxy (IAP), Access Context Managerを使ってみる
Access Context Managerで設定したアクセスレベル(ex. 特定のIPアドレスのみ許可、特定のデバイスのみ許可)をアタッチできたり、Googleアカウントに設定済みのMFAも動作する等、セキュアなアクセス制限を実現できます。
iap-connector
公式ドキュメントのオンプレミスアプリのIAPの概要にも記載がありますが、iap-connectorというGitHubリポジトリをGoogleが公開しています。
リポジトリ上のIaCテンプレートを使うとiap-connector(IAPで保護されたロードバランサ及びGKE)がデプロイされます。
iap-connector上で動いているAmbassadorのOSS(Emissary-ingress1)はドメインのルーティングができるため、「iap-connectorのロードバランサに付与したドメイン」と「保護したいWebサイトのドメイン」をマッピングすれば、iap-connectorへのアクセスがWebサイトに抜けるようになります。
iap-connectorで保護するリソースは任意のWebサーバ(Webアプリ)を指定できます。
バックエンドは任意のWebAPサーバーを指定できるので、(中略)site-to-site VPNやCloud Interconnectで他社クラウドやオンプレミスと閉域ネットワークで接続する構成にすると、既存WebアプリケーションのリバースプロキシとしてCloud IAPを置く構成がイメージできると思います。もちろんInternet FacingなWebアプリケーションをバックエンドとすることもでき、バックエンド側でCloud IAPからのリクエストか否かなどリクエスト真正性を評価したい場合はCloud IAPが付与するJWTトークンを手がかりにすると良いでしょう。
BeyondCorp Remote Accessを支える技術 #1 GCP Cloud IAP connectorを試してみた
IPアドレス制限をかけたWebサイトとiap-connectorを繋げる場合は、Cloud NATでiap-connectorから抜けるIPアドレスを固定すると良いでしょう2。
3. IAP + GCEをSOCKSプロキシ化する
みっつめ、最後は、GCEとssh接続を行いSOCKSプロキシを構成する方法です。
gcloudコマンドを使ったポートフォワード
gcloud compute ssh
コマンドを実行するとGCEインスタンスにssh接続できますが、通常のsshコマンドと同様にダイナミックポートフォワードできます。
ダイナミックポートフォワードとは何ぞやですが、下記の図が非常に分かりやすいと思います。
図のように、sshのクライアントが接続を張っているポート番号をPCやブラウザのSOCKSプロキシとして設定すると、ssh接続先のサーバから通信が抜けるようになります。
【改訂版】SSHポートフォワード(SSHトンネル)【ローカル・リモート・ダイナミック総集編】
gcloud compute ssh
では、次のコマンドでダイナミックポートフォワードができます(「--」以降がsshコマンドのオプションになっています)。
gcloud beta compute ssh --zone "ZONE_NAME" "INSTANCE_NAME" --project "PROJECT_NAME" -- -D 9080
コマンド実行後、9080番ポートでsshクライアントがGCEインスタンス(内のsshd)と接続を張ってくれます。
例えばmacOSにSOCKSプロキシを設定する場合なら、システム環境設定 > ネットワーク > 詳細 > プロキシ > SOCKSプロキシ > localhost:9080
を設定すれば、ブラウザからのアクセス等がGCEのインスタンス経由で抜けるようになります。
もちろん、IPアドレスはGCEインスタンスのものに変わります。
IAPを組み合わせる
ここで、より発展的なセキュリティを考えると、インスタンスに直接グローバルなIPアドレスを付与したくないおキモチが生じます。
結論から言うとgcloud compute ssh
コマンドは、グローバルなIPアドレスを持たないインスタンスに対しても、IAPを介することで接続できます。
手順は公式ドキュメントに記載されている通りなので、詳細は割愛いたします。
先ほどのコマンドに--tunnel-through-iap
を加えるとIAP経由でダイナミックポートフォワードできます。
gcloud beta compute ssh --zone "ZONE_NAME" "INSTANCE_NAME" --tunnel-through-iap --project "PROJECT_NAME" -- -D 9080
iap-connectorと同様、インスタンス自体にはグローバルなIPアドレスがなくても、Cloud NATでIPアドレスを固定すれば本ユースケースを満たせます。
繰り返しにはなりますが、IAPにはAccess Context Managerで設定したアクセスレベルをアタッチできます。
Googleの仕組みに乗っかりつつ、ssh接続のセキュリティを底上げできるのでステキです。
このあたりの設定方法は、以下の記事が詳しかったです。
余談
「なぜIAP経由でssh接続なんてできるのか」については、gcloud SDKとIAP間は通常のhttpsな通信なので、httpsで包んだsshコマンド文を送り、IAP通過後に中身のsshコマンドを取り出し実行しているイメージっぽいですね。
-
元々Ambassador API Gatewayという名前だったがCNCF加入に伴い改名 ↩
-
デプロイされたiap-connectorはただのGKE等なので、いつもと変わらず設定ができます。できればIaCに組み合わせたいところ ↩