GCP Cloud IAP経由のSSH接続にグローバルIP制限を組み込む

Cloud IAP(Identity-Aware Proxy)を使うと所謂Bastion(踏み台)インスタンスを構築せずとも、GCPに安全に接続できる構成が作れます。そこにGlobal IP制限も加えられるか設定してみました。

cloud.google.com

前提

この機能の主要コンポーネントのAccess Context Managerを利用するためには、組織が登録済みであることが必要です。

cloud.google.com

[組織作業] グローバルIP制限用のアクセスレベルを作成

Access Context Managerにてアクセスレベルを作成しますが、組織で作業する必要があります。

組織でなく、プロジェクトを指定している状態では、Access Context Managerは以下のような画面になります。

矢印をプロジェクトでなく組織に変更してください。そうすると新規のアクセスレベルを定義できるようになります。

今回は以下のように、自身のPCのGlobal IP xxx.xxx.xxx.77 であるというアクセスレベルを定義してみます。これに合致しない場合はSSHを拒否する設定にします。

otomo_gip というアクセスレベルが作成できました。

IAMユーザ準備

組織からプロジェクトに切り替えて、以下のIAMユーザで作業します。

以下のようなIAMユーザを使います。OSログイン権限をつけておきます。

f:id:yomon8:20191128190538p:plain

ネットワークとVMの作成

動きの確認用に適当なネットワークとVMを作成します。

ネットワーク作成

まずは適当なネットワークを作成します。

gcloud compute networks create vpc-iap-test --subnet-mode=custom
gcloud compute networks subnets create private-subnet --network vpc-iap-test --range 192.168.1.0/24 --region asia-northeast1

IAPからのアクセス用Firewallルール作成

IAPのレンジである 35.235.240.0/20 からのSSHアクセスをタグ iap-tunnel-ssh に許可します。

gcloud compute firewall-rules create allow-iap-tunnel-ssh \
  --network=vpc-iap-test \
  --allow=tcp:22 \
  --target-tags iap-tunnel-ssh \
  --source-ranges=35.235.240.0/20

VMの作成

以下のようにVMを作成します。外部IP無しで作成します。

--metadata=enable-oslogin=TRUE の設定が一つポイントになります。

gcloud compute instances create my-private-instance \
  --machine-type=f1-micro \
  --zone asia-northeast1-a \
  --subnet=private-subnet \
  --private-network-ip=192.168.1.10 \
  --tags=iap-tunnel-ssh \
  --no-address \
  --boot-disk-size=10GB \
  --metadata=enable-oslogin=TRUE

IAPにてGlobal IPの制限付きのアクセス許可設定

IAPで先程作成したGlobal IP制限のアクセスレベルを組み込んだ権限設定をします。

対象のインスタンスでメンバーの追加をします。

otomo-testユーザを IAP-secured Tunnel User で登録。 その際に条件の追加を選択します。

先程設定した otomo_gip のアクセスレベルを設定します。

設定を保存してみると以下のように条件付きで権限が付与される状態になります。

挙動確認

以下のようにSSHで接続しようとすると、設定したGlobal IPだと接続できますが、

$ gcloud compute ssh my-private-instance

他のGlobal IPからだと以下のようにエラーになります。想定通りの動きのようです。

$ gcloud compute ssh my-private-instance
No zone specified. Using zone [asia-northeast1-a] for instance: [my-private-instance].
External IP address was not found; defaulting to using IAP tunneling.
ERROR: (gcloud.compute.start-iap-tunnel) Error while connecting [4033: u'not authorized'].
ssh_exchange_identification: Connection closed by remote host
ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255].

以下が実際の画面です。

元のGlobal IPで繋いで、携帯のデザリングにWifi切り替えたら接続できなくなって、元に戻したら接続できています。

基本的な構成で書いたので、これを元に組めば色々できそうな感じでした。