IPsecVPN&GRE TAPで、サイトを跨いでL2セグメントを延伸する

サイト間でネットワークを構築します。
IPsecを張り、その中をGREを通します。
L2延伸を目的としたものです。

#IPsecの設定

##IPsecパッケージを導入するサーバーへの設定
こちらのファイル /etc/sysctl.conf 　へ以下を記載。
Device名が違う場合は修正が必要です。

```
net.ipv4.ip_no_pmtu_disc = 1 

net.ipv4.ip_forward = 1

net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.default.arp_ignore = 1
net.ipv4.conf.eth0.arp_ignore = 1
net.ipv4.conf.eth1.arp_ignore = 1

net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0
net.ipv4.conf.eth0.send_redirects = 0
net.ipv4.conf.eth1.send_redirects = 0
net.ipv4.conf.lo.send_redirects = 0

net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv4.conf.eth0.accept_redirects = 0
net.ipv4.conf.eth1.accept_redirects = 0
net.ipv4.conf.lo.accept_redirects = 0

net.ipv4.conf.all.rp_filter=0
net.ipv4.conf.default.rp_filter=0
net.ipv4.conf.eth0.rp_filter=0
net.ipv4.conf.eth1.rp_filter=0
net.ipv4.conf.lo.rp_filter=0

net.bridge.bridge-nf-call-iptables = 0
```

有効化は以下のコマンド実行

```
sysctl -p
```

IPsecパッケージの導入

```
dnf install libreswan
rm -rf /etc/ipsec.d/*db
ipsec initnss
systemctl start ipsec
```
接続先の設定


##secretsの設定

サーバーVPN01
vi /etc/ipsec.d/net1.secrets

```
163.73.69.222 141.125.102.213 : PSK "net1"
```

サーバーVPN02
vi /etc/ipsec.d/net1.secrets

```
163.73.69.222 141.125.102.213 : PSK "net1"
```

##confの設定


サーバーVPN01
vi /etc/ipsec.d/net1.conf

```
conn net1
     left=141.125.102.213
     leftsubnet=10.196.30.192/26
     right=163.73.69.222
     rightsubnet=10.10.18.128/26
     auto=start
     authby=secret
     dpddelay=10
     dpdtimeout=5
     dpdaction=restart
```


サーバーVPN02
vi/etc/ipsec.d/net1.conf

```
conn net1
     left=163.73.69.222
     leftsubnet=10.10.18.128/26
     right=141.125.102.213
     rightsubnet=10.196.30.192/26
     auto=start
     authby=secret
     dpddelay=10
     dpdtimeout=5
     dpdaction=restart
```

IPsecに関するファイルの作成は実質２つのみ。


##設定確認
以下のコマンドを実行

```
ipsec verify
```

以下のようにOKやOBSOLETEであれば通信が始まる。

```
Verifying installed system and configuration files

Version check and ipsec on-path                   	[OK]
Libreswan 4.3 (netkey) on 4.18.0-305.12.1.el8_4.x86_64
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                        	[OBSOLETE]
  003 WARNING: using a weak secret (PSK)
Checking 'ip' command                             	[OK]
Checking 'iptables' command                       	[OK]
Checking 'prelink' command does not interfere with FIPS	[OK]
Checking for obsolete ipsec.conf options          	[OK]
```

##IPsecトンネル確立の確認

```
ip xfrm state
```

以下のように相互に記載があればよい

```
src 141.125.102.213 dst 163.73.69.222
	proto esp spi 0x2314e9f7 reqid 16389 mode tunnel
	replay-window 32 flag nopmtudisc af-unspec
	aead rfc4106(gcm(aes)) 0xa158bb017987a8cbbb435e35c6a5013e6106dd7cf958e5b45b168c04abea11b232124ce5 128
	anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
src 163.73.69.222 dst 141.125.102.213
	proto esp spi 0xb891fdd9 reqid 16389 mode tunnel
	replay-window 32 flag nopmtudisc af-unspec
	aead rfc4106(gcm(aes)) 0x05253b03ae18dc3711ba0ac32f2b3afc54576b0e7b244fabd4be04d1a04691bdb103561f 128
	anti-replay context: seq 0x0, oseq 0x0, bitmap 0x00000000
```


##パケット通過確認
このままでは対向側のサーバーは応答しません。
IPsecトンネルを通すためには、然るべき入り口からパケットが入らなければいけません。
そのためのスタティックルートを設定します。
概要は、
route add -net (対向側のプライベートセグメント) gw (入り口となる自プライベート側NIC）


```
[root@vpn01 ~]# route add -net 10.196.30.192/26 gw 10.10.18.190
[root@vpn01 ~]# ping  10.196.30.220
PING 10.196.30.220 (10.196.30.220) 56(84) bytes of data.
64 bytes from 10.196.30.220: icmp_seq=1 ttl=64 time=249 ms
64 bytes from 10.196.30.220: icmp_seq=2 ttl=64 time=248 ms
```


```
[root@vpn02 ~]# route add -net 10.10.18.128/26 gw 10.196.30.220
[root@vpn02 ~]# ping 10.10.18.190
PING 10.10.18.190 (10.10.18.190) 56(84) bytes of data.
64 bytes from 10.10.18.190: icmp_seq=1 ttl=64 time=249 ms
64 bytes from 10.10.18.190: icmp_seq=2 ttl=64 time=248 ms
```





#GREの設定

iprouteパッケージを入れる必要がある

```
dnf install -y iproute
```

設定の方針として、
それぞれサーバー内にブリッジを作成し、gretapとプライベート側のNICを属する設定を行う。
ブリッジ(br0)には、疎通確認用にIPを付与しておく。

brctlコマンドは、別途「bridge-utils」パッケージを導入する必要がある。
そのためにはepelレポジトリにアクセスできる必要がある。
epelレポジトリ使った場合の保証はないため、使いたく無いという判断もあろうかと思います。

epelレポジトリが利用可能な場合に投入するコマンド(vpn02で入れてみました)

```
dnf install -y epel-release   
dnf install -y bridge-utils
```

####サーバーvpn01
#####epelレポジトリ利用しない場合の設定

```
modprobe ip_gre
nmcli connection add type bridge autoconnect yes con-name br0 ifname br0
nmcli connection modify br0 ipv4.method manual ipv4.addresses 10.10.10.1/24
nmcli connection add type ip-tunnel ip-tunnel.mode gretap slave-type bridge con-name gretap1 ifname gretap1 local 10.10.18.190 remote 10.196.30.220 master br0
nmcli connection modify br0 mtu 1500
nmcli connection up br0
nmcli connection up gretap1
```

#####epelレポジトリ利用できる場合の設定

```
brctl addbr br0
ip link set br0 mtu 1500
ip link set br0 up
ip addr add 10.10.10.1/24 dev br0
ip link add gretap1 type gretap local 10.10.18.190 remote 10.196.30.220 dev eth0 nopmtudisc
ip link set gretap1 mtu 1462
ip link set gretap1 up
ip link set gretap1 master br0
```


####サーバーvpn02

```
modprobe ip_gre
brctl addbr br0
ip link set br0 mtu 1500
ip link add br0 type bridge
ip link set br0 up
ip addr add 10.10.10.2/24 dev br0
ip link add gretap1 type gretap local 10.196.30.220 remote 10.10.18.190 dev eth0 nopmtudisc
ip link set gretap1 mtu 1462
ip link set gretap1 up
ip link set gretap1 master br0
```

インターフェイス状況の確認(nmcliコマンドを使った場合)

```
[root@vpn01 ~]# nmcli d
DEVICE   TYPE      STATE     CONNECTION  
eth1     ethernet  接続済み  System eth1 
br0      bridge    接続済み  br0         
eth0     ethernet  接続済み  System eth0 
gretap1  iptunnel  接続済み  gretap1     
erspan0  erspan    管理無し  --          
gre0     iptunnel  管理無し  --          
gretap0  iptunnel  管理無し  --          
lo       loopback  管理無し  --          
ip_vti0  vti       管理無し  --  
```

ip a コマンド実行の場合
「br0」の行でstate UPとなっていること、「gretap1」の行でbr0が含まれていることがポイント

```
8: gretap1@eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1462 qdisc fq_codel master br0 state UNKNOWN group default qlen 1000
    link/ether a2:a2:7f:6d:09:fb brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a0a2:7fff:fe6d:9fb/64 scope link 
       valid_lft forever preferred_lft forever
9: br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether a2:a2:7f:6d:09:fb brd ff:ff:ff:ff:ff:ff
    inet 10.10.10.2/24 scope global br0
       valid_lft forever preferred_lft forever
    inet6 fe80::a0a2:7fff:fe6d:9fb/64 scope link 
       valid_lft forever preferred_lft forever
```

###さらに確認
ブリッジ(br0)に付与したIPに向かって対向サーバーよりPingを打つ
vpn01からvpn02へ
この時、

```
ip link set gretap1 down
(復旧は ip link set gretap1 up)
```

や

```
systemctl stop ipsec
(復旧は systemctl start ipsec)
```

を実行した時に、応答が停止(復帰)することを確認する。



道を外れた場合

GRE tapを下げる（またあげる）
```
ip link set gretap1 down
ip link set gretap1 up
```

GRE tapを削除する(デバイス名をgretap1で登録した場合)
```
ip link del gretap1 
```

##ここでプライベートNICのブリッジ追加
どちらのサーバーでも以下を実行

VPN01(nmcliコマンドの場合)

```
ip addr del 10.10.18.190/26 dev eth0
nmcli c modify br0 ipv4.method manual +ipv4.addresses 10.196.30.211/26 
nmcli c modify br0 ipv4.method manual +ipv4.addresses 10.10.18.190/26
nmcli connection up br0
nmcli connection modify gretap1 ip-tunnel.mtu 1462
nmcli connection up gretap1
```
※注意：nmcliコマンドで設定した場合、「ip a」では上記で設定したセカンダリアドレスが出てきません。「nmcli connection show br0」コマンドにて確認が可能です。

VPN02(ip linkコマンドの場合)

```
ip addr del 10.196.30.220/26 dev eth0
ip link set eth0 master br0
ip addr add 10.196.30.220/26 dev br0

```



#確認方法
パケットの飛来を見る。

```
tcpdump -i eth1 proto gre
```
VPN1からVPN2のセグメントにある別なサーバーへ疎通確認
これができる場合、VPN1のサイトとVPN2のサイトは同一セグメント化がされた状態となる

```
ping 10.196.30.221
```

##注意
この時、仮想サーバーで実行している場合、NTPやNameサーバの設定(/etc/resolv.conf)の内容に注意が必要です。
今回はプライベートNIC側のStatic Routeの設定をしていないためです。
Nameサーバーがクラウド事業者側で用意されたものでプライベートアドレス上にある場合は通信できませんので、resolv.conf適時書き換える必要があります。


#Firewalld設定
IPsecの通過ルールを設定する

```
systemctl start firewalld
firewall-cmd --get-active-zone
firewall-cmd --add-port={4500,500}/udp --permanent
firewall-cmd --add-protocol={50,51} --permanent
firewall-cmd --add-service=ipsec --permanent
firewall-cmd --reload
```

#IBM CloudのDNSサーバーやレポジトリ先のスタティックルート設定はこちら
###vpn01への設定

```
route add -net 10.0.80.0/24 gw 10.10.18.129
route add -net 10.0.77.0/24 gw 10.196.30.193
```
###vpn02への設定

```
route add -net 10.0.80.0/24 gw 10.196.30.193
route add -net 10.0.77.0/24 gw 10.196.30.193
```