VPC環境へCloudNATを設定しよう

# VPC環境へCloudNATを設定しよう
GoogleCoudのVPC構築後、Google Compute Engine (以下GCE)からインターネットアクセスをしたい方へCloudNATの設定を紹介します。
GCEからインターネットにあるサーバとのデータやり取りがある場合でもグローバルIPを割り当てをするとFirewallやグローバルIP・インスタンスの管理が大変です。その為、GCEへ直接グローバルIPを割り当てるというのは、セキュリティの観点からあまり実施したくないと思います。
そこで、今回はVPC内にCloudNATを設定し、CloudNAT経由でVPCからインターネットへ通信する方法を紹介します。

## この記事の対象者

- VPCを構築し、外部からの通信は極力できない設計にしGCEからインターネットへ通信をしたい方
    - GCEに直接外部IPを付与したくない方
    - GCEからインターネットサイトへ通信したい方
    - LinuxOSのアップデート(apt-getなど)をしたい方
    
## CloudNATとは
CloudNAT（ネットワーク アドレス変換）を使用すると、外部IPアドレスを持たない特定のリソースからインターネットへの送信接続が可能になります。
例えば、家庭のインターネットルータの様にインターネットへは接続できるが、LANの中には通信できない様なネットワークを作ることができます。

## 特徴
Cloud NATにより、ネクストホップがデフォルトのインターネット ゲートウェイであるVPCの静的ルートに送信NATが実装されます。
Cloud NATは、インターネットからの受信接続は許可されていません。送信パケットへの応答として受信するパケットに対してのみ許可されており、一般的な自宅のルータのNATと同じ仕組みで通信が可能です。

**利用するメリット：**

- セキュリティ
    - 個々のCompute Engineに外部IPを割り振る必要がなく、下り（外向き）ファイアウォールルールに従い、インターネットへアクセスが可能です。
    また、インターネットから内部への接続は送信元への戻りの通信のみ許可されます。

- 高可用性
    - CloudNATは、分散マネージドサービスになっています。指定した構成のCloudNATを提供してくれます。利用するのに複雑な冗長化設計は不要です。

- スケーラビリティ
    - CloudNATは、NAT IPアドレスの数を自動的にスケーリングすることも可能です。

- パフォーマンス
    - Cloud NATは、GoogleのAndromedaソフトウェア定義ネットワーキングによって実装されています。その為、Compute Engineの様に種類によって帯域が縮小されません。
    
    :::note info
    CloudNATルールを活用すると、パフォーマンス状況を見てIP毎に利用するCloudNATを振り分けるなどをする事も可能です。
    https://cloud.google.com/nat/docs/using-nat-rules


## 利用環境
- GCEが1台以上ある、単一リージョンのVPC環境
 
## CloudNATを設定してみよう
設定方法を記載
[Cloud NAT NAT ルールの使用](https://codelabs.developers.google.com/codelabs/cloudnet-natrules#0)

次のようなCloudNAT構成を作成します。

![0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/f8858674-6d60-3f77-f232-126665b63a91.png)


### 1.　NAT用の外部IPアドレス予約
gcloudコマンドを使い、[nat-address]名で予約します。
    
    
    gcloud compute addresses  create nat-address --region us-central1
   

### 2.予約した外部IPの確認
予約した名前と外部IPアドレスを確認します。

    gcloud compute addresses list

![15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/dc895316-97af-1ae0-9fee-ee3f00f67be9.png)

上記の例では、NAMEが「nat-address」、予約アドレスが「34.133.128.221」になっています。

次から、VPC、サブネット、テスト用のインスタンスを作成します。
すでに環境がある場合は、項番6へ進んでください。
なお、それぞれのコマンドの変数は自分の環境設定へ変更し実行してください。


### ３.VPCの作成。
「consumer-vpc」という名前でVPCを作成します。

    gcloud compute networks create consumer-vpc --subnet-mode custom

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/3f5c4030-0e4c-76e5-4bce-1290f3efabd7.png)


### ４.サブネットの作成
サブネットを「consumer-vpc」上に「consumer-subnet」という名前で、「us-central1」リージョンに作成します。また、サブネットのアドレス範囲は、10.0.0.0/24で作成します。

    gcloud compute networks subnets create consumer-subnet \
    --network consumer-vpc --range 10.0.0.0/24 --region us-central1


![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/a7534ea9-e951-f170-ebf9-8a62b712adc9.png)


### ５.テスト用インスタンスの作成
「nat-test-instance」名でゾーン「us-central1-1」へ新規にインスタンスを作成します。

    gcloud compute instances create nat-test-instance --zone=us-central1-a \
    --machine-type=e2-medium --network-interface=subnet=consumer-subnet,no-address

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/220fcf61-107d-bbbf-ca46-e1ac57489f05.png)


subnet=consumer-subnetを設定し、no-addressオプションをつけることで、外部IPアドレスを付与しないようにします。

gcloud 詳細なコマンドオプションは、[こちらのドキュメント](https://cloud.google.com/sdk/gcloud/reference/compute/instances/create
)を参照にしてください。

### 6.Firewallルールの作成
CloudIAP経由でSSH接続できる用にFirewall ルールを作成する。
VPCファイアウォール ルールを作成して、IAP範囲アドレスがポート22でnat-test-instanceへ接続できるようにします。
今回のFirewallルールでは、送信元がIAPのIPレンジから「consumer-vpc」VPC内のネットワークに対し、SSHをすべて許可する設定をしています。


    gcloud compute firewall-rules create consumer-allow-iap \
    --network consumer-vpc --allow tcp:22 \
    --source-ranges 35.235.240.0/20

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/362e5181-146b-ecfd-a3f0-e2b99ff01674.png)


### ７.インスタンスからインターネットへの接続テスト
環境が整った為、現時点での通信確認を実施します。
GCEに外部IPが割り当たっておらず、NAT設定未設定の場合はインターネットへ通信ができない事を確認します。

#### a、作成した「nat-test-instance」へssh接続をします


    gcloud compute ssh nat-test-instance --zone=us-central1-a

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/1f86b680-0422-f8c4-ac7d-e0a08aa44515.png)


#### b.sshで接続できましたらインスタンスから、ping疎通確認と外部へHTTP通信ができるか確認します
    ping google.com
    curl http://ifconfig.co

どちらのコマンドも正常に通信できない為、５秒程で「CTL」＋「C」でコマンドを中止してください。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/128b71b0-8001-2bb7-033a-1e79bd42bde0.png)

    
### ８.Cloud Routerの作成
CloudNATを作成する前に、Cloud Routerインスタンスを[consumer-cr]という名前で作成します。 

    gcloud compute routers create consumer-cr \
    --region=us-central1 --network=consumer-vpc 

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/e27534d3-370a-87cf-98c7-78647d8ba71c.png)


### ９.CloudNATの作成
CloudNATを作成します。


    gcloud compute routers nats create consumer-nat-gw \
    --router=consumer-cr \
    --router-region=us-central1 \
    --nat-all-subnet-ip-ranges \
    --nat-external-ip-pool=nat-address-1


![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/ff8d340c-85df-c2fd-e3f4-8cf95be79334.png)


--auto-allocate-nat-external-ips    すべてのIPアドレスを対象
--nat-all-subnet-ip-ranges          リージョン内のすべてのサブネットを対象

### １０.インスタンスからインターネットへの接続テスト(CloudNAT設定後)

#### a、作成した「nat-test-instance」へssh接続をします

```
gcloud compute ssh nat-test-instance --zone=us-central1-a
```
![](./images/9.png)    
![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/6b3a90e5-2fbe-ce6b-ef6b-00dee6c4f913.png)


#### b.sshで接続できましたらインスタンスから、ping疎通確認と外部へHTTP通信ができるかを確認します
```
ping google.com
curl http://ifconfig.co
```
![](./images/14.png)
![14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2773468/96437244-8704-9aa0-167b-a2da4b4749dc.png)


CloudNAT設定後は、正常に外部のNWへ接続できるようになります。

http://ifconfig.co
へ接続すると、CloudNATへ割り当てた外部IPアドレス「34.133.128.221」が表示されている事がわかると思います。


## 最後に
VPCからCloudNATを利用しインターネットへ接続する方法を紹介しました。
CloudNATは起動しておくと利用料金がかかる為、利用の際は利用金額も算出してクラウド予算の中に含めておく事を推奨します。

実際にCloudNATやVPC構築する場合は、自社のセキュリティ・ネットワーク担当者へ相談し自社のポリシーに則った形で活用する事が重要となります。

企業システムで利用するクラウド環境の場合は、Interconnectを経由し自社データセンター経由で通信させるなどセキュリティとネットワーク経路設計が重要になってきます。1つの解決方法として、CloudNAT NATルールなどを活用し、限定したCompute EnginのみをNAT対象にする事も可能です。
興味がありましたら、おまけで紹介しているラボを実施し、活用の可否を検討いただきたいと思います。

## おまけ

### 1.CloudNATのNATルールを試したい場合
次のGoogleが用意しているラボを参考にしてみてください。

[Cloud NAT NAT ルールの使用](https://codelabs.developers.google.com/codelabs/cloudnet-natrules)

### 2.CloudNAT環境のWindows利用時の注意点
CloudNATを利用している場合、kmsの有効化と更新セキュリティーアップデートにて、うまく動作しない場合があるそうです。次のドキュメントを参考にネットワーク経路の見直しをしてください。

[Windows Server VM の作成と管理  |  Compute Engine ドキュメント  |  Google Cloud](https://cloud.google.com/compute/docs/instances/windows/creating-managing-windows-instances?hl=ja#routing_requirements)