マルチクラウド接続 S2S VPNサービス+独自VPNによる冗長化

# 概要
パブリッククラウド間をネットワーク接続するためには様々な選択肢があります。
- 専用線接続
    - DirectconnectやExpressRouteを利用
    - 閉域のためサービス品質が高い
    - ネットワーク接続業者を経由するため費用がかかる
    - サービスメンテナンス時は利用できない。コントロールも難しい
- Site to Site VPNサービス(S2S VPNサービス)
    - パブリッククラウドで提供しているVPNサービスを利用
    - すぐに開始ができる
    - サービスメンテナンス時は利用できない。コントロールも難しい
- 独自のVPNを構築
    - VMにlibreswan等のVPNを導入
    - サービスに係る料金がかからない
    - すぐに開始ができる
    - 自分でVPNをメンテナンスする必要がある

可用性を高めるためにはこれらのサービスを組み合わせることが有効かと思います。
この記事ではS2S VPNサービスと独自のVPNを組み合わせた検証を行っています。

# 何がいいの?
- 適切なコスト
マルチクラウド実現のためにはネットワークの費用や可用性が課題となります。
専用線は品質やサポートの面で優位ですが費用の高さがネックとなります。
一方Internet VPNは費用やサービス開始が速い利点はありますがサービス品質に不安があります。
S2S VPNサービスと独自のVPNの組み合わせは専用接続よりもコストが安く異経路で構成するため冗長性を実現かと思います。
- 十分な実績のある技術を組み合わせ
信頼性を高めるため十分な実績のある技術を組み合わせます。
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/83553615-f756-baba-3448-819910e9dbd4.png">

# 構成
今回はAWSとOCIを接続する検証を行います。
- AWS内のVPC1およびOCI内のVCN1は既に稼働中の前提です
- VPC1内のEC2(10.2.3.100)とVCN1のVM(10.105.2.100)の通信が可能になるよう設定します
- S2S VPNサービスをメイン経路、libereswanを使用した独自のVPNをバックアップ経路とするActive-Standby構成を設定します
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/aff71688-95d7-7747-f8e9-bd95f8a294ff.png">

# メイン経路作成
S2S VPNサービスを使用してメイン経路を作成します。
## AWS TGW用サブネット作成
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>サブネットを選択
- 「サブネットを作成」を押下
- 以下を入力して「サブネットを作成」を押下
    - VPC IDは10.2.0.0/16を選択
    - サブネット名
    - アベイラビリティーゾーン
    - IPv4サブネットCIDRブロックに10.2.255.0/28を入力
## AWS Transit Gateway(TGW)作成
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Transit Gatewayを選択
- 「Transit Gatewayを作成」を押下
- 名前を入力して「Transit Gatewayを作成」を押下

## AWS TGWアタッチメント VPC追加
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Transit Gatewayアタッチメントを選択
- 「Transit Gateway アタッチメントの作成」押下
- 以下を入力して「Transit Gateway アタッチメントの作成」押下
    - 名前
    - Transit Gateway IDに作成したTGWを選択
    - アタッチメントタイプはVPCを選択
    - VPC IDは10.2.0.0/16を選択
    - サブネットIDはTGW用サブネットを選択

## AWS 仮CGW作成
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>カスタマーゲートウェイを選択し「カスタマーゲートウェイを作成 」を押下
- 仮の名前、仮のIP アドレスを入力して「カスタマーゲートウェイを作成 」を押下

## AWS TGWアタッチメント VPN追加
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Transit Gatewayアタッチメントを選択
- 「Transit Gateway アタッチメントの作成」押下
- 以下を入力して「Transit Gateway アタッチメントの作成」押下
    - Transit Gateway IDに作成したTGWを選択
    - アタッチメントタイプはVPNを選択
    - カスタマーゲートウェイは先程作成したCGWを選択
    - ルーティングオプションはBGP
    - 内部IPはAWS自動生成
    - 事前共有キー
- 作成されたアタッチメントに名前を設定
    
## OCI DRG作成
- OCIコンソール　ナビゲーションメニューからネットワーキング>>顧客接続性>>
動的ルーティング・ゲートウェイを選択して「動的ルーティング・ゲートウェイの作成」を押下
- 名前を入力して「動的ルーティング・ゲートウェイの作成」を押下

## OCI DRGアタッチメント VCN追加
- OCIコンソール　ナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワーク>>VCN1を選択して画面左のResourcesから動的ルーティング・ゲートウェイのアタッチメントを選択して「DRGアタッチメントの作成」を押下
- 名前とDRGを選択して「DRGアタッチメントの作成」を押下

## OCI S2S VPN CPE作成
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Site-to-Site VPN 接続を選択
- 対象VPNを選択してTunnel1の外部IPアドレスと内部IPv4 CIDRをメモ
- OCIコンソール　ナビゲーションメニューからネットワーキング>>顧客接続性>>顧客構内機器を選択して「CPEの作成」を押下
- 以下を入力して「CPEの作成」を押下
    - 名前
    - IPアドレスにTunnel1の外部IPアドレスを入力
    - CPEベンダー情報はOtherを指定

## OCI S2S VPN作成
- OCIコンソール　ナビゲーションメニューからネットワーキング>>顧客接続性>>サイト間VPNを選択して「IPSec接続の作成」を押下
- 以下を入力して「IPSec接続の作成」を押下
    - 名前
    - 顧客構内機器：先ほど作成したCPE
    - DRG:既存のDRG
    - トンネル1の情報
        - 名前
        - 共有シークレット：AWSで設定した事前共有キー
        - IKEバージョン：IKEv2
        - ルーティングタイプ：BGP
        - BGP ASN:64512
        - IPv4トンネル内インターフェース-CPE:AWS 内部IPv4 CIDR+1のアドレス
        - IPv4トンネル内インターフェース-Oracle:AWS 内部IPv4 CIDR+2のアドレス
        - デッド・ピア検出タイムアウト(秒): 30 
          AWSのデフォルトに合わせる
        - フェーズ1
            - カスタム暗号化アルゴリズム:AES_256_CBC
            - カスタム認証アルゴリズム:SHA2_384
            - カスタムDHグループ:GROUP20
        - フェーズ2
            - カスタム暗号化アルゴリズム:AES_256_CBC
            - カスタム認証アルゴリズム:HMAC_SHA2_256_128
            - カスタムDHグループ:GROUP5
    - トンネル2の情報
    　 トンネル2は使用しませんが設定しないとエラーになるため適当に作成
- 作成されたらトンネル1のOracle VPN IPアドレスをメモ

## AWS CGW作成
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>カスタマーゲートウェイを選択し「カスタマーゲートウェイを作成 」を押下
- 以下を入力して「カスタマーゲートウェイを作成 」を押下
    - 名前
    - BGP ASN: 31898
    - IP アドレス:Oracle VPN IPアドレス

## AWS CGW差し替え
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Site-to-Site VPN 接続を選択
- 対象VPNを選択しアクション>>VPN接続を変更を選択
- ターゲットのCGWを先程作成したCGWに差し替えて「変更を保存」を押下
- 変更完了後、仮CGWは削除可能

## AWS VPNパラメータ固定
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Site-to-Site VPN 接続を選択
- 対象VPNを選択しアクション>>VPNトンネルオプションを変更を選択
- 以下のように変更
    - UP トンネルの変更を確認にチェック
    - フェーズ 1 暗号化アルゴリズム: AES256
    - フェーズ 2 暗号化アルゴリズム: AES256
    - フェーズ 1 整合性アルゴリズム: SHA2-384
    - フェーズ 2 整合性アルゴリズム: SHA2-256
    - フェーズ 1 DH グループ番号:20
    - フェーズ 2 DH グループ番号:5
    - IKE バージョン:ikev2

## AWS VPC route(10.105.0.0/16)追加
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>ルートテーブルを選択
- VPC1のルート表を選択してルート・ルールを追加
    - 宛先：10.105.0.0/16　ターゲット：トランジットゲートウェイ

## AWS VPC NSG追加
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>セキュリティグループを選択
- 対象のセキュリティグループを選択し通信許可を追加
    - 10.105.0.0/16からの通信

## OCI VCN route(10.2.0.0/16)追加
- OCIコンソール　ナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワーク>>VCN1を選択
- 画面左のResourcesからサブネットを選択して、対象サブネットを選択
- ルート表を選択してルート・ルールを追加
    - 宛先：10.2.0.0/16　ターゲット：DRG

## OCI VCN SL追加
- OCIコンソール　ナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワーク>>VCN1を選択
- 画面左のResourcesからサブネットを選択して、対象サブネットを選択
- セキュリティリストを選択し通信許可を追加
    - 10.2.0.0/16からの通信

## AWS ルーティング確認
OCIのネットワーク情報がAWSに届いていることを確認します。
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Transit Gateway ルートテーブルを選択
- 対象のルートテーブルを選択してルートを選択してOCI VCN情報がVPNを経由して伝搬されていることを確認
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/59db23a6-50c6-e07e-b3f0-2413474d7c6d.png">

## OCI ルーティング確認
AWSのネットワーク情報がAWSに届いていることを確認します。
- OCIコンソール　ナビゲーションメニューからネットワーキング>>顧客接続性>>動的ルーティング・ゲートウェイ>>DRG>>VCNアタッチメント>>対象のアタッチメントを選択
- DRGルート表を選択
- 「すべてのルート・ルールの取得」を押下し、AWS VPC情報がVPNを経由して伝搬されていることを確認
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/881606f5-26c8-9e16-a1a0-e5143f6fd43c.png">

# バックアップ経路作成
libereswanを使用した独自のVPNを作成します。
## AWS VPC作成
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPCを選択
- 「VPCを作成」を押下
- 名前およびIPv4 CIDR(10.3.0.0/16)を入力して「VPCを作成」を押下
- 左メニューからサブネットを選択
- 「サブネットの作成」を押下
- VPCIDに先ほど作成したVPCを選択、サブネット名およびIPv4 サブネットCIDRブロック(10.3.1.0/24)を入力して「サブネットを作成」を押下
- 続けてTGW用のサブネット(10.3.255.0/28)を作成
- インターネットゲートウェイを選択して「インターネットゲートウェイの作成」を押下
- 名前を入力して「インターネットゲートウェイの作成」を押下
- インターネットゲートウェイをVPC2にアタッチ
- ルートテーブルを選択して対象ルートテーブルを選択
- ルート追加
    - 送信先:0.0.0.0/0 ターゲット：インターネットゲートウェイ

## AWS Elastic IPアドレスの割り当て
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPCを選択
- 左メニューからElastic IPを選択し「Elastic IPアドレスを割り当てる」を押下
- パブリックIPv4アドレスプールに「AmazonのIPv4アドレスプール」が選択されていることを確認して「割り当て」を押下
- 作成されたElastic IPの名前を追加
<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/643e48c2-98ed-1ce8-c35a-affe555da478.png">

## OCI VCN作成
- OCIコンソール　ナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワークを選択して「VCNの作成」を押下
- 名前およびIPv4 CIDR blocks(10.106.0.0/16)を入力して「VCNの作成」を押下
- 画面左のResourcesからサブネットを選択して「サブネットの作成」を押下
- 名前、CIDR block(10.106.1.0/24)およびサブネット・アクセスはパブリック・サブネットを選択して「サブネットの作成」を押下
- 画面左のResourcesからインターネット・ゲートウェイを選択して「インターネット・ゲートウェイの作成」を押下
- 名前を入力して「インターネット・ゲートウェイの作成」を押下
- 画面左のResourcesからサブネットを選択して、作成したサブネットを選択
- ルート表を選択してルート・ルールを追加
    - 宛先：0.0.0.0/0　ターゲット：インターネットゲートウェイ

## OCI パブリックIPアドレスの予約
- OCIコンソール　ナビゲーションメニューからネットワーキング>>IP管理>>予約済パブリックIPを選択して「パブリックIPアドレスの予約」を押下
- 予約済パブリックIPアドレス名を入力して「パブリックIPアドレスの予約」を押下

## AWS セキュリティグループ作成
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPCを選択
- 「セキュリティグループを作成」を押下
- 対象のセキュリティグループを選択し、以下の通信許可を設定
    - OCI パブリックIPからTCP/500および4500
    - OCI パブリックIPからUDP/500および4500
    - OCI パブリックIPからICMP
    - AWS VPC1,VPC2およびOCI VCN1,VCN2からの通信

## OCIセキュリティリスト作成
- OCIコンソール　ナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワークを選択して対象VCNを選択
- 画面左のResourcesからサブネットを選択して、作成したサブネットを選択
- セキュリティリストを選択し、以下の通信許可を設定
    - AWS Elastic IPからTCP/500および4500
    - AWS Elastic IPからUDP/500および4500
    - AWS Elastic IPからICMP
    - AWS VPC1,VPC2およびOCI VCN1,VCN2からの通信

## AWS EC2作成
- AWSコンソールからサービスメニュー>>コンピューティング>>EC2を選択
- 「インスタンスを起動」を押下しインスタンスを作成
    - OSはAmazon linux
    - インスタンスタイプは検証ではt3a.microを選択
    - 10.3.1.0/24配下に作成
    - 10.3.1.200を固定アサイン
- 割り当てたElastic IPをEC2に割り当て
    - コンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Elastic IPを選択
    - 対象のIPを選択し「Elastic IPアドレスの関連付けを押下」
    - 作成したインスタンスを選択して「関連付ける」を押下
- インスタンスのアクションからネットワーキング>>ソース/宛先チェックを変更を選択して、停止を選択して「保存」を押下

## OCI VM作成
- OCIコンソール　ナビゲーションメニューからコンピュート>>インスタンスを選択
- 「インスタンスの作成」を押下しインスタンスを作成
    - OSはOracle Linux
    - インスタンスタイプは検証ではE4を選択
    - 10.106.1.0/24配下に作成
    - 10.106.1.200をプライベートIPv4アドレスの手動割当て
- 割り当てたパブリックIPアドレスをインスタンスに割り当て
    - 画面左のResourcesからアタッチされたVNICを選択
    - 対象VNICの右の三点リーダーメニューからVNICの編集を選択して、ソース/宛先チェックのスキップにチェックして保存
    - 対象VNICを選択して画面左のResourcesからIPv4 アドレスを選択
    - 対象IPv4の右の三点リーダーメニューから編集を選択
    - パブリックIPタイプを「パブリックIPがありません」に選択/更新後、再度編集して予約済パブリックIPを選択して作成した予約済IPを選択して更新

## AWS libreswanセットアップ
- EC2にloginしてlibreswanをセットアップします
```
# libreswanを導入
$ sudo yum -y update 
$ sudo yum -y install libreswan

# 導入確認
$ sudo ipsec --version
Libreswan 4.12

# Interfaceを確認(interface ens5)
$ ifconfig

# /etc/sysctl.confに項目追加
net.ipv4.ip_forward=1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens5.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.ens5.accept_redirects = 0

#更新
$ sudo sysctl -p

# サービス自動起動を有効
$ sudo systemctl enable ipsec --now

# /etc/ipsec.d/oci-ipsec.confを編集
conn oracle-tunnel-1
     left=10.3.1.200
     leftid=【AWS側Global IP】
     right=【OCI側Global IP】
     authby=secret
     leftsubnet=0.0.0.0/0
     rightsubnet=0.0.0.0/0
     auto=start
     mark=5/0xffffffff
     vti-interface=vti1
     vti-routing=no
     ikev2=insist
     ike=aes_cbc256-sha2_384;modp1536
     phase2alg=aes_gcm256;modp1536
     encapsulation=yes
     ikelifetime=28800s
     salifetime=3600s

# /etc/ipsec.d/oci-ipsec.secretsを編集
【OCI側Global IP】 【AWS側Global IP】: PSK "【事前共有キー】"

# ipsec再起動
$ sudo ipsec restart
```

## OCI libreswanセットアップ
- VMにloginしてlibreswanをセットアップします
```

# SELinuxを一時的にPermissiveモードにする
$ sudo setenforce 0 

# /etc/selinux/configを更新
SELINUX=disabled

# Firewallを停止
$ sudo systemctl stop firewalld
$ sudo systemctl disable firewalld

# libreswanを導入
$ sudo dnf install -y libreswan

# 導入確認
$ sudo ipsec --version
Libreswan 4.12

# Interfaceを確認(interface ens3)
$ ifconfig

# /etc/sysctl.confに項目追加
net.ipv4.ip_forward = 1
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.ens3.send_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.ens3.accept_redirects = 0
net.ipv4.conf.all.rp_filter = 0
net.ipv4.conf.default.rp_filter = 0
net.ipv4.conf.ens3.rp_filter = 0

#更新
$ sudo sysctl -p

# サービス自動起動を有効
$ sudo systemctl enable ipsec --now

#設定反映を確認
$ sudo ipsec verify
Verifying installed system and configuration files

Version check and ipsec on-path                         [OK]
Libreswan 4.12
Checking for IPsec support in kernel                    [OK]
 NETKEY: Testing XFRM related proc values
         ICMP default/send_redirects                    [OK]
         ICMP default/accept_redirects                  [OK]
         XFRM larval drop                               [OK]
Pluto ipsec.conf syntax                                 [OK]
Checking rp_filter                                      [OK]
Checking that pluto is running                          [OK]
 Pluto listening for IKE on udp 500                     [OK]
 Pluto listening for IKE/NAT-T on udp 4500              [OK]
 Pluto ipsec.secret syntax                              [OK]
Checking 'ip' command                                   [OK]
Checking 'iptables' command                             [OK]
Checking 'prelink' command does not interfere with FIPS [OK]
Checking for obsolete ipsec.conf options                [OK]

# /etc/ipsec.d/oci-ipsec.confを編集
conn aws-tunnel-1
     left=10.106.1.200
     leftid=【OCI側Global IP】
     right=【AWS側Global IP】
     authby=secret
     leftsubnet=0.0.0.0/0
     rightsubnet=0.0.0.0/0
     auto=start
     mark=5/0xffffffff
     vti-interface=vti1
     vti-routing=no
     ikev2=insist
     ike=aes_cbc256-sha2_384;modp1536
     phase2alg=aes_gcm256;modp1536
     encapsulation=yes
     ikelifetime=28800s
     salifetime=3600s

# /etc/ipsec.d/oci-ipsec.secretsを編集
【AWS側Global IP】 【OCI側Global IP】: PSK "【事前共有キー】"

# ipsec再起動
$ sudo ipsec restart
```
- IPSecステータスを確認します。
```
sudo ipsec trafficstatus
006 #563: "aws-tunnel-1", type=ESP, add_time=0, inBytes=101674, outBytes=101494, maxBytes=2^63B, id='【AWS側Global IP】'

$ ifconfig
vti1:の情報が表示
```
- AWS EC2にインターフェースIPおよびルーティングを追加します
```
$ sudo ip addr add 192.168.2.1/30 dev vti1
$ sudo ip route add 10.105.0.0/16 nexthop dev vti1
$ sudo ip route add 10.106.0.0/16 nexthop dev vti1
```
- OCI VMにインターフェースIPおよびルーティングを追加します
```
$ sudo ip addr add 192.168.2.2/30 dev vti1
$ sudo ip route add 10.2.0.0/16 nexthop dev vti1
$ sudo ip route add 10.3.0.0/16 nexthop dev vti1
```
- OCI VMからAWS EC2にping可能なことを確認します
```
$ ping 192.168.2.1
```
## AWS TGWアタッチメント VPC追加
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Transit Gatewayアタッチメントを選択
- 「Transit Gateway アタッチメントの作成」押下
- 以下を入力して「Transit Gateway アタッチメントの作成」押下
    - 名前
    - Transit Gateway IDに作成したTGWを選択
    - アタッチメントタイプはVPCを選択
    - VPC IDは10.3.0.0/16を選択
    - サブネット IDはTGW用サブネットを選択

## AWS TGW static route追加
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Transit Gatewayルートテーブルを選択
- Transit Gatewayルートテーブルを選択
- ルートメニューから「静的ルートを作成」を押下
- CIDRを10.105.0.0/16, 宛先のアタッチメントをVPC2のアタッチメントを選択して「静的ルートを作成」を押下

## AWS VPC1 route(10.3.0.0/16)追加 
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>ルートテーブルを選択
- VPC1のルート表にルート・ルールを追加
    - 宛先：10.3.0.0/16 ターゲット：トランジットゲートウェイ

## AWS VPC2 route(10.2.0.0/16, 10.105.0.0/16および10.106.0.0/16)追加 
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>ルートテーブルを選択
- VPC2のルート表にルート・ルールを追加
    - 宛先：10.2.0.0/16 ターゲット：トランジットゲートウェイ
    - 宛先：10.105.0.0/16 ターゲット：作成したEC2
    - 宛先：10.106.0.0/16 ターゲット：作成したEC2

## OCI DRGアタッチメント VCN追加
- OCIコンソール　ナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワーク>>VCN2を選択して画面左のResourcesから動的ルーティング・ゲートウェイのアタッチメントを選択して「DRGアタッチメントの作成」を押下
- 名前とDRGを選択して「DRGアタッチメントの作成」を押下

## OCI vcn routeをDRGに追加
ルート(宛先:AWSへの経路 Next hop:OCI VM)をVCN1に伝えるための設定です
- OCIコンソール　ナビゲーションメニューからネットワーキング>>仮想クラウド・ネットワーク>>VCN2を選択して画面左のResourcesからルート表を選択
- 「ルート表を作成」を押下しルート表を作成
    - 宛先:10.2.0.0/15, ターゲットタイプ:プライベートIP, 
 ターゲット:10.106.1.200
- 先程作成した動的ルーティング・ゲートウェイのアタッチメントを選択
- 「編集」を押下して拡張オプションの表示を選択
- VCNルート表で先ほど設定したルート表を追加

## OCI VCN1 route(10.106.0.0/16)追加
- VCN1の画面左のResourcesからサブネットを選択して、作成したサブネットを選択
- ルート表を選択してルート・ルールを追加
    - 宛先：10.106.0.0/16, ターゲット：動的ルーティングゲートウェイ

## OCI VCN2 route(10.105.0.0/16および10.2.0.0/15)追加
- VCN2の画面左のResourcesからサブネットを選択して、作成したサブネットを選択
- ルート表を選択してルート・ルールを追加
    - 宛先：10.105.0.0/16, ターゲット：動的ルーティングゲートウェイ
    - 宛先：10.2.0.0/15, ターゲット：プライベートIP 10.106.1.200
    
## AWS ルーティング確認
バックアップ経路があることを確認します。
- AWSコンソールからサービスメニュー>>ネットワーキングとコンテンツ配信>>VPC>>Transit Gateway ルートテーブルを選択
- 対象のルートテーブルを選択してルートを選択してOCI VCN情報がVPNを経由して伝搬されていることを確認
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/de40f967-1ea4-3cc6-ccae-12d73c15f571.png">

10.105.2.0/24がメイン経路、10.105.0.0/16がバックアップ経路です。

## OCI ルーティング確認
バックアップ経路があることを確認します。
- OCIコンソール　ナビゲーションメニューからネットワーキング>>顧客接続性>>動的ルーティング・ゲートウェイ>>DRG>>VCNアタッチメント>>VCN1のアタッチメントを選択
- DRGルート表を選択
- 「すべてのルート・ルールの取得」を押下し、AWS VPC情報がVPNを経由して伝搬されていることを確認
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/8021ef49-12f7-a19c-62ae-a2dfd0980ca8.png">

10.2.0.0/16がメイン経路、10.2.0.0/15がバックアップ経路です。

# 確認
AWSのTGWとOCIのDRGのルーティング状況を確認しました。
## 正常時のルーティング
ロンゲストマッチによりメイン経路が選択されます。
- AWS
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/de40f967-1ea4-3cc6-ccae-12d73c15f571.png">

10.105.2.0/24がメイン経路、10.105.0.0/16がバックアップ経路です。

-OCI
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/8021ef49-12f7-a19c-62ae-a2dfd0980ca8.png">
10.2.0.0/16がメイン経路、10.2.0.0/15がバックアップ経路です。

## メイン経路障害時のルーティング
VPN切断によりメイン経路のBGPのルートが消えたためバックアップ経路が選択されます。
- AWS
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/b26f65a3-2e2e-687f-4d5a-bc5d1a8b669a.png">

- OCI
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/24b69192-ff46-9eb4-1787-739f03179d44.png">

## バックアップ経路障害時のルーティング
バックアップ経路障害時はメイン経路には影響ありません。
- AWS
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/8f02ff06-0611-65be-1150-83b98e27121f.png">

- OCI
<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2730992/7e3fc08e-083a-74e9-1c11-cc386d12bc19.png">

# 運用
## AWS EC2起動script追加
VTIにIPアドレス付与して経路追加するためにscriptを追加します
```
$ cat /path/to/vpnstart.sh
#!/bin/sh
sleep 30
sudo ip addr add 192.168.2.1/30 dev vti1
sudo ip route add 10.105.0.0/16 nexthop dev vti1
sudo ip route add 10.106.0.0/16 nexthop dev vti1
$ chmod 755 vpnstart.sh

$ crontab -l
@reboot /path/to/vpnstart.sh
```

## OCI VM 起動script追加
VTIにIPアドレス付与して経路追加するためにscriptを追加します
```
$ cat /path/to/vpnstart.sh
#!/bin/sh
sleep 30
sudo ip addr add 192.168.2.2/30 dev vti1
sudo ip route add 10.2.0.0/16 nexthop dev vti1
sudo ip route add 10.3.0.0/16 nexthop dev vti1
$ chmod 755 vpnstart.sh

$ crontab -l
@reboot /path/to/vpnstart.sh
```

# 監視
S2S VPNサービスおよび独自VPNの稼働状況を確認するため監視設定します。
詳細手順は[OCIの監視設定例](https://qiita.com/tktk2712/items/f1c9002ff5fb20040e0a)に掲載していますのでここでは概要の説明となります。
## OCI VPN監視

[サイト間VPN VPNステータス監視](https://qiita.com/tktk2712/items/f1c9002ff5fb20040e0a#%E3%82%B5%E3%82%A4%E3%83%88%E9%96%93vpn-vpn%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E7%9B%A3%E8%A6%96)を参考にAWS-OCI間S2S VPNをOCI側から監視します

## OCI 監視　ping 死活

[Webサーバ 死活監視(Ping)](https://qiita.com/tktk2712/items/f1c9002ff5fb20040e0a#web%E3%82%B5%E3%83%BC%E3%83%90-%E6%AD%BB%E6%B4%BB%E7%9B%A3%E8%A6%96ping)参考に、AWS EC2-OCI VM libreswan VPN接続において、OCI VMからAWS EC2へのping結果をカスタムメトリックとして送信するスクリプトを作成します

- OCI VMにping結果をカスタムメトリックとして送信するスクリプトを作成
```pingcheck.py
import oci,psutil,datetime
from pytz import timezone
import subprocess

# initialize service client with InstancePrincipals
signer = oci.auth.signers.InstancePrincipalsSecurityTokenSigner()
monitoring_client = oci.monitoring.MonitoringClient(config={},signer=signer,service_endpoint="https://telemetry-ingestion.ap-tokyo-1.oraclecloud.com")

times_stamp = datetime.datetime.now(timezone('UTC'))

with open('/path/to/pingdata.txt') as f:
    l_strip = [s.strip() for s in f.readlines()]
    hosts = (l_strip)

for host in hosts:
    res = subprocess.run(["ping",host,"-c","1", "-W", "1"],stdout=subprocess.PIPE)

    post_metric_data_response = monitoring_client.post_metric_data(
        post_metric_data_details=oci.monitoring.models.PostMetricDataDetails(
        metric_data=[
            oci.monitoring.models.MetricDataDetails(
                namespace="custom_metrics",
                compartment_id="【コンパートメントOCID】",
                name="ping_result",
                dimensions={'server_id': host},
                datapoints=[
                    oci.monitoring.models.Datapoint(
                        timestamp=datetime.datetime.strftime(
                            times_stamp,"%Y-%m-%dT%H:%M:%S.%fZ"),
                            value=res.returncode)]
                )]
            )
        )
```
- ping対象はAWS EC2のトンネルインターフェース
```pingdata.txt
192.168.2.1
```
- 定期実行するクーロンを追加
```
$ crontab -l
*/1 * * * * python3 /path/to/pingcheck.py
```
## OCI 監視  VM死活監視
[Webサーバ 死活監視(不在アラーム)](https://qiita.com/tktk2712/items/f1c9002ff5fb20040e0a#web%E3%82%B5%E3%83%BC%E3%83%90-%E6%AD%BB%E6%B4%BB%E7%9B%A3%E8%A6%96%E4%B8%8D%E5%9C%A8%E3%82%A2%E3%83%A9%E3%83%BC%E3%83%A0)を参考にOCI VMの死活監視を実施します

# パフォーマンス計測
ファイル転送とPingを使ってパフォーマンスを計測しました。
- AWS、OCI共に東京リージョン
- ファイル転送はscpを平日日中に実施
- Pingはサイズ1バイトを平日に24時間以上連続実施
- VMはAWS,OCI共に最低限のシェイプを選択しているためネットワークパフォーマンスの上限あり(OCI側は0.5Gbps)

## メイン経路
- ファイル転送

|転送方向  |転送速度 |
|---|---|
|OCI->AWS  |51.9MB/s  |
|AWS->OCI  |48.3MB/s  |

- Ping

|実施回数|失敗回数|失敗率(%)|平均時間(ms)|
|---|---|---|---|
|45468  |15  |0.03  | 3|

## バックアップ経路
- ファイル転送

|転送方向  |転送速度 |
|---|---|
|OCI->AWS  |54.4MB/s  |
|AWS->OCI  |64.4MB/s  |

- Ping

|実施回数|失敗回数|失敗率(%)|平均時間(ms)|
|---|---|---|---|
|83025  |0  |0  | 4|