GCP IAP tunnel を HTTP プロキシを通して利用する場合の注意点
[履歴] [最終更新] (2021/08/14 23:55:34)
最近の投稿
注目の記事

概要

グローバルIP を持たない GCP VM への SSH 接続方法』で記載した IAP tunnel は、HTTPS トンネル内で TCP パケットを forward するための技術です。

この HTTPS トンネルは、ユーザと tunnel.cloudproxy.app の間で確立される WebSocket です。

そのため、IAP tunnel を HTTP プロキシ環境下で利用する際には、以下の二つに注意する必要があります。

  • tunnel.cloudproxy.app への通信を許可する。
  • tunnel.cloudproxy.app との WebSocket 接続が問題なく行える。

tunnel.cloudproxy.app への通信を許可

こちらのページに記載のとおりです。HTTP プロキシサーバで通信の許可対象 whitelist を制御している場合は、whitelist に tunnel.cloudproxy.app を含める必要があります。

tunnel.cloudproxy.app との WebSocket 接続

IAP tunnel で利用されるプロトコルおよびサーバ

IAP tunnel は、Cloud IAM による認証が行われた後に作成される、ユーザと Cloud IAP の間の HTTPS トンネルです。
HTTPS トンネルによって、SSH や RDP といったアプリケーションのための TCP パケットを forward します。

Uploaded Image

Overview of TCP forwarding

公式のドキュメントに明記されている箇所はありませんが、この HTTPS は具体的には、ユーザと tunnel.cloudproxy.app の間に作成される WebSocket 接続です。より正確には WebSocket over SSL/TLS です。URI スキームとしては ws: ではなく wss: です。

SSH/RDP
----------
TCP
----------
HTTP ->(upgrade)-> WebSocket
----------
SSL/TLS
----------
TCP

SSH from browser 機能を実行した際の WebSocket 接続

Uploaded Image

参考資料:

The IAP TCP forwarding tunnels that IAP Desktop uses to create SSH and RDP connections use WebSockets. Make sure that your proxy server permits WebSocket communication to the following domain: https://tunnel.cloudproxy.app

GoogleCloudPlatform / iap-desktop / Proxy Configuration

HTTP プロキシを通した場合

HTTP プロキシを通して GCP と通信する際には、

  • 通信プロトコルが https であるか wss であるか。
  • HTTP プロキシによる SSL Inspection の有無。

上記二つの観点から、以下の 4 つの場合が存在します。

User ----------- HTTP ------------ googleapis.com
User ---------- SSL/TLS ---------- googleapis.com
User --- TCP --- Proxy --- TCP --- googleapis.com


User --- HTTP -- Proxy --- HTTP -- googleapis.com
User - SSL/TLS - Proxy - SSL/TLS - googleapis.com
User --- TCP --- Proxy --- TCP --- googleapis.com


User ---------- SSH/RDP ---------- tunnel.cloudproxy.app
User ------------ TCP ------------ tunnel.cloudproxy.app
User --------- WebSocket --------- tunnel.cloudproxy.app
User ---------- SSL/TLS ---------- tunnel.cloudproxy.app
User --- TCP --- Proxy --- TCP --- tunnel.cloudproxy.app


User - SSH/RDP - Proxy - SSH/RDP - tunnel.cloudproxy.app
User --- TCP --- Proxy --- TCP --- tunnel.cloudproxy.app
User - WebSocket Proxy - WebSocket tunnel.cloudproxy.app
User - SSL/TLS - Proxy - SSL/TLS - tunnel.cloudproxy.app
User --- TCP --- Proxy --- TCP --- tunnel.cloudproxy.app

ここで問題になるのは 4 つ目のパターンです。多くの HTTP プロキシは 4 つ目のパターンをサポートしておらず、SSL Inspection を WebSocket と併用できません。その場合、SSL Inspection を用いる場合には tunnel.cloudproxy.app に対して 3つ目のパターンになるように、プロキシを設定する必要があります。

参考資料:

Note: Squid (and possibly other proxy servers) does not allow WebSocket connections when configured to perform SSL inspection (bumping). To allow WebSocket communication, exclude tunnel.cloudproxy.app from SSL termination by letting Squid splice connections to this domain.

GoogleCloudPlatform / iap-desktop / Proxy Configuration

例えば、Google の Block access to consumer accounts 機能を利用する場合に、4つ目のパターンが発生します。

Squid における SSL bumping (Interception / Inspection)

Squid における SSL Inspection は SSL bumping として実装されています。SSL bumping のバージョンは過去の経緯で大きく 3つ存在しています。

特定のバージョンの squid が必要な場合はソースコードからビルドします。
設定 directives のドキュメントは Squid configuration directives を参照します。バージョンによって設定方法が異なります。

SSL bumping における、接続先サーバのドメインが利用する証明書に相当する、偽の証明書は、後述の認証局秘密鍵を用いて動的に生成されます

Squid 3.5 の設定例

認証局秘密鍵、自分の秘密鍵で署名した認証局証明書

openssl コマンドで秘密鍵を発行します。

openssl genrsa -out my-private-key.pem 2048

CSR を自分の秘密鍵で署名します。

openssl req -sha256 -new -key my-private-key.pem -out csr.pem
openssl x509 -sha256 -req -days 36500 -in csr.pem -signkey my-private-key.pem -out my-certificate.crt

squid の仕様に従い、秘密鍵と証明書を一つのファイルにまとめます。

cat my-private-key.pem my-certificate.crt > squidCA.pem

それぞれのコマンドの意味については、こちらのページも参照します。

SSL Bump の有効化

squid.conf

http_port 3128 ssl-bump generate-host-certificates=on dynamic_cert_mem_cache_size=4MB cert=/etc/squid/squidCA.pem

SSL DB の初期化

systemctl restart squid
systemctl status squid

を実行した後に以下のファイルのログを確認します。

/var/log/squid/cache.log

初回 SSL Bump 利用時は SSL DB が初期化されていない旨のエラーが確認できます。以下のコマンドで初期化します。

/usr/lib64/squid/ssl_crtd -c -s /var/lib/ssl_db
chown -R squid:squid /var/lib/ssl_db

参考:

[root@ip-172-31-13-150 squid]# rpm -qa | grep squid
squid-3.5.20-17.amzn2.6.1.x86_64

[root@ip-172-31-13-150 squid]# rpm -ql squid-3.5.20-17.amzn2.6.1.x86_64 | grep crtd
/usr/lib64/squid/ssl_crtd

SSL Bump の設定

acl wssConnection ssl::server_name .tunnel.cloudproxy.app
acl step1 at_step SslBump1
acl step2 at_step SslBump2
acl step3 at_step SslBump3

ssl_bump splice wssConnection
ssl_bump peek step1 all
ssl_bump stare step2 all
ssl_bump bump step3 all

Squid 3.3-3.4 の場合

以下のような記法になります。

acl broken_sites dstdomain .tunnel.cloudproxy.app
ssl_bump none broken_sites
ssl_bump server-first all

参考資料

ルート CA 証明書のインストール

Windows を対象とする場合は、DER 形式に変換します。

openssl x509 -in my-certificate.crt -outform DER -out squid.der

Windows の場合は Internet Properties の Content を開いて Certificates をクリックします。

Uploaded Image

Import からルート証明書をインポートします。

Uploaded Image

動作検証 SSH from browser

確かに squid が発行した偽の証明書が使われていることが分かります。

Uploaded Image

tunnel.cloudproxy.app は squid の splice 対象となっており、squid が SSL 終端になっていないことが分かります。

Uploaded Image

補足: ブラウザの SSL 証明書キャッシュをクリアしたい場合は「Clear SSL state」をクリックします。

Uploaded Image

SSH from browser が動作します。

Uploaded Image

tunnel.cloudproxy.app を SSL 終端とすると、WebSocket 通信が失敗するため、以下のエラーとなります。

Uploaded Image

動作検証 gcloud コマンド IAP tunnel

Cloud Shell ではなくローカル PC にインストールした gcloud で IAP tunnel を作成できるか検証します。

補足: Cloud Shell で接続される端末は、インターネット上の端末であり、ローカル PC が参照するプロキシを通らないため検証になりません。

gcloud compute ssh instance-2 --project myproject-20210411 --zone asia-northeast1-b --tunnel-through-iap --log-http

--tunnel-through-iap は IAP tunnel による接続を強制するためのオプションです。--log-http は検証時のデバッグ用途です。

Windows の場合はシステムの証明書設定を参照せず、gcloud と同封された python の証明書設定を参照します。そのため、Squid のルート証明書を信頼できておらず、通信がタイムアウトすることが確認できます。

これを回避する簡単な方法は、以下のオプションを指定することです。証明書をすべて信頼するようになります。curl の -k と同じ働きです。

gcloud config set auth/disable_ssl_validation True

あるいは、以下のオプションで gcloud が信頼するルート証明書を指定することもできます。CER や DER ではなく PEM ファイルです。

gcloud config set core/custom_ca_certs_file C:\Users\Administrator\Downloads\roots.pem

注意: 信頼するルート証明書が追加されるのではなく、上書きされます。そのため、まずは roots.pem を python のフォルダからコピーしてきて、squidCA.pem の内容を追記します。

Uploaded Image

IAP tunnel の作成に成功すると、以下のようなウィンドウが起動します。

Uploaded Image

関連ページ