内容
組織ポリシーにより、PublicIPの付与を禁止したプロジェクトがある。
ホストプロジェクトからサービスプロジェクトへ共有VPCをアタッチし、ホストプロジェクトのCloud NAT経由でインターネットへのアクセスを実施する。
最後に、ホストプロジェクトのFirewallによってサービスプロジェクトのインスタンスが正しく制御できることを確認
構成図
ホストプロジェクト:shared host PJ
-> External IPの利用可能
サービスプロジェクト1:Service PJ1
サービスプロジェクト2:Service PJ2
-> 組織ポリシーにてサービスプロジェクトではExternal IPの利用を禁止
共有VPCサブネット:internet-access 172.16.0.0/12
Cloud NATをinternet-accessのサブネットに接続
組織階層
組織名:xcloudyx.net
組織ポリシー:パブリックIPの利用を禁止している
組織から配下のフォルダおよびプロジェクトにポリシーを継承している
Adminフォルダに関しては管理者用として利用しており、パブリックIPの利用を許可している
共有VPC作成に伴う権限の付与
必要な権限は以下の通り
参考ページ:共有 VPC 管理者の指名
[プロジェクトレベル]
compute.projects.get -> Compute 閲覧者
resourcemanager.projects.getIamPolicy -> Project IAM 管理者
[組織レベル]
compute.organizations.enableXpnHost -> Compute Shared VPC 管理者
参考ページ:Compute Shared VPC Admin role
Compute Shared VPC Adminの権限を付与するには、組織もしくはフォルダを選択して実施する
ホストプロジェクトの作成
共有VPCのホストプロジェクト名を入力、組織および場所を選択し、作成を選択
共有VPCの設定時に必要となるため、ComputeEngineAPIを有効化しておく
サービスプロジェクトの作成
サービスプロジェクト名を入力、組織および場所を選択し、作成を選択
共有VPCの設定時に必要となるため、ComputeEngineAPIを有効化しておく
ホストプロジェクトにサービスプロジェクトに共有するVPCを作成
ホストプロジェクトを選択 -> VPCネットワーク -> VPCネットワーク -> VPCネットワークを作成を選択
名前を入力し、サブネット作成モードカスタムにチェックを入れる
サブネットの名前、リージョンおよびサブネットのアドレスレンジを入力し、完了を選択
ここまでで、共有VPCの作成準備は完了
共有VPCの作成
ComputeEngineのAPIを有効化しておかないとエラーとなる
また、権限も足りている必要がある -> 権限の付与参照
サービスプロジェクトへ共有したいサブネットを選択し、続行をクリック
今回は、us-centra1のサブネット:172.16.0.0/12を共有する
追加したいサービスプロジェクトもComputeEngineAPIを有効化しておかないとエラーとなる
ホストプロジェクト側
サービスプロジェクト側
インターネットアクセス用ComputeEngineインスタンスの作成
Shared VPCで払い出された172.16.0.0/12のサブネットにインスタンスを作成する
Service PJ -> ComputeEngine -> VMインスタンス -> インスタンスを作成を選択
ホストプロジェクトから共有されたサブネットがあるリージョンを選択する
今回はus-central1
下にスクロールし、詳細オプション -> ネットワーキングから
共有ネットワークを選択し、ホストプロジェクトから共有されたサブネットを選択する
また、外部IPはなしとし、完了を選択
今回は組織ポリシーで外部IPの付与を許可していない
インターネットにアクセスできないことを確認
作成したComputeEngineインスタンスは外部IPをもっていないため、現状はインターネットにアクセスできない
digコマンドでwww.google.co.jpのIPアドレスを確認
manabu_admin@instance-10:~$ dig www.google.co.jp
; <<>> DiG 9.16.44-Debian <<>> www.google.co.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 6612
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.google.co.jp. IN A
;; ANSWER SECTION:
www.google.co.jp. 300 IN A 142.250.1.94
;; Query time: 15 msec
;; SERVER: 169.254.169.254#53(169.254.169.254)
;; WHEN: Wed Nov 29 02:31:06 UTC 2023
;; MSG SIZE rcvd: 61
curlコマンドでアクセスを実行するが、応答なしとなる。
manabu_admin@instance-10:~$ curl 142.250.1.94
curl: (28) Failed to connect to 142.250.1.94 port 80: Connection timed out
digコマンドはデフォルトだとインストールされていないため、別途導入が必要
manabu_admin@instance-10:~$ sudo apt-cache search dig
manabu_admin@instance-10:~$ sudo apt-get install -y dnsutils
ホストにてサービスPJ向けのCloudNATを作成
ホストプロジェクトにてCloudNATを作成し、サービスプロジェクト側で作成した
ComputeEngineからインターネットへのアクセスができるようにする
ゲートウェイの名称:Cloud NATインスタンスの名前
NATタイプ:公開(インターネットにアクセスするため、Cloud NATにパブリックIPが必要)
Cloud Routerの選択:NATを利用する際にCloud Routerが必要となるため作成する
パブリックIPアドレスにアクセスするサブネットのIP範囲を、Cloud NATにマッピングする
カスタムを選択
Cloud NAT経由でインターネットにアクセスさせたいサブネットを選ぶ
サブネット名「internet-access」を選択
Cloud NATのIPに指定がなければ、自動のにする。
下記の内容を確認しサービスティアを選択
ネットワークサービスティア プレミアム:トラフィックは Google の高品質グローバル バックボーンを通り、ユーザーに最も近い Google エッジ ピアリング ポイントから出ていきます。
ネットワークサービスティア スタンダード:トラフィックは送信先または送信元のクラウド リージョンに最も近いピアリング ポイントから Google ネットワークに出入りします。
最後に、作成を選択
これで、パブリックIPを持たないインスタンスからインターネットへの通信が必要な場合、
Cloud NATを経由することで、実現が可能となる。
サービスプロジェクトからのインターネットアクセス
digコマンドでwww.google.co.jpのIPアドレスを確認
kyndryl_owner@instance-10:~$ dig www.google.co.jp
; <<>> DiG 9.16.44-Debian <<>> www.google.co.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 65181
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.google.co.jp. IN A
;; ANSWER SECTION:
www.google.co.jp. 300 IN A 173.194.193.94
;; Query time: 4 msec
;; SERVER: 169.254.169.254#53(169.254.169.254)
;; WHEN: Wed Nov 29 04:54:08 UTC 2023
;; MSG SIZE rcvd: 61
curlコマンドでアクセスを実行し応答を確認した
kyndryl_owner@instance-10:~$ curl 173.194.193.94
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
Firewallの動作確認
ホストプロジェクト側のファイアウォールルールを変更することで、トラフィックの制御ができることを確認する
具体的には、サービスプロジェクトのComputeEngineからHTTPトラフィックがCloud NAT経由に通信できないこと
Firewallの変更
共有VPCに設定されている、現状のFirewallルールを確認する
デフォルトでは、下り(google cloudからインターネット向け通信)は全て許可となっている
従って、下りに対してTCP80を拒否するルールを作成する
これにより、curlコマンドでアクセスできないことを確認する
ファイアウォールルールを作成を選択
名前:ポリシー名を入力
ネットワーク:共有VPC名を選択
トラフィックの方向:Google Cloudからインターネット向けのため、下りを選択
一致した時のアクション:拒否とする
送信先IPv4範囲:インターネット向けを全て拒否するため、0.0.0.0/0とする
指定したプロトコルとポート:TCP80を拒否するため、TCPにチェックをいれ、ポートに80を入力
最後に。作成を選択
動作確認
サービスプロジェクトのComputeEngineからHTTPアクセスをためしてみる
「www.kyndryl.com」に対して、HTTP80の通信を実施すると、タイムアウトする
kyndryl_owner@instance-1:~$ curl --max-time 5 http://www.kyndryl.com
curl: (28) Failed to connect to www.kyndryl.com port 80: Connection timed out
拒否していないHTTPS443通信の場合、正常に応答が返ってくることからFirewallが正しく動作している
kyndryl_owner@instance-1:~$ curl --max-time 5 https://www.kyndryl.com
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="https://www.kyndryl.com/us/en">here</a>.</p>
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v84a3a4012de94ce1a686ba8c167c359c1696973893317" integrity="sha512-euoFGowhlaLqXsPWQ48qSkBSCFs3DPRyiwVu3FjR96cMPx+Fr+gpWRhIafcHwqwCqWS42RZhIudOvEI+Ckf6MA==" data-cf-beacon='{"rayId":"82d9ae0fabb622ca","b":1,"version":"2023.10.0","token":"82de1bcba60e4fe390aecc52326b7583"}' crossorigin="anonymous"></script>
</body></html>