AWSとGCP間をVPN接続してみた

# はじめに
AWSとGCP間をシームレスに接続する必要が出てきたので、VPNセッションを冗長化する方法で実装しました。

この投稿内容は、テスト環境上に実装＆動作検証した際の備忘録となります。

# VPN要件

- ２つのVPN接続を用意して冗長性を確保する。
- クラウド間は[**BGP**(**B**order **G**ateway **P**rotocol)](https://ja.wikipedia.org/wiki/Border_Gateway_Protocol)を用いてルーティング情報を交換する。（ダイナミックルーティング）
- 両クラウド基盤は、**東京リージョン**間を接続する。（距離遅延を最小に抑える為）

# 実装後のネットワーク構成イメージ
VPN周りの構成を検討するにあたり、公式ドキュメントにある『[**冗長 Cloud VPN トンネル**](https://cloud.google.com/router/docs/concepts/overview?authuser=19&hl=ja#redundant_cloud_vpn_tunnels)』を参考にした。

また本投稿ではテスト環境下で検証した為、IPアドレス等の情報をマスクせずに記載する。
（現在は全てのテスト環境を削除した為、アドレス等は存在していません。）

![Topology.png](https://qiita-image-store.s3.amazonaws.com/0/94476/87d2c381-8868-8b0a-eace-d20460dedf41.png)


# VPN接続手順

## (GCP) 外部IPアドレスの予約
`VPN Gateway #1`、`#2` に割り当てる外部IPアドレスを２つ予約する。

`VPCネットワーク`＞`外部 IP アドレス`を開き、`静的アドレスを予約`をクリック

任意の`名前`を入力、`リージョン`に`asia-northeast1`を選択して`予約`をクリック 
![gcp_vpn_01.png](https://qiita-image-store.s3.amazonaws.com/0/94476/afdbdb00-6274-9e91-bacd-32852d2b8316.png)


以上の操作を２回繰り返し、外部IPアドレスを２個予約する
![gcp_vpn_02.png](https://qiita-image-store.s3.amazonaws.com/0/94476/6a99f062-1dc6-8148-6fa9-d49f52353072.png)


## (AWS) VPN接続の作成
`VPC`＞`VPN接続`を開き、`VPNの作成`をクリック

各項目に必要な情報を入力して１つ目のVPN接続を作成
![aws_vpn_01.png](https://qiita-image-store.s3.amazonaws.com/0/94476/b74c83b2-7739-31d2-2e86-dc9cdf981347.png)


|項目|説明|今回値|
|---|---|---|
|名前タグ|このVPN接続に付ける任意の名前|**VPN Test 1**|
|仮想プライベートゲートウェイ|VPN接続を作成するVGWを選択|**vgw-2d85382c**|
|カスタマーゲートウェイ|対向のカスターゲートウェイについて、既存のゲートウェイを利用するか新規に作成するか選択|**新規**|
|IPアドレス|カスタマーゲートウェイのIPアドレス。GCP側で予約した外部IPアドレスを入力|**35.189.141.66**|
|BGP ASN|カスタマーゲートウェイ側BGP AS番号|**65000**（デフォルト）|
|ルーティングオプション|ルートの管理方法を選択|**動的**（デフォルト）|
|トンネルオプション||全て空欄|

<br />２つ目のVPN接続も１つ目と同様に作成（`IPアドレス`はGCP側で予約した、別の外部IPアドレスを入力）
![aws_vpn_02.png](https://qiita-image-store.s3.amazonaws.com/0/94476/3db7a760-672c-c580-3db9-18cff753870e.png)


これで下図のように、２つのVPN接続が作成される。
![aws_vpn_03.png](https://qiita-image-store.s3.amazonaws.com/0/94476/a04524cc-cde9-d554-df32-eaa028c58618.png)


またVPN接続と同時にカスタマーゲートウェイも同時に作成される。（コンソールから`VPC`＞`カスタマーゲートウェイ`）
![aws_vpn_04.png](https://qiita-image-store.s3.amazonaws.com/0/94476/2d9d0e89-e20c-c0c8-4d66-ff1f101a6946.png)


VPN接続の`状態`が`保留中`から`使用可能`に変わった後、それぞれのVPN接続を選択して`設定のダウンロード`をクリック
![aws_vpn_05.png](https://qiita-image-store.s3.amazonaws.com/0/94476/46fb375a-b146-9c72-6788-7588a332ee90.png)


`ベンダー`に`Generic`を選択して`ダウンロード`をクリック、任意の場所に設定ファイルを保存する。
![aws_vpn_06.png](https://qiita-image-store.s3.amazonaws.com/0/94476/230286ab-ac08-77fe-c020-d09e6192cc78.png)


ダウンロードした設定ファイルには、GCP側でVPN接続を作成する際に必要な情報が記載されている。
このファイルをテキストエディタ（改行コードが`LF`な点に注意）で開けば内容を確認できる。

また設定ファイルには、`Tunnel #1`と`Tunnel #2`の２セッション分が記載されているが、各VPN接続で設定するトンネルは１つなので、`Tunnel #1`の情報だけを利用する。

以下、各設定ファイルの内容から必要な情報のみ抜粋する。

（１つ目のVPN）

```text:vpn-5db35034.txt
IPSec Tunnel #1
================================================================================
#1: Internet Key Exchange Configuration
Configure the IKE SA as follows:
  - IKE version              : IKEv1 
  - Pre-Shared Key           : pcXXXXXXXXXXXXXXXXXXXXXXXXXXXXxS

#3: Tunnel Interface Configuration
Outside IP Addresses:
  - Customer Gateway 		        : 35.189.141.66 
  - Virtual Private Gateway	        : 13.113.157.43

Inside IP Addresses
  - Customer Gateway         		: 169.254.26.158/30
  - Virtual Private Gateway             : 169.254.26.157/30

#4: Border Gateway Protocol (BGP) Configuration:
BGP Configuration Options:
  - Customer Gateway ASN	          : 65000 
  - Virtual Private  Gateway ASN          : 64512
```

（２つ目のVPN）

```text:vpn-5db35035.txt
IPSec Tunnel #1
================================================================================
#1: Internet Key Exchange Configuration
Configure the IKE SA as follows:
  - IKE version              : IKEv1 
  - Pre-Shared Key           : MqXXXXXXXXXXXXXXXXXXXXXXXXXXXXP3

#3: Tunnel Interface Configuration
Outside IP Addresses:
  - Customer Gateway 		        : 35.189.143.44 
  - Virtual Private Gateway	        : 13.113.145.178
		
Inside IP Addresses
  - Customer Gateway         		: 169.254.26.134/30
  - Virtual Private Gateway             : 169.254.26.133/30

#4: Border Gateway Protocol (BGP) Configuration:
BGP Configuration Options:
  - Customer Gateway ASN	          : 65000 
  - Virtual Private  Gateway ASN          : 64512
```

## (GCP) クラウドルータの作成
コンソールから`ハイブリッド接続`＞`クラウド ルーター`を開き、`ルーターを作成`をクリック

各項目を入力してクラウドルーターを作成
![gcp_vpn_03.png](https://qiita-image-store.s3.amazonaws.com/0/94476/a9ac8671-264e-9f5a-22d6-9f28e8886cfd.png)


|項目|説明|今回値|
|---|---|---|
|名前|このクラウドルーターに付ける任意の名前|**vpn-router**|
|ネットワーク|このクラウドルーターをアタッチするVPC|**test-vpc**|
|名前|このクラウドルーターをアタッチするリージョン|**asia-northeast1**|
|名前|クラウドルーターのBGP AS番号、特に変更する必要が無ければ`65000`|**65000**|


## (GCP) VPN接続の作成
### １つ目のVPN接続の作成
前述のAWS側でダウンロードした１つ目の設定ファイルの情報を元に、１つ目のVPN接続を作成する。

コンソールから`ハイブリッド接続`＞`VPN`を開き、`作成`をクリック

VPNゲートウェイとトンネルの各項目を入力してVPN接続を作成
![gcp_vpn_04.png](https://qiita-image-store.s3.amazonaws.com/0/94476/457b4e00-7d18-cffa-47f8-7dc031540cf9.png)


（VPNゲートウェイ項目）

|項目|説明|今回値|
|---|---|---|
|名前|このVPNゲートウェイに付ける任意の名前|**vpn-test-1-gw**|
|ネットワーク|このVPNゲートウェイをアタッチするVPC|**test-vpn**|
|リージョン|このVPNゲートウェイをアタッチするリージョン|**asia-northeast1**|
|IPアドレス|予約しておいた１つ目の外部IPアドレス|**35.189.141.66**|

（VPNトンネル項目）

|項目|説明|今回値|
|---|---|---|
|名前|このVPNトンネルに付ける任意の名前|**vpn-test-1-tun**|
|リモートピア IP アドレス|１つ目の設定ファイルにある`Outside IP Addresses`の`Virtual Private Gateway`|**13.113.157.43**|
|IKEバージョン|IKEプロトコルのバージョンを選択|**IKEv1**|
|共有シークレット|１つ目の設定ファイルにある`Pre-Shared Key`|**pcXXX...XXXxS**|
|ルーティング オプション|ルーティングの設定方法|**動的（BGP）**|
|クラウドルーター|このVPNゲートウェイと連携するクラウドルーターを選択|**vpn-router**|
|BGP セッション|（後述参照）|

`BGP セッション`の右にある鉛筆マークをクリックすると`BGP セッションの作成`ダイアログが表示されるので、各項目を入力
![gcp_vpn_05.png](https://qiita-image-store.s3.amazonaws.com/0/94476/e7fdd211-0362-1977-8116-eab1e2d1caa9.png)


|項目|説明|今回値|
|---|---|---|
|名前|このBGPセッションに付ける任意の名前|**vpn-test-1-bgp**|
|ピア ASN|１つ目の設定ファイルにある`Virtual Private  Gateway ASN`|**64512**|
|Cloud Router の BGP IP|１つ目の設定ファイルにある`Inside IP Addresses`の`Customer Gateway`|**169.254.26.158**|
|BGP ピア IP|１つ目の設定ファイルにある`Inside IP Addresses`の`Virtual Private Gateway`|**169.254.26.157**|

### ２つ目のVPN接続の作成
１つ目のVPN接続と同様に、今度はダウンロードした２つ目の設定ファイルの情報を元に、２つ目のVPN接続を作成する。

コンソールから`ハイブリッド接続`＞`VPN`を開き、`作成`をクリック

VPNゲートウェイとトンネルの各項目を入力してVPN接続を作成
![gcp_vpn_06.png](https://qiita-image-store.s3.amazonaws.com/0/94476/5243a527-e94f-3b1b-1365-010b347ab663.png)


（VPNゲートウェイ項目）

|項目|説明|今回値|
|---|---|---|
|名前|このVPNゲートウェイに付ける任意の名前|**vpn-test-2-gw**|
|ネットワーク|このVPNゲートウェイをアタッチするVPC|**test-vpn**|
|リージョン|このVPNゲートウェイをアタッチするリージョン|**asia-northeast1**|
|IPアドレス|予約しておいた２つ目の外部IPアドレス|**35.189.143.44**|

（VPNトンネル項目）

|項目|説明|今回値|
|---|---|---|
|名前|このVPNトンネルに付ける任意の名前|**vpn-test-2-tun**|
|リモートピア IP アドレス|２つ目の設定ファイルにある`Outside IP Addresses`の`Virtual Private Gateway`|**13.113.145.178**|
|IKEバージョン|IKEプロトコルのバージョンを選択|**IKEv1**|
|共有シークレット|２つ目の設定ファイルにある`Pre-Shared Key`|**MqXXX...XXXP3**|
|ルーティング オプション|ルーティングの設定方法|**動的（BGP）**|
|クラウドルーター|このVPNゲートウェイと連携するクラウドルーターを選択|**vpn-router**|
|BGP セッション|（後述参照）|

`BGP セッション`の右にある鉛筆マークをクリックすると`BGP セッションの作成`ダイアログが表示されるので、各項目を入力
![gcp_vpn_07.png](https://qiita-image-store.s3.amazonaws.com/0/94476/232a99cd-42dc-7a5b-3bf2-cbec7f25f609.png)


|項目|説明|今回値|
|---|---|---|
|名前|このBGPセッションに付ける任意の名前|**vpn-test-2-bgp**|
|ピア ASN|２つ目の設定ファイルにある`Virtual Private  Gateway ASN`|**64512**|
|Cloud Router の BGP IP|２つ目の設定ファイルにある`Inside IP Addresses`の`Customer Gateway`|**169.254.26.134**|
|BGP ピア IP|２つ目の設定ファイルにある`Inside IP Addresses`の`Virtual Private Gateway`|**169.254.26.133**|

これで下図のように、VPNゲートウェイが２つ作成される。
![gcp_vpn_08.png](https://qiita-image-store.s3.amazonaws.com/0/94476/c9d2896e-13f9-ea03-33d0-3524f2dd5f86.png)


## (GCP) IPsec、BGPセッションの確認
`Google VPN トンネル`をクリックすると、下図のように作成した２つのトンネルが表示される。
それぞれの`ステータス`が`確立済み`であれば、IPsecでのVPNセッションが対向のAWS側VPNセッションと確立していることを表す。
![gcp_vpn_09.png](https://qiita-image-store.s3.amazonaws.com/0/94476/b2be0ac7-bcf5-a0a8-98c8-cbb20ed3ae16.png)


コンソールから`ハイブリッド接続`＞`クラウド ルーター`を開き、VPNを設定したクラウドルーターの名前（`vpn-router`）をクリック

下図のようにBGPセッションが２つ表示されていれば、２本のVPNセッションを介してそれぞれBGPセッションが確立されていることが判る。
更にアドバタイズ（広報）されたルートにある`ネクストホップ`を確認すると、BGPのベストパス（優先ルート）がどちらのVPNセッションに設定されているか判る。（下図の場合、`vpn-test-1-tun`が優先ルートになっている。）
![gcp_vpn_10.png](https://qiita-image-store.s3.amazonaws.com/0/94476/90fc1100-89bb-6207-9b4a-5d048afc3f9f.png)


## (AWS) IPsec、BGPセッションの確認
コンソールから`VPC`＞`VPN接続`を開き、各VPN接続を選択して`トンネル詳細`タブをクリックすると、トンネルの状態を確認することができる。
`詳細`列が`X BGP ROTES`または`IPSEC IS UP`となっていればIPsecでのVPNセッションが確立されていることを表し、`状態`列が`アップ`となっていればBGPセッションが確立されていることを表している。

（VPN#1側）
![aws_vpn_07.png](https://qiita-image-store.s3.amazonaws.com/0/94476/bbcc4296-5a71-5c38-b0b1-617765815c4b.png)

（VPN#2側）
![aws_vpn_08.png](https://qiita-image-store.s3.amazonaws.com/0/94476/f3bd04b9-5dd3-18e8-24b4-3c2bde84f06f.png)


## (GCP) ルートテーブルの確認
コンソールから`VPCネットワーク`＞`ルート`を開くと、プロジェクトのルーティングテーブルを確認することができる。
下図のように、AWS側からアドバタイズされたルートが動的に追加されていることが判る。
![gcp_vpn_11.png](https://qiita-image-store.s3.amazonaws.com/0/94476/edbb7ec5-eb15-0438-7d17-c38ffa9a01ba.png)


（何故ベストパス以外のルートが、ルーティングテーブルに追加されているのか不明･･･。挙動に支障はないけど）

## (AWS) ルートテーブルの確認
コンソールから`VPC`>`ルートテーブル`を開き、VPNを作成したVPCのルートテーブルを選択後`ルート`タブをクリックする。
BGPセッションが確立していれば、下図のようにGCPからアドバタイズされたルートが動的に追加されている。
![aws_vpn_09.png](https://qiita-image-store.s3.amazonaws.com/0/94476/8bbf23ed-bfc7-10ad-b6f6-27576525e63b.png)


もしBGPセッションが確立しているにも関わらずCGPへのルートが追加されてい場合は、`ルート伝播`タブをクリックし、`伝播`列が`はい`となっているか確認する。
もし下図のように`いいえ`になっている場合、GCPからのアドバタイズを無視してしまうので、編集して`はい`に変更する。
![aws_vpn_10.png](https://qiita-image-store.s3.amazonaws.com/0/94476/35859b6d-d655-4596-e147-56b1297baac4.png)
↓↓↓↓↓変更
![aws_vpn_11.png](https://qiita-image-store.s3.amazonaws.com/0/94476/8ab0fef8-79e4-18cc-f579-b0332aa76191.png)


# 疎通、フェイルオーバーテスト

## (AWS, GCP) インスタンスの作成

CGP、AWSそれぞれにLinux（今回は`CentOS7`）のインスタンスを作成する。（作成手順は割愛）
またAWS側のインスタンス側のセキュリティグループには、GCPからのPingを通すよう、インバウンド側への`ICMP`通信を許可するルールを追加しておく。

## Pingテスト
GCPのVMインスタンスからEC2インスタンスに対し、Pingを10回送ってみた。
距離が近いだけに（東京リージョン間）、思っていたより速度が出ている感じだ。

```bash
$ ping -c 10 10.2.0.6
PING 10.2.0.6 (10.2.0.6) 56(84) bytes of data.
64 bytes from 10.2.0.6: icmp_seq=1 ttl=64 time=7.64 ms
64 bytes from 10.2.0.6: icmp_seq=2 ttl=64 time=6.76 ms
64 bytes from 10.2.0.6: icmp_seq=3 ttl=64 time=6.85 ms
64 bytes from 10.2.0.6: icmp_seq=4 ttl=64 time=6.76 ms
64 bytes from 10.2.0.6: icmp_seq=5 ttl=64 time=6.80 ms
64 bytes from 10.2.0.6: icmp_seq=6 ttl=64 time=6.60 ms
64 bytes from 10.2.0.6: icmp_seq=7 ttl=64 time=6.74 ms
64 bytes from 10.2.0.6: icmp_seq=8 ttl=64 time=6.63 ms
64 bytes from 10.2.0.6: icmp_seq=9 ttl=64 time=6.70 ms
64 bytes from 10.2.0.6: icmp_seq=10 ttl=64 time=6.57 ms
--- 10.2.0.6 ping statistics ---
10 packets transmitted, 10 received, 0% packet loss, time 9017ms
rtt min/avg/max/mdev = 6.571/6.810/7.645/0.302 ms
```

## フェイルオーバーテスト
AWS、GCP共に、VPNのセッションを一時的に切断する方法が見当たらなかったので、GCP側のトンネルを削除することで検証した。

GCP側VMインスタンスからEC2インスタンスに対し、Pingを実行しておく。

```bash
$ ping 10.2.0.6
PING 10.2.0.6 (10.2.0.6) 56(84) bytes of data.
64 bytes from 10.2.0.6: icmp_seq=1 ttl=64 time=8.13 ms
64 bytes from 10.2.0.6: icmp_seq=2 ttl=64 time=6.75 ms
64 bytes from 10.2.0.6: icmp_seq=3 ttl=64 time=6.81 ms
･･･
```

GCPコンソールから`ハイブリッド接続`＞`クラウド ルーター`を開き、`vpn-router`をクリックして詳細を確認し、どちらのVPN接続がベストパスに選択されているか確認する。
この時は下図のように、`vpn-test-2`がベストパスとして選択されていた。
![gcp_vpn_12.png](https://qiita-image-store.s3.amazonaws.com/0/94476/01d3d0b7-2782-bc55-cedd-fcc0c8b8fc91.png)

サイドメニューの`VPN`を開き、`vpn-test-2-tun`をクリックして詳細ページにある`削除`をクリックする。
![gcp_vpn_13.png](https://qiita-image-store.s3.amazonaws.com/0/94476/9066ceb1-f7ad-1afc-c1cd-e1ba2610588a.png)


暫くすると`vpn-test-2-tun`が削除される。
![gcp_vpn_14.png](https://qiita-image-store.s3.amazonaws.com/0/94476/6fb29981-a228-915f-59cc-03a9a9939da2.png)


実行しておいたPingの状態を確認する。
`icmp_seq`が`85`から`115`に飛んでいるので、この間にルーティングが`vpn-test-1`側に切り替わったことが想像できる。（`クラウド ルーターの詳細`ページで確認可能）
またPingの間隔はデフォルトでは**1秒**なので、フェイルオーバーに約30秒かかっていると思われる。

```bash
･･･
64 bytes from 10.2.0.6: icmp_seq=83 ttl=64 time=4.98 ms
64 bytes from 10.2.0.6: icmp_seq=84 ttl=64 time=5.24 ms
64 bytes from 10.2.0.6: icmp_seq=85 ttl=64 time=5.10 ms
64 bytes from 10.2.0.6: icmp_seq=115 ttl=64 time=5.87 ms
64 bytes from 10.2.0.6: icmp_seq=116 ttl=64 time=5.13 ms
64 bytes from 10.2.0.6: icmp_seq=117 ttl=64 time=5.06 ms
･･･
```

何回かテストしてみた結果、**瞬時～30秒**で切り替わることが確認できた。
[RFC1771](https://tools.ietf.org/html/rfc1771)(「Appendix 6.4 BGP Timers」)では**30秒**が推奨されているので、この仕様に従って最小アドバタイズの間隔が設定されていると思われる。

削除したVPNトンネル`vpn-test-2-tun`を再作成し、もう一方のトンネルも削除して同様の試験を実施する。（テストの内容は上記と同様なため割愛）
尚、トンネルを再作成する際、VPNゲートウェイ`vpn-test-2-gw`は削除されず残っているので、VPNゲートウェイの詳細ページから`VPN トンネルを追加`をクリックしてトンネルのみ作成する。
![gcp_vpn_15.png](https://qiita-image-store.s3.amazonaws.com/0/94476/c463dfdd-d5d0-dd2a-5b47-fb22fb602791.png)