家庭ネットワークからVPNでAWSと動的ルーティング接続する(NATトラバーサル) - VyOS編

# はじめに
皆さんこんにちは。仕事でAWSを使っているのですが、これまで自分でVPNを用いたことが無かったため、検証として自宅のネットワークからAWSへのSite-Site VPN接続を試してみました。

# 前提条件
AWSとの接続はSite-Site VPN構成による接続を行ってみます。
我が家はプロパイダー経由によるNTT光回線を利用しており、宅内にはNTTから送られてきた標準タイプひかり電話ルータなるものが設置されています。ルータからはPPPoE (PPP over Ethernet)による認証を用いて、インターネットプロパイダに接続され、インターネットへの接続が行われています。
グローバルの固定IPアドレスは契約していないため、今回はルータで取得したグローバルIPアドレスを用いて、NATトラバーサルによるVPN接続を行うことにしました。
ルータはテスト用途で、仮想環境で構築できるVyatta (VyOS)を用いました。

# NAT-T (NATトラバーサル)とは？
NATトラバーサルとは、アプリケーションがNATによるIPアドレス変換に対応するために定義された規格です。IPSecにおいてはRFC3947でIPSec NAT-TとしてInternet側からNATの内側にあるVPN機器にポートマッピングさせることで通信が確立できるようになります。

- IKE (UDP/500)
- NAT-T (UDP 4500)

# ハマる。。NTT光のルータに設定ができない！？
NATトラバーサルのために、家庭にあるルータに久々に接続し、ポートマッピング設定を見てみます。
・・・あれ、グレーになっており設定出来ない。
・・・というか、NAT設定が見当たらん！ポートマッピングが無い？
・・・それ以前に、PPPoEの認証設定も触れない！これって何？

調べてみたところ、今はIPv6によるIPoE方式がデフォルト契約になっており、IPv4網によるインターネット接続ではなく、IPv6網による通信が前提になっているようです。昔のNTTフレッツ網時代はPPPoE認証前提だったのに、世の中進化しているんですね。
IPv4網よりもIPv6網の方が通信の混雑が無く、高速なインターネット接続が実現出来るとのことですが、このままでは検証が出来ないため変更することにしました。
プロパイダのコールセンターに電話して、IPv6サービスを止めてもらいました。1週間ぐらいかかるとのことでしたが、1日後にメールが送られてIPv4に切り替えられたとの連絡が。改めてルータの設定を見たところ、懐かしいIPv4設定が出来るようになりました。

# 家庭用ルータ側の設定　ポートマッピングを行いましょう
自宅のルータはNTT光のPR-S300NEです。設定画面の「静的IPマスカレード設定」から行います。
本設定では、192.168.1.12がVPN機器になります。

- UDP:4500 - IKE
- UDP:500 - NATトラバーサル
![2_fletsR_2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/be9e5aaf-20df-da81-36cb-a63ed61a045a.png)

# AWS側設定
手順は以下の通りです。

- Customer Gateway
- VPN Gateway
- VPN設定

## Customer Gateway設定
IPアドレスは自宅で取得しているグローバルIPアドレスを設定します。
固定IPを持てないPPPoE形式の場合は、アドレスが変更毎に修正しましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/72b54d8f-fea2-43a8-138a-af6538de9eb0.png)

## 仮想プライベートGateway設定
AWS側の仮想プライベートGatewayを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/36eb96ec-ef3e-3c31-3531-0bd5013a6cb0.png)

## サイト間のVPN接続を設定
Customer Gatewayと仮想プライベートGatewayを用いて、Site-to-Site VPNを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/adfb38bd-a00d-6d22-f5e5-b24ce76e4b24.png)
設定後、「設定のダウンロード」から対象となるVPN設定ファイルをダウンロードできます。
今回はVyOSのVPN設定をダウンロードして適用します。

# VyOSインストール
[公式サイト](https://wiki.vyos.net/wiki/Main_Page)からovaイメージをダウンロードして環境を構築します。

## VyOS Configuration
AWS側でダウンロードしたVPN設定情報を流し込みます。

- VyOSのNATトラバーサル設定のため、AWSの設定ファイルを流す前に以下を設定します。

```
set vpn ipsec nat-traversal enable
set vpn ipsec ipsec-interfaces interface eth0
set vpn ipsec nat-networks allowed-network 0.0.0.0/0
```
- AWS設定ファイルを流し込んだ後、AWS側対向VPN宛のlocal-addressをNAT前のIPに書き換えます。

```
set vpn ipsec site-to-site peer 18.181.XXX.XXX local-address 192.168.1.12
set vpn ipsec site-to-site peer 54.250.XXX.XXX local-address 192.168.1.12
```

VyOS設定例

```
vyos@awsvpnr:~$ show configuration
interfaces {
    ethernet eth0 {
        address 192.168.1.12/24
        description OutSide
        duplex auto
        hw-id 08:00:27:0c:fe:cd
        smp_affinity auto
        speed auto
    }
    ethernet eth1 {
        address 172.16.1.1/24
        description InSide
        duplex auto
        hw-id 08:00:27:dc:b0:7d
        smp_affinity auto
        speed auto
    }
    loopback lo {
    }
    vti vti0 {
        address 169.254.XX.XX/30
        description "VPC tunnel 1"
        mtu 1436
    }
    vti vti1 {
        address 169.254.XX.XX/30
        description "VPC tunnel 2"
        mtu 1436
    }
}
protocols {
    bgp 65000 {
        neighbor 169.254.XX.XX {
            remote-as 64512
            soft-reconfiguration {
                inbound
            }
            timers {
                holdtime 30
                keepalive 10
            }
        }
        neighbor XXX.XXX.XXX.XXX {
            remote-as 64512
            soft-reconfiguration {
                inbound
            }
            timers {
                holdtime 30
                keepalive 10
            }
        }
        network 0.0.0.0/0 {
        }
    }
}
service {
    ssh {
        port 22
    }
}
system {
    config-management {
        commit-revisions 100
    }
    console {
    }
    gateway-address 192.168.1.1
    host-name awsvpnr
    login {
        user vyos {
            authentication {
                encrypted-password ****************
                plaintext-password ****************
            }
            level admin
        }
    }
    ntp {
        server 0.pool.ntp.org {
        }
        server 1.pool.ntp.org {
        }
        server 2.pool.ntp.org {
        }
    }
    package {
        auto-sync 1
        repository community {
            components main
            distribution helium
            password ****************
            url http://packages.vyos.net/vyos
            username ""
        }
    }
    syslog {
        global {
            facility all {
                level notice
            }
            facility protocols {
                level debug
            }
        }
    }
    time-zone Asia/Tokyo
}
vpn {
    ipsec {
        esp-group AWS {
            compression disable
            lifetime 3600
            mode tunnel
            pfs enable
            proposal 1 {
                encryption aes128
                hash sha1
            }
        }
        ike-group AWS {
            dead-peer-detection {
                action restart
                interval 15
                timeout 30
            }
            ikev2-reauth no
            key-exchange ikev1
            lifetime 28800
            proposal 1 {
                dh-group 2
                encryption aes128
                hash sha1
            }
        }
        ipsec-interfaces {
            interface eth0
        }
        nat-networks {
            allowed-network 0.0.0.0/0 {
            }
        }
        nat-traversal enable
        site-to-site {
            peer 18.181.XXX.XXX {
                authentication {
                    mode pre-shared-secret
                    pre-shared-secret ****************
                }
                connection-type initiate
                description "VPC tunnel 1"
                ike-group AWS
                ikev2-reauth inherit
                local-address 192.168.1.12
                vti {
                    bind vti0
                    esp-group AWS
                }
            }
            peer 54.250.XXX.XXX {
                authentication {
                    mode pre-shared-secret
                    pre-shared-secret ****************
                }
                connection-type initiate
                description "VPC tunnel 2"
                ike-group AWS
                ikev2-reauth inherit
                local-address 192.168.1.12
                vti {
                    bind vti1
                    esp-group AWS
                }
            }
        }
    }
}
```

## VPN情報確認
AWSマネジメントコンソールから、VPN接続のステータスがUpすることを確認出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/653790/f85f016f-e0c3-d0e9-387b-30973d4af37a.png)

VyOS側VPNステータス

```
vyos@awsvpnr:~$ show vpn ipsec sa
Peer ID / IP                            Local ID / IP
------------                            -------------
18.181.XXX.XXX                           192.168.1.12

    Description: VPC tunnel 1

    Tunnel  State  Bytes Out/In   Encrypt  Hash    NAT-T  A-Time  L-Time  Proto
    ------  -----  -------------  -------  ----    -----  ------  ------  -----
    vti     up     25.1K/23.9K    aes128   sha1    yes    2670    3600    all


Peer ID / IP                            Local ID / IP
------------                            -------------
54.250.XXX.XXX                            192.168.1.12

    Description: VPC tunnel 2

    Tunnel  State  Bytes Out/In   Encrypt  Hash    NAT-T  A-Time  L-Time  Proto
    ------  -----  -------------  -------  ----    -----  ------  ------  -----
    vti     up     24.9K/25.0K    aes128   sha1    yes    2996    3600    all


vyos@awsvpnr:~$
```


## ルーティング確認

```
vyos@awsvpnr:~$ show ip bgp neighbors
BGP neighbor is 169.254.XXX.XXX, remote AS 64512, local AS 65000, external link
  BGP version 4, remote router ID 169.254.XXX.XXX
  BGP state = Established, up for 00:35:09
  Last read 14:52:14, hold time is 30, keepalive interval is 10 seconds
  Configured hold time is 30, keepalive interval is 10 seconds
  Neighbor capabilities:
    4 Byte AS: advertised and received
    Route refresh: advertised and received(old & new)
    Address family IPv4 Unicast: advertised and received
  Message statistics:
    Inq depth is 0
    Outq depth is 0
                         Sent       Rcvd
    Opens:                  1          0
    Notifications:          0          0
    Updates:                2          2
    Keepalives:           212        212
    Route Refresh:          0          0
    Capability:             0          0
    Total:                215        214
  Minimum time between advertisement runs is 30 seconds

 For address family: IPv4 Unicast
  Inbound soft reconfiguration allowed
  Community attribute sent to this neighbor(both)
  1 accepted prefixes

  Connections established 1; dropped 0
  Last reset never
Local host: 169.254.XXX.XXX, Local port: 179
Foreign host: 169.254.XXX.XXX, Foreign port: 38641
Nexthop: 169.254.XXX.XXX
Nexthop global: ::
Nexthop local: ::
BGP connection: non shared network
Read thread: on  Write thread: off

BGP neighbor is 169.254.XXX.XXX, remote AS 64512, local AS 65000, external link
  BGP version 4, remote router ID 169.254.XXX.XXX
  BGP state = Established, up for 00:34:58
  Last read 14:52:12, hold time is 30, keepalive interval is 10 seconds
  Configured hold time is 30, keepalive interval is 10 seconds
  Neighbor capabilities:
    4 Byte AS: advertised and received
    Route refresh: advertised and received(old & new)
    Address family IPv4 Unicast: advertised and received
  Message statistics:
    Inq depth is 0
    Outq depth is 0
                         Sent       Rcvd
    Opens:                  1          1
    Notifications:          0          0
    Updates:                4          2
    Keepalives:           211        211
    Route Refresh:          0          0
    Capability:             0          0
    Total:                216        214
  Minimum time between advertisement runs is 30 seconds

 For address family: IPv4 Unicast
  Inbound soft reconfiguration allowed
  Community attribute sent to this neighbor(both)
  1 accepted prefixes

  Connections established 1; dropped 0
  Last reset never
Local host: 169.254.XXX.XXX, Local port: 44927
Foreign host: 169.254.XXX.XXX, Foreign port: 179
Nexthop: 169.254.XXX.XXX
Nexthop global: ::
Nexthop local: ::
BGP connection: non shared network
Read thread: on  Write thread: off

vyos@awsvpnr:~$
```
# まとめ
AWS側はNAT-Tを意識することなく、通常のSite-to-Site VPNを設定するだけでした。
[公式サイト](https://aws.amazon.com/jp/premiumsupport/knowledge-center/vpn-tunnel-phase-1-ike/)にも掲載されている通り、条件はユーザー側でNAT-TをポートマッピングすることでUDP 500(IKE)、4500(NAT-T)の疎通が行えるようにしてあげれば、問題がなく通信が行えるようになりました。
どなたかのお役に立てれば光栄です。