strongSwan + xl2tpd でVPN(L2TP/IPsec)を構築する

# 執筆時点の環境
ここではstrongSwan, xl2tpdを使用してIPSec/L2TPなVPNを使用可能にします。

* UbuntuServer 16.04.1 LTS (SELinux 無効化)
* strongSwan v5.3.5
* xl2tpd v1.3.6

# やりたい事
外出先から自宅のマシンへアクセスできるようにしてみます。

    ┌─────────────────┐             ┌─────┐          ┌────────┐
    │ Android,Windows │-(Internet)->│ NAT │--(LAN)-->│ Server │
    └─────────────────┘             └─────┘          └────────┘

以下のOSで接続確認しています。

* Windows 10: L2TP/IPSec PSK
* Android 6.0.1: L2TP/IPSec PSK

# 手順
## 必要アプリの導入
```bash
$ sudo apt-get install -y strongswan xl2tpd
```

## 各種設定
### strongSwan (IPSec)

```bash:/etc/ipsec.conf
# IPSec 接続設定
# 以下の記述をipsec.confへ追記する。細かい設定項目は公式資料を参照すること。
# https://wiki.strongswan.org/projects/strongswan/wiki/IpsecConf

config setup
    # 必須。VPNクライアントがNATの内側にある場合に必要。
    nat_traversal=yes
# デフォルト設定(全接続の共通設定が記述されます)
conn %default
    # 必須。strongSwan起動時に接続プロファイルを受信待機状態にする。
    auto=add
# L2TP/IPSec用接続設定
conn L2TP-NAT
    # 必須。IPSec/L2TPではIPSecはHost to Hostで繋ぐ。
    type=transport
    # 省略可。指定するならばVPNサーバーのIPアドレス。
    # (ex: 192.168.x.x)
    #left=%any 
    # 必須(default: pubkey)。認証方式。事前共有鍵を使用。
    leftauth=psk
    # 省略可。VPNクライアントのIPアドレス
    # (ex: 192.168.y.y)
    #right=%any
    # 必須。認証方式。事前共有鍵を使用。
    rightauth=psk
```
```bash:/etc/ipsec.secrets
# IPSec 認証用情報
# 以下の記述をAAAを埋めた上でipsec.secretsの先頭へ追記する。
# 細かい設定項目は公式資料のPSKの章を参照すること。
# https://wiki.strongswan.org/projects/strongswan/wiki/IpsecSecrets
# (ex:
#      : PSK "abcd")
: PSK "AAA" #事前共有鍵
```

### xl2tpd (L2TP)
```bash:/etc/xl2tpd/xl2tpd.conf
; 以下の記述のzA-zZ,XXXを埋めたものを元ファイルへ追記する。
; 細かい設定項目はmanコマンドを参照すること。
; man xl2tpd.conf

[lns default]                               ; Our fallthrough LNS definition
  ; VPNクライアントへ振るIPアドレス範囲
  ; (ex: 192.168.z.1-192.168.z.254)
  ip range = zA-zZ                          ; * Allocate from this IP range
  ; VPNサーバーのIPアドレス
  ; (ex: 192.168.x.x)
  local ip = XXX                            ; * Our local IP to use
  length bit = yes                          ; * Use length bit in payload?
  refuse pap = yes                          ; * Refuse PAP authentication
  refuse chap = yes                         ; * Refuse CHAP authentication
  require authentication = yes              ; * Require peer to authenticate
  name = l2tp                               ; * Report this as our hostname
  pppoptfile = /etc/ppp/options.l2tpd.lns   ; * ppp options file
```
```bash:/etc/ppp/options.l2tpd.lns
name l2tp
refuse-pap
refuse-chap
refuse-mschap
require-mschap-v2
nodefaultroute
lock
nobsdcomp
mtu 1280
mru 1280
logfile /var/log/xl2tpd.log
```
```bash:/etc/ppp/chap-secrets
# 以下の記述のUserName ,Passwordを埋めたものをchap-secretsへ追記する。
# (ex: "carol" * "abcd123" *)。

# Secrets for authentication using CHAP
# client	server	secret			IP addresses
"UserName" * "Password" *
```

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

### その他の設定
* **NATのポート開放**  
  UDP 500,4500ポートの受信を許可する必要があります。
* **ルーターを設定変更**  
  VPNサーバーの所属ネットのルーターにはVPNクライアントへ振られるIPアドレスの経路設定を行う必要があります。  
  192.168.z.0/24 → 192.168.x.x
* **クライアントの設定変更**  
  NATの内側にあるVPNサーバーへ外側のWindowsクライアントから接続する場合、Windowsはレジストリから設定変更する必要があります。  
  https://support.microsoft.com/ja-jp/kb/926179

## 設定を適用
strongSwan, xl2tpdを再起動します。VPNクライアントから接続できれば成功。

```bash
#デーモンを再起動
sudo systemctl restart strongswan
sudo systemctl restart xl2tpd
sudo sysctl -p
```

# 参考資料

* IKEv1 Configuration Examples  
  https://wiki.strongswan.org/projects/strongswan/wiki/IKEv1Examples)
* Configuration Files  
  https://wiki.strongswan.org/projects/strongswan/wiki/ConfigurationFiles