パブリッククラウドでVM(でもContainerでも何でもいいが)を作成する際,セキュリティ上の理由からパブリックIPアドレスを削除したい場合がある.攻撃面を減らしたり,アクセス制御を一元化したい等である.しかし,何も準備せずに単にパブリックIPアドレスの削除だけを行うと,以下のような不都合が起きる.
- 外部ネットワークからインバウンド通信ができなくなる → SSH接続できない
- 外部ネットワークへのアウトバウンド通信ができなくなる →
apt installやgit cloneなどのコマンドが使えない
かといって自前でクラウドネットワーク内にプロキシサーバを立てて云々というのも面倒である.これらは以下の設定により解決するのが標準的である.
- IAPを立てて,アクセス制御をした上で,IAP経由でSSH接続(tunneling)する
- Cloud NATを設定し,NATによるプライベートIPアドレス→パブリックIPアドレスの変換を噛ませて,アウトバウンド通信する
ここではGoogle Cloud Platformにて上記の設定を行う方法をまとめておく.大部分の手順をWeb Console上で実行する.コマンドライン上で全て済ませたいなら gcloud で同等の操作を行えばよい.
IAPの設定
IAP (Identity-Aware Proxy)はIAM (Identity & Access Management)と連動するプロキシである.IAPを立てることにより,クラウドリソースへのアクセスは必ずIAPを介し,IAMによる認証を受けることになる.本稿の目的にとって重要なのは,IAP tunnelingによりクラウドネットワークの内部IPアドレスに到達できるので,外部IPアドレスを持たないVMにもSSH接続が可能になる点である.
さらに,後述のCloud firewallにてIAP経由のインバウンド通信(Source IP範囲 35.235.240.0/20 )のみ許可すれば,設定ミスでパブリックIPアドレスを露出させてしまったとしても,IAP経由でないインバウンド通信を拒否できるため安全である.クラウドネットワーク内からの攻撃のリスクを減らす効果もある.
IAPは Security (or IAM & Admin) > Identity-Aware Proxy より設定を確認できる.VPC networkやCloud NATと違って,「IAPを作成」するのではなく,IAPで保護したいプロジェクト・サービス毎にIAPの有効化」を行う.詳細は他項目の執筆で力尽きたのでEnable IAP for Compute Engineを参照.
Cloud NATの設定
本項では以下の設定方法を述べる.恐るべきことに,Cloud Network関係のサービスであるにもかかわらず,各々のコンソールがバラバラのカテゴリに分散配置されている.
- VPC network
- Cloud Router (VPC/Region-associated)
- Cloud NAT (Cloud Router-associated)
VPC network
VPC (Virtual Private Cloud) networkはごく大雑把にいえばクラウド上に構築される仮想的なイントラネット(プライベートネットワーク)である.
GCPではProjectを作成するとデフォルトVPCネットワークも自動的に作成される.個人的に使う分にはこれでも十分といえば十分ではあるが,デフォルトVPCネットワークにプリセットされるfirewall rulesはかなりガバガバである.よりセキュアなクラウドネットワークを構築したいのであれば,デフォルトVPCネットワークを削除したうえで,新規にVPCネットワークを作成することを推奨する.
VPCネットワークは VPC Network > VPC networks > Create VPC network より作成できる.
ここで "Configure network profile" チェックボックスを有効にすると,Zone及びNetwork profileが指定可能できるが,必須ではない.
続いてサブネット作成やfirewale rulesの初期設定を行う.ただし,VPCネットワーク作成画面では後述のfirewall policyが利用できないため,firewallの詳細な設定は後回しにする.
DNS Armorというセキュリティサービス(執筆時点ではプレビュー段階)の設定等もここで併せて実行できる.
Cloud Router
Cloud RouterはVPCネットワーク内の動的ルーティング用の論理ルータである.後述のCloud NATはCloud Routerに紐付けて設定するものである.そのためCloud Routerを作成する必要がある.
Cloud Routerは Network Connectivity > Cloud Router > Create router より作成できる.
- Associated with: VPC network
- Description: 任意
- Network: 関連付けるVPCネットワークを選択
- Region: 関連付けるRegionを選択
- Other settings: 適当に設定
Cloud NAT
NAT (Network Address Translation)は或るネットワーク内のIPアドレスを別のネットワーク内のIPアドレスに変換する機能である.狭義にはプライベートネットワーク内のプライベートIPアドレスをパブリックIPアドレスに変換する機能(Public NAT)を指す.Cloud NATはクラウドネットワーク(VPCネットワーク)におけるNATサービスである.これによりクラウドネットワーク内のパブリックIPアドレスを持たないリソースであってもアウトバウンド通信が可能となる.
Cloud NATは Network Services > Cloud NAT > Create Cloud NAT gataway より設定できる.
- NAT type: Public
- Select Cloud Router: 関連付けたいVPCネットワーク/Region/Cloud Routerを選択
Cloud NATがアドレス変換の対象とするプライベートIPアドレスをサブネット単位で指定するものである.
- Source IP version: アドレス変換の対象となるVPCネットワーク内リソースがどのIP versionを使っているかを指定する(IPv4, IPv6, or both)
- IPv4/6 subnet ranges: デフォルトでは全てのCompute Engine VM instances (primary range)とK8s Engine container pods (secondary range)を対象とするが,primary rangeに絞ったりカスタムサブネットを指定することも可能である
- Cloud NAT IP addresses: Automatic
- Other settings: 適当に設定(ポートアロケーションやタイムアウト時間など色々設定できるがデフォルトでも構わない)
Firewallの設定
Firewallの設定は Network Security > Firewall policies にて行う.
Firewall rulesの作成にはVPC firewall rulesを用いる方法とNetwork firewall policiesを用いる方法とがある.
VPC firewall rulesは文字通りVPCネットワークに関連付けられるfirewall rulesである.Firewall rulesを個別に作成し,優先度を付けてフラットに並べるというものである.前述のVPC network作成時にプリセットされていたfirewall rulesがそれである.
一方,Network firewall policiesは,複数のfirewall rulesをまとめたルールセット(ポリシー)であり,指定したVPCネットワーク/Regionに対して一括適用できる.Network firewall policyは単にポリシー単位で管理できて楽というだけでなく,VPC firewall rulesには存在しない追加機能を備えている.
VPC firewall policiesではCloud Next Generation Firewall (NGFW) ruleと呼ばれるルールが利用できる.これはSecure tagという特殊なタグ(及び値)を条件として適用されるルールである.例えば「ポート22へのSSH接続許可」・「アウトバウンド通信許可」などに相当するsecure tagを作成した上で,これらのsecure tagを条件とするCloud NGFW ruleを作成しておけば,各VMインスタンスに当該secure tagを付与するだけでSSH接続・アウトバウンド通信を許可できる.
さらに,maliciousな外部IPアドレスとの間のインバウンド/アウトバウンド通信の禁止,TOR出口ノードからのインバウンド通信の禁止,といった便利なfirewall rulesがプリセットされている.これらはVPC firewall rulesには用意されていない.(これらのfirewall rulesを削除することもできるが推奨しない.)
小規模ネットワークであればVPC firewall rulesでも十分ではあるが,Network firewall policiesの方が機能性・管理性ともに優れる.小規模構成ならVPC firewall rulesの方が楽というわけでもない.とくにこだわりがないならNetwork firewall policiesの利用を推奨する.
ここでは概ね以下のような挙動をするfirewall policyの作成手順を述べる:
Secure tagの作成
Secure tagの作成・編集・削除は IAM & Admin > Tags で行う.TagはCreate tag keyにてtag keyとtag value(s)を設定することで作成できる.なお,tagの有無のみが重要であって,tag valueに役割がとくにないのであれば,tag valueとしては適当なダミー値(たとえば "value" のようなもの)のみ設定しておけばよい.
上記作成画面にてFor use with Cloud NGFWチェックボックスを有効にすると,Project及びNetwork(VPC)の設定項目が追加で現れる.これにより当該ネットワーク内のcompute resourceにのみ付与可能なtagが作成される.これがSecure tagである.
前述の目的で使うなら
- key:
allow-ssh-22, values: {value} ─ TCP:22へのインバウンド通信許可設定 - key:
allow-egress, values: {value} ─ アウトバウンド通信許可設定
のようなsecure tagを作成すればよい.
なお,secure tagの作成・編集・削除,resourceへのsecure tagの付与・編集・削除は,それぞれ当該Project内にて十分な権限を持つユーザにのみ可能である.Project内の誰でもsecurity設定に関わるsecure tagを弄り回すことができたら台無しである.複数ユーザからなるProjectではsecure tag周りの適切な権限管理が必要である.当然firewall周りの権限管理も同様.
Network firewall policyの作成
Network Security > Firewall policies > Create firewall policy より作成する.
- Policy name / Description: 適当に設定
- Policy type: VPC policy
- Deployment scope: 全てのリージョンで共通のポリシーを使うなら "Global" を,特定のリージョンにのみ適用したいなら "Regional" を選択してからRegionを指定
"Continue" を押すとFirewall rulesの設定画面に移行する.デフォルトでは次のようなrulesがプリセットされている.Firewall rulesは優先度の数値が小さい方から順に評価される.
次のようなfirewall rulesを追加することで,冒頭で述べたfirewall policyが完成する.
| Priority | Direction of traffic | Action on match | Target | Source filters | Protocols and ports |
|---|---|---|---|---|---|
| 500 | Ingress | Allow | Secure tag (allow-ssh-22) |
IPv4 35.235.240.0/20
|
TCP:22 |
| 2000 | Egress | Allow | Secure tag (allow-egress) |
IPv4 0.0.0.0/0
|
All |
| 2001 | Egress | Allow | Secure tag (allow-egress) |
IPv6 ::/0
|
All |
- compute resource (destination)に
allow-ssh-22が付与されており,sourceがIAP経由で,ポート22番へのTCP通信ならば許可 - compute resource (source)に
allow-egressが付与されているなら,全てのIPv4アドレスへのegressを許可 - compute resource (source)に
allow-egressが付与されているなら,全てのIPv6アドレスへのegressを許可
(2)と(3)のルールは単独では危険だが,これらのruleが評価されるのは上位のruleで拒否(Deny)されていない場合に限ることに注意.プリセットpolicyの優先度1004においてmalicious IPへのegressが弾かれる.
VPC firewall rulesの削除
VPCネットワークを作成する際,VPC firewall rulesも自動で作成されるが,Network firewall policyを使用する場合は不要である.これらは当該VPCに対して正しいfirewall policyを作成してから削除する.
VM instanceの設定
外部IPアドレスの削除
Webコンソールにて,外部IPアドレスを持たないVM instanceを新規作成する場合,VM instance作成画面の Networking タブにおいて,全てのnetwork interface(トグルになっており展開すると詳細設定が表示される)に対して External IPv4/6 address プルダウンメニューから None を選択する.
作成済みのVM instanceから外部IPアドレスを削除する場合も同様に,VM instance編集画面の Networking セクションにて各network interfaceに対して同様の設定をする.
当たり前だがnetwork interface自体を削除してしまうと一切の通信が不能となる.
Secure tagの付与
さきほど作成したsecure tagを対象VM instanceに付与することで,アウトバウンド通信及びIAP tunnelingによるSSH接続を許可できる.TagとLabelは別物なので注意.
VM新規作成時は Advanced タブの Manage tags and labels トグルからsecure tagの設定が可能である.(前述とsecure tag nameが異なっているがよしなに読み替えること.)
作成済みVMのsecure tagを編集する場合は Details の Tags から実行する.
VS Code SSH設定
VS Codeベースの開発環境(CursorやVoid Editorなど)からRemote SSH拡張機能でVMにアクセスする際の .ssh/config の設定方法を述べる.通常のVMなら
Host VM_NAME
HostName VM_PUBLIC_IP_ADDR
Port PORT_NUMBER
User USERNAME
IdentityFile SSH_PRIV_KEY_PATH
とやればいいが,IAP経由でアクセスするには次のようにする.
Host VM_NAME
HostName TRUE_VM_INSTANCE_NAME
Port PORT_NUMBER
User USERNAME
IdentityFile AUTH_PRIV_KEY_PATH
IdentitiesOnly yes
IdentityAgent none
ProxyCommand gcloud compute start-iap-tunnel %h %p --zone=ZONE --project=PROJECT --listen-on-stdin
-
Host— 自由に決めてよい -
Port— 基本的には22 -
User— 当該VMのゲストOSのユーザ名 -
IdentityFile— Projectに登録された認証用公開鍵と対応する秘密鍵のパス.gcloud経由で初回SSH接続時にgoogle_compute_engineという名前の認証用鍵ペアが自動生成・登録される.自前で鍵ペアを生成してProjectに登録することもできる.Projectに登録済みの鍵はgcloud compute ssh USERNAME@TRUE_VM_INSTANCE_NAME \ --project=PROJECT \ --zone=ZONE \ --tunnel-through-iapで確認できる.この出力結果をコピーし,必要な修正を施した一時ファイルを作成した後,gcloud compute project-info describe --format="value(commonInstanceMetadata[items][ssh-keys])"で編集を反映させる.gcloud compute project-info add-metadata --metadata-from-file=ssh-keys=KEY_FILE -
ProxyCommand— SSH接続の際に当該コマンドを経由する.ここではgcloudのIAP tunnelingを行っている.-
ZONE— Zone (e.g.us-central1-a) -
PROJECT— Project ID
-
なお,Windowsにおいて上記設定ファイルを使うと,"Proxy Command" を実行時に gcloud の名前解決に失敗することがある.これは以下のように gcloud の絶対パスを指定すれば解決する.
# gcloudをユーザ単位でインストールした場合
"C:\Users\username\AppData\Local\Google\Cloud SDK\google-cloud-sdk\bin\gcloud.cmd" compute start-iap-tunnel %h %p ...
# gcloudをシステム全体にインストールした場合
"C:\Program Files (x86)\Google\Cloud SDK\google-cloud-sdk\bin\gcloud.cmd" compute start-iap-tunnel %h %p ...
参考リンク
- Google Cloud SDK Reference https://docs.cloud.google.com/sdk/gcloud/reference
- Virtual Private Cloud (VPC) overview https://docs.cloud.google.com/vpc/docs/overview
- Cloud Router overview https://docs.cloud.google.com/network-connectivity/docs/router/concepts/overview
- Cloud NAT overview https://docs.cloud.google.com/nat/docs/overview
- DNS Armor https://docs.cloud.google.com/dns/docs/threat-detection
- Identity-Aware Proxy overview https://docs.cloud.google.com/iap/docs/concepts-overview
- Enable IAP for Compute Engine https://docs.cloud.google.com/iap/docs/enabling-compute-howto
- Secure tags for firewalls https://docs.cloud.google.com/firewall/docs/tags-firewalls-overview
- Initializing the gcloud CLI https://docs.cloud.google.com/sdk/docs/initializing
- Add SSH keys to VMs https://docs.cloud.google.com/compute/docs/connect/add-ssh-keys











