Google Cloud VPNとCiscoルータの接続（静的経路）

# Google Cloud VPN

外部のネットワークをGoogle Cloud Platform(GCP)に接続する方法として、以下の4つのオプションがあります。ハイブリッドクラウド的な観点からオンプレミスのインフラを接続するとなると、前の2つのどちらかになります。

- 相互接続
    - Dedicated Interconnect
    - IPsec VPN
- ピアリング
    - ダイレクトピアリング
    - キャリアピアリング

Google Cloud VPNを使うと、オンプレミスのインフラとGCP Virtual Private Cloud(VPC)ネットワークをIPsec VPN接続経由でパブリックインターネット上でトラフィックを暗号化してセキュアに接続することができます。

その他の接続方式については、以下のGoogle Cloudオフィシャルのドキュメント参考にしてください。

**CLOUD INTERCONNECT**
https://cloud.google.com/interconnect/?hl=ja

# Google Cloud VPN構成

Google Cloud VPNでGCPとオンプレミスを接続する構成には2つのオプションがあります。

一つは、GCPのVPNゲートウェイとオンプレミスのピアゲートウェイをIPsec接続する方法です。この場合、経路情報は静的に設定されます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/176968/846c8a60-213e-44cf-04c2-c20bfb31e78c.png)

もう一つは、上記のゲートウェイ間のIPsec接続に加え、GCPのCloud Routerと顧客のピアゲートウェイの間でBGPにより動的に経路情報を交換する方法です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/176968/74bc9979-331b-4747-a7b8-07c737bf252d.png)

このドキュメントでは、前者の静的経路を用いる方法を解説します。

BGP経路を用いる方法については以下の投稿を参照ください。

**Google Cloud VPNとCiscoルータの接続（BGP経路）**
https://qiita.com/tetsusat/items/e4e001d4b90eda7186b3

# 環境

このドキュメントを作成するにあたっては、以下の環境で試験してます。

- デバイス: Cisco ISR4321
- IOS XE Version: 16.8.1

他のCisco IOS XEルータ（ASR1000シリーズ、ISR4000シリーズ）でも同様の動作が期待されます。Google Cloud VPNはパブリックインターネットを通る場合は最大1.5Gbpsの転送速度で処理できるらしいので、実際はより上位のプラットフォームを選択するのがよいでしょう。

# おことわり

IKEv2およびIPsecのパラメータはGoogle Cloudのサイトに掲載されてある以下のコミュニティチュートリアルを参考にしました。

**How to Set Up VPN between Cisco ASR and Cloud VPN**
https://cloud.google.com/community/tutorials/using-cloud-vpn-with-cisco-asr

Google Cloud VPNではこの資料で設定したもの以外の各種アルゴリズムもサポートします。詳細は以下のGoogle Cloudオフィシャルのドキュメント参考にしてください。

https://cloud.google.com/compute/docs/vpn/advanced?hl=ja

# GCP側の設定

オンプレミス側の設定にはGCP側の設定時に取得するグローバルスタティックIPが必要になるので、GCP側から設定します。

VPCのネットワークを作成します。

```
gcloud compute networks create my-network \
    --subnet-mode custom
```

VPCのサブネットを作成します。
今回はGCP側のネットワークを`10.0.1.0/24`としました。

```
gcloud compute networks subnets create subnet-1 \
    --network my-network \
    --region asia-northeast1 \
    --range 10.0.1.0/24
```

ターゲットVPNゲートウェイを作成します。

```
gcloud compute target-vpn-gateways create my-vpn \
    --network my-network \
    --region asia-northeast1
```

VPNゲートウェイに使用するグローバルスタティックIPアドレスを予約します。

```
gcloud compute addresses create vpn-static-ip \
    --region asia-northeast1 
```

実際に予約されたIPアドレスは以下のコマンドの出力から分かります。

```
gcloud compute addresses describe vpn-static-ip \
    --region asia-northeast1
```

ESP、UDPポート500、UDPポート4500をVPNゲートウェイに転送する転送ルールを作成します。
`[VPN_STATIC_IP_ADDRESS]`には、前の手順で予約したスタティックIPアドレスを指定します。

```
gcloud compute forwarding-rules create fr-esp \
    --region asia-northeast1 \
    --address [VPN_STATIC_IP_ADDRESS] \
    --target-vpn-gateway my-vpn \
    --ip-protocol ESP
```

```
gcloud compute forwarding-rules create fr-udp500 \
    --region asia-northeast1 \
    --address [VPN_STATIC_IP_ADDRESS] \
    --target-vpn-gateway my-vpn \
    --ip-protocol UDP \
    --ports 500
```

```
gcloud compute forwarding-rules create fr-udp4500 \
     --region asia-northeast1 \
     --address [VPN_STATIC_IP_ADDRESS] \
     --target-vpn-gateway my-vpn \
     --ip-protocol UDP \
     --ports 4500
```

VPNトンネルを作成します。
`[CISCO_GW_EXT_IP]`には、オンプレミス側のピアゲートウェイに設定する外部IPアドレスを指定します。
`[SHARED_SECRET]`には、IKEv2認証用の共有秘密鍵を指定します。
BGP経路との違いは、Cloud Routerを指定する代わりにトラフィックセレクタを指定します。

```
gcloud compute vpn-tunnels create tunnel1 \
    --region asia-northeast1 \
    --ike-version 2 \
    --target-vpn-gateway my-vpn \
    --peer-address [CISCO_GW_EXT_IP] \
    --shared-secret [SHARED_SECRET] \
    --local-traffic-selector 10.0.1.0/24 \
    --remote-traffic-selector 192.168.1.0/24
```

オンプレミス側のネットワークに関する静的経路を設定します。

```
gcloud compute routes create route1 \
    --network my-network \
    --next-hop-vpn-tunnel tunnel1 \
    --next-hop-vpn-tunnel-region asia-northeast1 \
    --destination-range 192.168.1.0/24
```

# オンプレミス側の設定

ここからはCiscoルータの設定をします。
Cisco固有の解説は割愛しますので、適宜Ciscoが提供するドキュメント等をご参照ください。

WANインターフェイスの設定をします。
`[CISCO_GW_EXT_IP]`には、パブリックインターネットに接続するためのグローバルIPアドレスを指定します。
`[CISCO_GW_EXT_MASK]`には、上記グローバルIPアドレスに対応するマスクを指定します。

```
interface GigabitEthernet0/0/0
 ip address [CISCO_GW_EXT_IP] [CISCO_GW_EXT_MASK]
```

LANインターフェイスの設定をします。
今回はオンプレミス側のネットワークを`192.168.1.0/24`としました。

```
interface GigabitEthernet0/0/1
 ip address 192.168.1.254 255.255.255.0
```

IKEv2プロポーザルの設定をします。

```
crypto ikev2 proposal IKEV2_PROPOSAL
 encryption aes-cbc-256 aes-cbc-192 aes-cbc-128
 integrity sha256
 group 16
```

IKEv2プロファイルの設定をします。

```
crypto ikev2 policy IKEV2_POLICY
 proposal IKEV2_PROPOSAL
```

IKEv2の秘密鍵を管理するKeyringを作成します。
`[VPN_STATIC_IP_ADDRESS]`には、GCP側でVPNゲートウェイ用に用意したスタティックIPを指定します。
`[SHARED_SECRET]`には、GCP側で使用したものと同じIKEv2認証用の共有秘密鍵を指定します。

```
crypto ikev2 keyring KEY
 peer GCP
  address [VPN_STATIC_IP_ADDRESS]
  pre-shared-key [SHARED_SECRET]
```

`[VPN_STATIC_IP_ADDRESS]`には、GCP側でVPNゲートウェイ用に用意したスタティックIPを指定します。

```
crypto ikev2 profile IKEV2_PROFILE
 match address local interface GigabitEthernet0/0/0
 match identity remote address [VPN_STATIC_IP_ADDRESS]
 authentication local pre-share 
 authentication remote pre-share 
 keyring local KEY
 lifetime 36000
 dpd 60 5 periodic
```

IPsecのSAライフタイムとリプレイウィンドウサイズを設定します。前者はデフォルト値なので、実際は設定する必要はないです。

```
crypto ipsec security-association lifetime seconds 3600 
crypto ipsec security-association replay window-size 1024
```

トランスフォームセットを設定します。

```
crypto ipsec transform-set TS esp-aes 256 esp-sha-hmac
 mode tunnel
```

Crypto Mapを設定します。

```
crypto map CMAP 1 ipsec-isakmp 
 set peer [VPN_STATIC_IP_ADDRESS]
 set transform-set TS
 set pfs group16
 set ikev2-profile IKEV2_PROFILE
 match address 100
```

Crypto Mapで使用するトラフィックセレクタとなるACLを設定します。

```
access-list 100 permit ip 192.168.1.0 0.0.0.255 10.0.1.0 0.0.0.255
```

Crypto MapをWANインターフェイスに適用します。

```
interface GigabitEthernet0/0/0
 crypto map CMAP
```

パブリックインターネットへの静的経路を設定します。
`[CISCO_GW_NEXTHOP]`には、ISP側のゲートウェイのIPアドレスを指定します。
ルータの用途如何ですが、今回の設定ではGCPへのVPN経由のトラフィック以外もこのインターフェイスから出力され、上記トラフィックセレクタにヒットするトラフィックだけがIPsecの対象となります。

```
ip route 0.0.0.0 0.0.0.0 [CISCO_GW_NEXTHOP]
```

# 確認

オンプレミス側のネットワーク(`192.168.1.0/24`)からの通信を許容するファイアウォールルールを設定します。

```
gcloud compute firewall-rules create vpnrule1 \
    --network my-network \
    --allow tcp,udp,icmp \
    --source-ranges 192.168.1.0/24
```

Pingの宛先になるCompute Engineのインスタンスを立ち上げます。このインスタンスのプライベートアドレスは10.0.1.2となりました。

```
gcloud compute instances create "ping-test" \
    --zone "asia-northeast1-a" \
    --machine-type "f1-micro" \
    --subnet "subnet-1" 
```

CiscoルータからLAN側のインターフェイスを送信元として上記のインスタンスにPingして、応答があることを確認します。

```
Router#ping 10.0.1.2 so gi0/0/1
Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.1.2, timeout is 2 seconds:
Packet sent with a source address of 192.168.1.254
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 26/27/29 ms
```

暗号化されているかどうかは以下のコマンドで分かります。
Pingに前後してコマンドを実行すると、暗号(encrypt)と復号(decrypt)のカウンタが増えるはずです。

```
Router#sh crypto ipsec sa | inc pkts
    #pkts encaps: 10, #pkts encrypt: 10, #pkts digest: 10
    #pkts decaps: 9, #pkts decrypt: 9, #pkts verify: 9
    #pkts compressed: 0, #pkts decompressed: 0
    #pkts not compressed: 0, #pkts compr. failed: 0
    #pkts not decompressed: 0, #pkts decompress failed: 0
```

# 参考資料

**VPN の作成**
https://cloud.google.com/compute/docs/vpn/creating-vpns?hl=ja