network namespace間でstrongswanによるVPN構築

## 概要
network namespace間でstrongswanによるVPNトンネルを構築する。

## 環境
* OS : osx multipass上で動作するUbuntu
* strongswan-5.9.5

## 手順
(1) strongswanをインストールする。
<pre>sudo apt install make
sudo apt install gcc
sudo apt install libgmp-dev
wget http://download.strongswan.org/strongswan-5.9.5.tar.bz2
cd strongswan-5.9.5/
./configure --prefix=/usr --sysconfdir=/etc --with-piddir=/etc/ipsec.d/run
make
sudo make install</pre>

(2) network namespaceを作成する。ここではlan-router-wanの3つのnamespaceを作成する。
<pre>sudo ip netns add lan
sudo ip netns add router
sudo ip netns add wan
sudo ip link add lan-veth0 type veth peer name gw-veth0
sudo ip link add wan-veth0 type veth peer name gw-veth1
sudo ip link set lan-veth0 netns lan
sudo ip link set wan-veth0 netns wan
sudo ip link set gw-veth0 netns router
sudo ip link set gw-veth1 netns router
sudo ip netns exec lan ip link set lan-veth0 up
sudo ip netns exec wan ip link set wan-veth0 up
sudo ip netns exec router ip link set gw-veth0 up
sudo ip netns exec router ip link set gw-veth1 up
sudo ip netns exec router ip a add 192.0.2.254/24 dev gw-veth0
sudo ip netns exec router ip a add 203.0.113.254/24 dev gw-veth1
sudo ip netns exec router sysctl net.ipv4.ip_forward=1
sudo ip netns exec lan ip a add 192.0.2.1/24 dev lan-veth0
sudo ip netns exec lan ip route add default via 192.0.2.254
sudo ip netns exec wan ip a add 203.0.113.1/24 dev wan-veth0
sudo ip netns exec wan ip route add  default via 203.0.113.254
</pre>

(3) namespaceごとにstrongswanを起動するための設定を行う。
- ディレクトリを作成。
<pre>$ sudo mkdir -p /etc/ipsec.d/run
$ sudo mkdir -p /etc/netns/lan/ipsec.d/run
$ sudo mkdir -p /etc/netns/wan/ipsec.d/run
</pre>
- wan側のipsec.confを作成。
<pre>$ cat /etc/netns/wan/ipsec.conf 
conn linux-to-linux
	authby=secret
	auto=start
	closeaction=restart
	dpdaction=restart
	left=203.0.113.1
	leftsubnet=10.0.2.0/24
	leftikeport=4500
	right=192.0.2.1
	rightsubnet=10.0.1.0/24
	rightikeport=4500
</pre>
- lan側のipsec.confを作成。
<pre>$ cat /etc/netns/lan/ipsec.conf 
conn linux-to-linux
	authby=secret
	auto=add
	closeaction=clear
	dpdaction=clear
	left=192.0.2.1
	leftsubnet=10.0.1.0/24
	leftikeport=4500
	right=203.0.113.1
	rightsubnet=10.0.2.0/24
	rightikeport=4500
</pre>

(4) 接続
<pre>$ sudo ip netns exec wan ipsec start
$ sudo ip netns exec lan ipsec start

$ sudo ip netns exec lan ipsec status
Security Associations (1 up, 0 connecting):
linux-to-linux[1]: ESTABLISHED 15 seconds ago, 192.0.2.1[192.0.2.1]...203.0.113.1[203.0.113.1]
linux-to-linux{1}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: cb828634_i c303abee_o
linux-to-linux{1}:   10.0.1.0/24 === 10.0.2.0/24
linux-to-linux{2}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: cd477f96_i c3b637b7_o
linux-to-linux{2}:   10.0.1.0/24 === 10.0.2.0/24

$ sudo ip netns exec wan ipsec status
Security Associations (1 up, 0 connecting):
linux-to-linux[2]: ESTABLISHED 19 seconds ago, 203.0.113.1[203.0.113.1]...192.0.2.1[192.0.2.1]
linux-to-linux{2}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c303abee_i cb828634_o
linux-to-linux{2}:   10.0.2.0/24 === 10.0.1.0/24
linux-to-linux{3}:  INSTALLED, TUNNEL, reqid 1, ESP SPIs: c3b637b7_i cd477f96_o
linux-to-linux{3}:   10.0.2.0/24 === 10.0.1.0/24
</pre>

## 補足
ipsec.confにて、portをしないとデフォルトで500ポートでipsecの接続が行われる。
port指定して試した際、nat-tが動作し、4500ポートに使用ポートが変わるとstrongswan間でport unreachableとなり、通信に失敗していた。
なぜかは原因不明。（おそらく設定が抜けている？？）
暫定処置としてipsec.confで明示的に4500ポート指定すると接続が成功した。

<pre>$ sudo ip netns exec lan ipsec up linux-to-linux
initiating IKE_SA linux-to-linux[1] to 203.0.113.1
generating IKE_SA_INIT request 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(REDIR_SUP) ]
sending packet: from 192.0.2.1[500] to 203.0.113.1[500] (936 bytes)
received packet: from 203.0.113.1[500] to 192.0.2.1[500] (280 bytes)
parsed IKE_SA_INIT response 0 [ SA KE No N(NATD_S_IP) N(NATD_D_IP) N(FRAG_SUP) N(HASH_ALG) N(CHDLESS_SUP) N(MULT_AUTH) ]
selected proposal: IKE:AES_CBC_128/HMAC_SHA2_256_128/PRF_AES128_XCBC/ECP_256
authentication of '192.0.2.1' (myself) with pre-shared key
establishing CHILD_SA linux-to-linux{1}
generating IKE_AUTH request 1 [ IDi N(INIT_CONTACT) IDr AUTH SA TSi TSr N(MOBIKE_SUP) N(NO_ADD_ADDR) N(MULT_AUTH) N(EAP_ONLY) N(MSG_ID_SYN_SUP) ]
sending packet: from 192.0.2.1[4500] to 203.0.113.1[4500] (368 bytes)
retransmit 1 of request with message ID 1
sending packet: from 192.0.2.1[4500] to 203.0.113.1[4500] (368 bytes)

$ sudo ip netns exec lan tcpdump -tnl -i lan-veth0
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on lan-veth0, link-type EN10MB (Ethernet), capture size 262144 bytes
IP 192.0.2.1.500 > 203.0.113.1.500: isakmp: parent_sa ikev2_init[I]
IP 203.0.113.1.500 > 192.0.2.1.500: isakmp: parent_sa ikev2_init[R]
IP 192.0.2.1.4500 > 203.0.113.1.4500: NONESP-encap: isakmp: child_sa  ikev2_auth[I]
IP 192.0.2.1.4500 > 203.0.113.1.4500: NONESP-encap: isakmp: child_sa  ikev2_auth[I]
IP 203.0.113.1 > 192.0.2.1: ICMP 203.0.113.1 udp port 4500 unreachable, length 408
</pre>

## 参考
https://wiki.strongswan.org/projects/strongswan/wiki/Netns