クラウド同上

GCEちょい技 – Cloud IAP TCP Forwarding で踏み台サーバ要らずなメンテナンス

Author
Shohei Abe
Lv:9 Exp:13834

2017年10月より入社しました。これまでの技術分野は主にインフラ関係です。
今後はGCPでフルスタック対応できるエンジニアを目指し日々いろいろと活動しています。

外部IPアドレスがないCompute Engine VMにSSH/RDPログインするためには、これまでは
踏み台サーバ(Bastion Server)を経由する必要がありました。
外部IPがなければFWルールの状態にかかわらず外部インターネットからのアクセスを
制限できる反面、踏み台サーバを用意して起動しておく必要があり、余計なコストが
かかっていました。

これから紹介する Cloud IAP TCP Forwarding を使えば、踏み台サーバを用意せずに外部IPアドレスがないVMに対してSSHやRDPログインすることが可能になります。

対象読者

  • Cloud Shellにそんなに抵抗がない
  • コマンド実行のためだけの踏み台サーバの運用がつらい

Cloud Shellの基本的な使い方については、こちらの記事を参考にしてください。

HandsOn環境迷子に贈るCloud Shell

準備作業

最初に、Compute Engine APIを有効化する必要があります。Cloud Shellで以下のコマンドを実行してAPIが有効化されているかを確認してみましょう。

Compute Engine のAPI確認コマンド

$ gcloud services list --filter=NAME:compute

以下のように「Compute Engine API」が表示されれば、Compute Engine APIは有効化されています。

NAME                    TITLE
compute.googleapis.com  Compute Engine API

表示されなかった人は、以下のコマンドで Compute Engine APIを有効化しましょう。

$ gcloud services enable compute.googleapis.com

ネットワークを作成する

VMを作成するネットワークは、 default ネットワークでもよいのですが、
今回はカスタムのネットワークとして iap-test ネットワークを作成して動作を確認してみます。

$ gcloud compute networks create iap-test --subnet-mode=custom

次に、 iap-test ネットワークに東京リージョンの iap-test-tokyo サブネットワークを作成します。
サブネットワークのIPアドレス範囲はなんでもよいですが、今回は 10.10.0.0/16 としました。

gcloud compute networks subnets create iap-test-tokyo \
  --network=iap-test --range=10.10.0.0/16 --region=asia-northeast1

Compute Engine VMを作成する

さて、前述のネットワークにVMを作成します。構築するゾーンは asia-northeast1-b にしました。
特にこだわりはありませんが、VMのOSイメージは Ubuntu18.04LTSを選択しています。
他のOSイメージを使いたい場合は --image-project--image-famiry オプションを使って、別のOSイメージファミリを指定します。
※OSイメージプロジェクトとイメージファミリの一覧は gcloud compute images list で確認できます。
また、マシンタイプは最も安い f1-micro を指定しています。より性能の高いVMを使用したい場合は --machine-type オプションに別のマシンタイプを指定しましょう。

今回の検証で重要なオプションになりますが、外部IPアドレスを付与せずVMを作成する場合は --no-address オプションを指定しましょう。

gcloud compute instances create iap-test \
  --network=iap-test --subnet=iap-test-tokyo \
  --zone=asia-northeast1-b \
  --no-address \
  --machine-type=f1-micro \
  --image-project=ubuntu-os-cloud --image-family=ubuntu-1804-lts

作成が完了しますと、以下のようなメッセージが表示されます。

NAME      ZONE               MACHINE_TYPE  PREEMPTIBLE  INTERNAL_IP  EXTERNAL_IP  STATUS
iap-test  asia-northeast1-b  f1-micro                   10.10.0.2                 RUNNING

もちろん、この状態でSSH接続しようとしても、接続できません。

$ gcloud compute ssh iap-test --zone=asia-northeast1-b
External IP address was not found; defaulting to using IAP tunneling.
ERROR: (gcloud.compute.start-iap-tunnel) Error while connecting [4003: u'failed to connect to backend'].
ssh_exchange_identification: Connection closed by remote host
ERROR: (gcloud.compute.ssh) [/usr/bin/ssh] exited with return code [255].

※「defaulting to using IAP tunneling.」というメッセージも出てますが、とりあえず気にしないでください……

Cloud IAP を有効化する

さて、ここからが本題です。まずは、 Cloud IAP APIを有効化します。

Cloud IAP のAPI確認コマンド

$ gcloud services list --filter=NAME:iap

以下のように「Cloud Identity-Aware Proxy API」が表示されれば、既にAPIは有効化されています。

NAME                TITLE
iap.googleapis.com  Cloud Identity-Aware Proxy API

表示されなかった人は、以下のコマンドでIAP APIを有効化しましょう。

$ gcloud services enable iap.googleapis.com

ユーザーアカウントにCloud IAP TCP Forwardingを許可する

次に、Cloud IAP TCP Forwarding を使いたいユーザーアカウントにアクセス許可を付与します。
まず、使用しているGCPプロジェクトのプロジェクトIDを確認します。確認する方法はいくつかありますが、
手っ取り早く確認するなら Cloud Shell で以下のコマンドを実行しましょう。

$ echo ${DEVSHELL_PROJECT_ID}

Cloud Shell 以外でプロジェクトIDを確認する場合は、 gcloud projects list と実行すると、コマンド実行したときのアカウントで表示可能なGCPプロジェクトの一覧を参照できます。

Cloud IAPを使いたいプロジェクトIDと、ユーザーアカウントのメールアドレスを確認したら、以下のコマンドを実行します。

gcloud projects add-iam-policy-binding MY_PROJECT_ID \
   --member=user:EXAMPLE_USER@EXAMPLE.COM \
   --role=roles/iap.tunnelResourceAccessor

MY_PROJECT_ID は先に確認したGCPプロジェクトIDに、 EXAMPLE_USER@EXAMPLE.COM は許可したいGoogleアカウントのメールアドレスに置き換えてください。

ちなみに、Cloud Console(Webブラウザ)からでも設定可能です。
公式ドキュメントに手順がありますので、こちらを参考に設定してください。

FWルールで許可する

Cloud IAP TCP Forwarding 経由でSSHアクセスさせるために、
Cloud IAPのバックエンドIPアドレス 35.235.240.0/20 をVMのTCP Port22に対してアクセス許可する必要があります。

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

SSHログインしてみる

先ほど失敗した gcloud compute ssh コマンドをもう一度実行してみます。

$ gcloud compute ssh iap-test --zone=asia-northeast1-b --tunnel-through-iap

以下のように、無事ログインすることができました。

Welcome to Ubuntu 18.04.3 LTS (GNU/Linux 4.15.0-1040-gcp x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

...(省略)...

また、Cloud IAP TCP Forwardingを有効化し、アクセス許可している場合は、Cloud ConsoleのSSHボタンからでもログインできるようになります。

Cloud IAP TCP Forwarding のその他使い方について

今回はSSH接続の例を確認しましたが、Windowsサーバの場合は、FWルールでTCP3389ポートを許可すれば、
RDPについても外部IPなしで接続することが可能になります。

FWルール設定例

gcloud compute firewall-rules create allow-iap-forwarding-rdp \
  --network=iap-test \
  --allow=tcp:3339 \
  --source-ranges=35.235.240.0/20

RDP接続するには

残念ながら、SSHとは異なりCloud Consoleから透過的にRDP接続することは現状できないようです。
そのため、Cloud Shellではなく自分の端末にCloud SDKを導入して、以下のコマンドを実行し、
手動で Cloud IAP TCP Forwarding Tunnel を開く必要があります。

gcloud compute start-iap-tunnel iap-test-win 3389 \
  --local-host-port=localhost:13389 --zone=asia-northeast1-b

iap-test-win はWindowsサーバのインスタンス名、 3389 はRDPの標準ポート番号です。

上記のコマンドで重要なオプションは --local-host-port オプションです。
これは、 HOSTNAME:LOCALPORT という形式で設定することで、自分の端末上のどのポートで
通信を行うかを指定します。

上記の例では、 localhostの 13389 で通信を開くように指定していますので、
上記コマンドを実行した後に接続先を localhost:13389 としてRDP接続すると、
RDPログインしたいWindowsサーバにアクセスすることができるようになります。

まとめ

Cloud IAP TCP Forwarding を使用すると、SSHやRDPの踏み台サーバの代わりになります。
その際に設定するべきことは以下の要素になります。

  • Cloud IAP APIの有効化
  • Cloud IAP のバックエンドIPアドレスを許可するFWルール
  • RDP接続の場合は、 gcloud compute start-iap-tunnel コマンドで手動で通信トンネルを開く

SSHやRDPは外部からアタックされやすいプロトコルになります。Cloud IAPを併用して、より強固なセキュリティ設定を実現することができます。

次の記事を読み込んでいます
次の記事を読み込んでいます