strongSwanでVPN (IKEv2)を構築する

# 1.はじめに
[前回](http://qiita.com/namoshika/items/30c348b56474d422ef64)はL2TP/IPSecなVPNを作成しました。
今回はIKEv2(IPSec EAP MSCHAPv2)なVPNを構築します。

以下のクライアントから接続できることを確認しています。

* Windows 10: IKEv2接続
* Android 6.0.1: [strongSwan VPN Client](https://play.google.com/store/apps/details?id=org.strongswan.android&hl=ja)

VPNサーバーのOSは以下の通りです。

* UbuntuServer 15.04
* SELinux は無効化

# 2.手順
## 2.1.必要なアプリの導入
```bash
$ sudo apt-get install strongswan-plugin-eap-mschapv2
```

## 2.2.各種設定
### 認証用ファイル作成
サーバー側用に秘密鍵や証明書を作成します。strongSwanには証明書の作成向けにipsec pkiがあります。作成したファイルは以下の場所に適切に配置します。

* /etc/ipsec.d/cacerts/: 認証局証明書
* /etc/ipsec.d/certs/: サーバー証明書
* /etc/ipsec.d/private/: 認証局・サーバーの秘密鍵

Windows用のひねりを入れる必要があります。
以下の操作をroot権限で行い、Windows対応の証明書を作成します。証明書はサーバーの適切な場所へ配置します。

```bash:setupCert.sh
#!/bin/bash

#各種 key,crt,サーバードメインを埋めて実行します。
#ファイル名
readonly CA_KEY=#認証局秘密鍵.key
readonly CA_CRT=#認証局証明書.crt
readonly VPN_KEY=#サーバー秘密鍵.key
readonly VPN_CRT=#サーバー証明書.crt
#作業場、VPNサーバードメイン
readonly SRV_DOMAIN=#サーバードメイン
readonly OUTPATH=./keyCrts

#初期化
rm /etc/ipsec.d/cacerts/*
rm /etc/ipsec.d/certs/*
rm /etc/ipsec.d/private/*
mkdir ./keyCrts

#ルート証明書作成
cakey=${OUTPATH}/${CA_KEY}
cacrt=${OUTPATH}/${CA_CRT}
ipsec pki --gen > $cakey
ipsec pki --self --in $cakey --ca --dn "C=JP, O=strongSwan, CN=strongSwanVPN CA" > $cacrt

cp $cakey /etc/ipsec.d/private/
cp $cacrt /etc/ipsec.d/cacerts/
chmod 600 /etc/ipsec.d/private/$CA_KEY
chmod 600 /etc/ipsec.d/cacerts/$CA_CRT
chown root:root /etc/ipsec.d/private/$CA_KEY
chown root:root /etc/ipsec.d/cacerts/$CA_CRT

#サーバー証明書作成
# 署名にひねりがあるため注意。
# 参考資料:
# 1). https://wiki.strongswan.org/projects/strongswan/wiki/Win7CertReq
srvkey=${OUTPATH}/${VPN_KEY}
srvcrt=${OUTPATH}/${VPN_CRT}
ipsec pki --gen > $srvkey
ipsec pki --pub --in $srvkey | \
	ipsec pki \
	--issue --cacert $cacrt --cakey $cakey --san $SRV_DOMAIN \
	--flag serverAuth --dn "C=JP, O=strongSwan, CN=${SRV_DOMAIN}" > $srvcrt

cp $srvkey /etc/ipsec.d/private/
cp $srvcrt /etc/ipsec.d/certs/
chmod 600 /etc/ipsec.d/private/$VPN_KEY
chmod 600 /etc/ipsec.d/certs/$VPN_CRT
chown root:root /etc/ipsec.d/private/$VPN_KEY
chown root:root /etc/ipsec.d/certs/$VPN_CRT
```

### 設定ファイル編集
```bash:/etc/ipsec.conf
# IPSec IKEv2
conn EAP-MSCHAPv2
   leftsubnet=0.0.0.0/0
   auto=add
   # 省略可(default: pubkey)。認証方式。サーバー側は公開鍵認証。
   leftauth=pubkey
   # 必須。証明書。
   leftcert=#サーバー証明書.crt
   # 必須。認証方式。クライアントはEAP-MSCHAPv2認証。
   rightauth=eap-mschapv2
   # 必須。VPNクライアントへ振るIPアドレスの範囲。IKEv2認証を使用する際には必要。
   # サーバーの所属ネットとは異なるアドレスにする。
   rightsourceip=192.168.x.0/24
   # 必須。Windows対応に必要。Androidでは不要
   eap_identity=%any
```

### 認証設定ファイル編集
```bash:/etc/ipsec.secrets
# サーバー秘密鍵、ユーザー名、パスワード部分を
# 埋めたものをipsec.secretsへ追記する。

%any : RSA KeyAAA #サーバー秘密鍵.key
UserNameBBB : EAP "PasswordCCC" #ユーザー名 & パスワード
```

### sysctl の編集
```bash:/etc/sysctl.conf
#サーバーがVPNクライアントと内部ネットワークを繋ぐルーター
#として機能できるよう以下の設定をsysctl.confへ追記する。
net.ipv4.ip_forward=1
```

### その他の作業

* **作成したルート証明書をクライアントへインストール**  
* **ルーターを設定変更**  
  VPNサーバーの所属ネットのルーターにはVPNクライアントへ振られるVirtualIPの経路設定を行う必要があります。  
  192.168.x.0/24 → 192.168.x.x

## 2.3.ハマりどころ
* **MTU: クライアントのMTUをレジストリで変更する必要が生じることがあります。**  
  Android ([strongSwan VPN Client](https://play.google.com/store/apps/details?id=org.strongswan.android&hl=ja)\): オプションから変更可能。  
  Windows: [Tech TIPS：ネットワークのMTUサイズを変更する](http://www.atmarkit.co.jp/ait/articles/0610/07/news019.html)

# 3.感想
strongSwanとIKEv2の感想は以下の通り。

* **良かった点**
    * 単体でVPNを構築できるためにシンプルで設定しやすい。(strongSwan IKEv2)
    * 他のソフトと比較してapt-getから入れられるため、更新が楽。(strongSwan)
    * L2TP/IPSecより[早いらしい](https://www.bestvpn.com/blog/4147/pptp-vs-l2tp-vs-openvpn-vs-sstp-vs-ikev2/)。(速度測定してみましたが微妙...(IKEv2)
* **悪かった点**
    * MTU調整をクライアント側で行わなければならない。(IKEv2)
    * 色々拘らなければSoftEther VPNは楽でよかった...(strongSwan)

# 参考資料
* 「Windows 7 and newer」  
  https://wiki.strongswan.org/projects/strongswan/wiki/Windows7  
* 「Setting-up a Simple CA Using the strongSwan PKI Tool」  
  https://wiki.strongswan.org/projects/1/wiki/SimpleCA
* 「Requirements for certificates used with Windows 7」  
  https://wiki.strongswan.org/projects/strongswan/wiki/Win7CertReq