VyOS で p2p VPN over pppoe (両端固定 IP, IKEv2 ipsec, vti トンネル)

# 構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306041/103256ca-9d13-d608-9083-2eb8a1dd6f2c.png)

|インターフェース|目的|
|:-----:|:------:|
| eth0  | ssh 接続 (vrf MGT) |
| eth1  | ルーターの先の LAN |
| eth2  | インターネット (pppoe) |
| pppoe | pppoe トンネル |
| vit10 | vpn トンネル |
| dum0  | 通信試験用 (ルーターの先の LAN)|

# 基本設定
```configuration:
set system host-name VyOS-19
set system domain-name home.my
set system login user vyos authentication encrypted-password vyos
delete system login user vyos authentication plaintext-password
set system time-zone Asia/Tokyo

set service lldp interface all
set service lldp legacy-protocols cdp
set service ntp server 172.30.10.254

set interfaces ethernet eth1 address 172.16.0.19/24
set interfaces ethernet eth2
```

# vrf、マネージメント設定
```configuration:
set vrf name MGT ip disable-forwarding
set vrf name MGT table 100

set interfaces ethernet eth0 address 172.30.10.19/24
set interfaces ethernet eth0 description MGT
set interfaces ethernet eth0 vrf MGT

set service ntp vrf MGT
set service ssh listen-address '172.30.10.19'
set service ssh vrf MGT
```
管理用 LAN を vrf MGT にして、サービス用ネットワークからログインできないよう分離。
ntp も管理用 LAN を利用。

# pppoe 設定
```configuration:
set interfaces pppoe pppoe0 authentication password pass_Center
set interfaces pppoe pppoe0 authentication username Center@Cisco
set interfaces pppoe pppoe0 description to_PPPoE
set interfaces pppoe pppoe0 mtu 1454
set interfaces pppoe pppoe0 source-interface eth2
```
pppoe の設定

https://docs.vyos.io/ja/latest/configuration/interfaces/pppoe.html

# VPN 設定
## vpn 共通部分
```configuration: IKE ＆ ESP
set vpn ipsec esp-group ESP_DEFAULT lifetime '3600'
set vpn ipsec esp-group ESP_DEFAULT mode 'tunnel'
set vpn ipsec esp-group ESP_DEFAULT pfs 'dh-dh-group32'
set vpn ipsec esp-group ESP_DEFAULT proposal 1 encryption 'aes256gcm128'
set vpn ipsec esp-group ESP_DEFAULT proposal 1 hash 'sha512'
set vpn ipsec ike-group IKE_DEFAULT dead-peer-detection action 'restart'
set vpn ipsec ike-group IKE_DEFAULT dead-peer-detection interval '15'
set vpn ipsec ike-group IKE_DEFAULT dead-peer-detection timeout '30'
set vpn ipsec ike-group IKE_DEFAULT ikev2-reauth
set vpn ipsec ike-group IKE_DEFAULT key-exchange 'ikev2'
set vpn ipsec ike-group IKE_DEFAULT lifetime '28800'
set vpn ipsec ike-group IKE_DEFAULT proposal 1 dh-group '31'
set vpn ipsec ike-group IKE_DEFAULT proposal 1 encryption 'chacha20poly1305'
set vpn ipsec ike-group IKE_DEFAULT proposal 1 hash 'sha512'
set vpn ipsec interface 'pppoe0'
```
IKEv2 sa (IKEv1 の Phase1 / IKE sa) の lifetime は 24時間程度
IPsec sa (IKEv1 の Phase2 / Child sa) の lifetime は 数時間程度にすることが多い


```configuration:
# この id は対向だけあれば良いけど
# 両方入れても問題ないので両方とも書いて共通設定とする
set vpn ipsec authentication psk Site2Site id '100.64.0.29'
set vpn ipsec authentication psk Site2Site id '100.64.0.19'
set vpn ipsec authentication psk Site2Site secret 'secret_ABC-def'

set vpn ipsec site-to-site peer Site2Site authentication mode 'pre-shared-secret'
set vpn ipsec site-to-site peer Site2Site ike-group 'IKE_DEFAULT'
set vpn ipsec site-to-site peer Site2Site vti bind 'vti10'
set vpn ipsec site-to-site peer Site2Site vti esp-group 'ESP_DEFAULT'
```

## vpn センター側
```configuration:
set interfaces vti vti10
set interfaces vti vti10 address '172.16.99.19/24'
set interfaces vti vti10 description 'to_SiteA'
set interfaces vti vti10 ip adjust-mss '1350'

set vpn ipsec site-to-site peer Site2Site authentication local-id '100.64.0.19'
set vpn ipsec site-to-site peer Site2Site authentication remote-id '100.64.0.29'
set vpn ipsec site-to-site peer Site2Site local-address '100.64.0.19'
set vpn ipsec site-to-site peer Site2Site remote-address '100.64.0.29'

set interfaces dummy dum0 address 172.17.19.0/32
set protocols static route 172.17.0.0/16 interface vti10
```
dum0 は通信試験用。dum0 向けのルートを vpn トンネルに向ける。


## 拠点A (差分のみ)
```configuration:
set system host-name VyOS-29

set interfaces ethernet eth0 address 172.30.10.29/24
set interfaces ethernet eth1 address 172.16.0.29/24
set service ssh listen-address '172.30.10.29'

# pppoe
set interfaces pppoe pppoe0 authentication password pass_A
set interfaces pppoe pppoe0 authentication username site-A@Cisco

# vpn
set interfaces vti vti10 address '172.16.99.29/24'
set vpn ipsec site-to-site peer Site2Site authentication local-id '100.64.0.29'
set vpn ipsec site-to-site peer Site2Site authentication remote-id '100.64.0.19'
set vpn ipsec site-to-site peer Site2Site local-address '100.64.0.29'
set vpn ipsec site-to-site peer Site2Site remote-address '100.64.0.19'

set interfaces dummy dum0 address 172.17.29.0/32
```

172.17.0.0/16 向けのルーティングが適当なので、一対一の VPN にしか使えません。
一対多の場合はセンターから各拠点向けを一つづつ書いていく必要があります。
 
最低限の設定としては以下が参考になると思います。

https://webprog.spg-games.net/2023-07-09/vyos-1.4%E3%81%A7ipv6-ipsec-vpn%E3%82%92%E6%A7%8B%E7%AF%89%E3%81%99%E3%82%8B/


# 状態確認

```console:センター側
vyos@VyOS-19:~$ show vpn ike sa
Peer ID / IP                            Local ID / IP
------------                            -------------
100.64.0.29 100.64.0.29                 100.64.0.19 100.64.0.19

    State  IKEVer  Encrypt      Hash          D-H Group      NAT-T  A-Time  L-Time
    -----  ------  -------      ----          ---------      -----  ------  ------
    up     IKEv2   CHACHA20_POLY1305 n/a           CURVE_25519    no     817     0

vyos@VyOS-19:~$
vyos@VyOS-19:~$ show vpn ike secrets
PSK        Id           Secret
---------  -----------  --------------
Site2Site  100.64.0.19  secret_ABC-def
           100.64.0.29
vyos@VyOS-19:~$
vyos@VyOS-19:~$ show vpn ipsec connections
Connection     State    Type    Remote address    Local TS    Remote TS    Local id     Remote id    Proposal
-------------  -------  ------  ----------------  ----------  -----------  -----------  -----------  ---------------------------------------
Site2Site      up       IKEv2   100.64.0.29       -           -            100.64.0.19  100.64.0.29  CHACHA20_POLY1305/None/None/CURVE_25519
Site2Site-vti  up       IPsec   100.64.0.29       0.0.0.0/0   0.0.0.0/0    100.64.0.19  100.64.0.29  AES_GCM/256/None/None
                                                  ::/0        ::/0
vyos@VyOS-19:~$
vyos@VyOS-19:~$ show vpn ipsec sa
Connection     State    Uptime    Bytes In/Out    Packets In/Out    Remote address    Remote ID    Proposal
-------------  -------  --------  --------------  ----------------  ----------------  -----------  --------------
Site2Site-vti  up       40m46s    0B/0B           0/0               100.64.0.29       100.64.0.29  AES_GCM_16_256
Site2Site-vti  up       40m52s    0B/0B           0/0               100.64.0.29       100.64.0.29  AES_GCM_16_256
vyos@VyOS-19:~$
vyos@VyOS-19:~$ show interfaces
Codes: S - State, L - Link, u - Up, D - Down, A - Admin Down
Interface    IP Address       MAC                VRF        MTU  S/L    Description
-----------  ---------------  -----------------  -------  -----  -----  -------------
dum0         172.17.0.19/32   4e:ea:ac:b2:50:38  default   1500  u/u
eth0         172.30.10.19/24  00:0c:29:3f:f6:f2  MGT       1500  u/u    MGT
eth1         172.16.0.19/24   00:0c:29:3f:f6:fc  default   1500  u/u    to_vEOS-21
eth2         -                00:0c:29:3f:f6:06  default   1500  u/u
lo           127.0.0.1/8      00:00:00:00:00:00  default  65536  u/u
             ::1/128
pppoe0       100.64.0.19/32   n/a                default   1454  u/u    to_PPPoE
vti10        172.16.99.19/24  n/a                default   1500  u/u    to_Center
vyos@VyOS-19:~$
vyos@VyOS-19:~$ ping 172.17.0.29 source-address  172.17.0.19
PING 172.17.0.29 (172.17.0.29) from 172.17.0.19 : 56(84) bytes of data.
64 bytes from 172.17.0.29: icmp_seq=1 ttl=64 time=0.952 ms
64 bytes from 172.17.0.29: icmp_seq=2 ttl=64 time=1.16 ms
64 bytes from 172.17.0.29: icmp_seq=3 ttl=64 time=1.03 ms
64 bytes from 172.17.0.29: icmp_seq=4 ttl=64 time=1.08 ms
^C
--- 172.17.0.29 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 0.952/1.053/1.157/0.074 ms
vyos@VyOS-19:~$
```


## パケットキャプチャ
トンネルの中 (vti10) と外 (pppoe0) を同時にキャプチャ
```console:
vyos@VyOS-19:~$  ( tcpdump -i vti10 > /dev/tty &) | ( tcpdump -i pppoe0 )
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on vti10, link-type RAW (Raw IP), snapshot length 262144 bytes
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on pppoe0, link-type LINUX_SLL (Linux cooked v1), snapshot length 262144 bytes
23:08:15.719811 IP 100.64.0.29.ipsec-nat-t > 100.64.0.19.ipsec-nat-t: NONESP-encap: isakmp: child_sa  inf2
23:08:15.965494 IP 100.64.0.29.ipsec-nat-t > 100.64.0.19.ipsec-nat-t: NONESP-encap: isakmp: child_sa  inf2[I]
23:08:15.972373 IP 100.64.0.19.ipsec-nat-t > 100.64.0.29.ipsec-nat-t: NONESP-encap: isakmp: child_sa  inf2[IR]
23:08:16.205793 IP 100.64.0.19.ipsec-nat-t > 100.64.0.29.ipsec-nat-t: NONESP-encap: isakmp: child_sa  inf2[R]
23:08:16.288026 IP 100.64.0.29.isakmp > 100.64.0.19.isakmp: isakmp: parent_sa ikev2_init[I]
23:08:16.288776 IP 100.64.0.19.isakmp > 100.64.0.29.isakmp: isakmp: parent_sa ikev2_init[R]
23:08:16.290203 IP 100.64.0.29.ipsec-nat-t > 100.64.0.19.ipsec-nat-t: NONESP-encap: isakmp: child_sa  ikev2_auth[I]
23:08:16.624455 IP 100.64.0.19.ipsec-nat-t > 100.64.0.29.ipsec-nat-t: NONESP-encap: isakmp: child_sa  ikev2_auth[R]
23:08:21.045392 IP 172.17.0.29 > 172.17.0.19: ICMP echo request, id 16806, seq 1, length 64
23:08:21.045423 IP 172.17.0.19 > 172.17.0.29: ICMP echo reply, id 16806, seq 1, length 64
23:08:21.045305 IP 100.64.0.29 > 100.64.0.19: ESP(spi=0xc9d4df77,seq=0x1), length 120
23:08:21.045440 IP 100.64.0.19 > 100.64.0.29: ESP(spi=0xc02a0c0d,seq=0x1), length 120
23:08:22.046958 IP 172.17.0.29 > 172.17.0.19: ICMP echo request, id 16806, seq 2, length 64
23:08:22.046992 IP 172.17.0.19 > 172.17.0.29: ICMP echo reply, id 16806, seq 2, length 64
23:08:22.046866 IP 100.64.0.29 > 100.64.0.19: ESP(spi=0xc9d4df77,seq=0x2), length 120
23:08:22.047010 IP 100.64.0.19 > 100.64.0.29: ESP(spi=0xc02a0c0d,seq=0x2), length 120
23:08:23.048330 IP 172.17.0.29 > 172.17.0.19: ICMP echo request, id 16806, seq 3, length 64
23:08:23.048351 IP 172.17.0.19 > 172.17.0.29: ICMP echo reply, id 16806, seq 3, length 64
23:08:23.048275 IP 100.64.0.29 > 100.64.0.19: ESP(spi=0xc9d4df77,seq=0x3), length 120
23:08:23.048363 IP 100.64.0.19 > 100.64.0.29: ESP(spi=0xc02a0c0d,seq=0x3), length 120
^C

6 packets captured
6 packets received by filter
0 packets dropped by kernel
14 packets captured
14 packets received by filter
0 packets dropped by kernel
vyos@VyOS-19:~$
```

意図してなかったのですがセンターの `eth1 : 172.16.0.19/24` と、拠点 A の `eth1 : 172.16.0.29/24` が繋がってますねぇ。L2 を伸ばすことができるんですねぇ。一対一だから通るのかな。一対多だと、ホスト単位でルーティングを書かないと通らないでしょうね。
`dum0` の `172.17.0.19/32` と `172.17.0.29/32` がルータの下の LAN というイメージだったのですが。