UbuntuでIKEv2 VPNサーバーを構築(Libreswan)

# はじめに
+ VPNサーバをL2TP over Ipsecで立てていたが、iPhone(iOS)のVPNでは接続できるのに、macOS14(Sonoma)あたりからMacのVPNクラアントで繋がらなくなることが多くなった。再起動後は繋がるのに、しばらくすると繋がらなくなったり。macOS15(Sequoia)だと全く繋がらなくなった。
+ L2TPよりIKEv2の方が良いみたいなので、IKEv2のVPNサーバを立ててみる。
+ ChatGPTに聞いたことのまとめ。書いとかないと忘れるんでね。

# L2TPとIKEv2の比較

| 特徴 | L2TP/IPsec | IKEv2/IPsec |
|------|------------|-------------|
| **セキュリティ** | 良好（IPsecと組み合わせて使用） | 優れている（最新の暗号化方式） |
| **速度** | 比較的遅い（二重カプセル化による） | 高速（効率的なプロトコル設計） |
| **安定性** | 中程度 | 優れている（MOBIKE技術採用） |
| **再接続能力** | 弱い | 強い（ネットワーク切替時に強い） |
| **マルチデバイス対応** | 広い（レガシーデバイスも対応） | 主要OSには対応（古いデバイスでは制限あり） |
| **ファイアウォールへの対応** | 制限される場合あり（UDP 500などがブロックされる可能性） | より強い（ポート切替機能あり） |
| **設定の複雑さ** | 比較的簡単 | やや複雑 |
| **消費リソース** | 多め | 少なめ |
| **モバイル対応** | 基本的な対応 | 優れている（接続切替に強い） |
| **初期開発年** | 1999年頃 | 2005年頃 |
| **標準規格** | RFC 2661 | RFC 7296 |

+ 「IKEv2は特にモバイルデバイスでの使用や、頻繁にネットワークが切り替わる環境で優れたパフォーマンスを発揮します。L2TPはより広範なデバイスで利用可能ですが、全体的なパフォーマンスとセキュリティではIKEv2に劣ります」

だそうです。

# Ubuntuサーバを用意
+ 実サーバなり、Hyper-Vなり、ParallelsなりでUbuntuサーバを用意します。
仮想サーバの場合、ネットワークは「共有」にしないこと。必ず実ネットワークにブリッジするように。のちのちVPNサーバでネットワーク転送がうまくいかなくなる。
ここでは
+ ネットワークアドレスは192.168.2.0/24
+ VPNサーバのIPは固定で192.168.2.254
とする

### 1. 必要なパッケージのインストール
```sh:
$ sudo apt update
$ sudo apt install -y strongswan strongswan-pki libstrongswan-extra-plugins \
  libcharon-extra-plugins libstrongswan-standard-plugins iptables-persistent
```
途中でiptablesのip4.rulesとipv6.rulesを保存するか聞いてくるのでyes
### 2. サーバー証明書とCA(認証局）を生成
まずは一時的な作業ディレクトリを作成
```sh
mkdir -p ~/ikev2-certs
cd ~/ikev2-certs
```
### 3. CA（認証局）の秘密鍵と証明書を作成
```sh:
$ ipsec pki --gen --type rsa --size 4096 --outform pem > ca.key.pem
$ ipsec pki --self --ca --lifetime 3650 \
  --in ca.key.pem --type rsa \
  --dn "CN=IKEv2 VPN Root CA" \
  --outform pem > ca.cert.pem
```
ここで以下のメッセージが出る場合
```sh:
TPM 2.0 - could not load "libtss2-tcti-tabrmd.so.0"
plugin 'tpm': failed to load - tpm_plugin_create returned NULL
```
TPM（Trusted Platform Module）プラグインが読み込めなかったという警告メッセージ。証明書が生成されていれば無視して構わない。
### 4. サーバー鍵と証明書を作成
+ サーバー鍵
```sh:
$ ipsec pki --gen --type rsa --size 4096 --outform pem > server.key.pem
```
+ サーバー証明書要求と署名
ローカルでテストする場合
--dn "CN=192.168.2.254"
--san "192.168.2.254"
のようにサーバのIPにする
グローバルIPやDDNSサービスの場合は、IPやFQDNを入れる。
+ ※ローカルでテストした後、FQDNが変更になる場合は、server.key.pemは再作成する必要がある。
```sh:
$ ipsec pki --pub --in server.key.pem --type rsa | \
  ipsec pki --issue --lifetime 1825 \
    --cacert ca.cert.pem \
    --cakey ca.key.pem \
    --dn "CN=192.168.2.254" \
    --san "192.168.2.254" \
    --flag serverAuth --flag ikeIntermediate \
    --outform pem > server.cert.pem
```


### 5. 証明書を配置
```sh:
$ sudo cp ca.cert.pem /etc/ipsec.d/cacerts/
$ sudo cp server.cert.pem /etc/ipsec.d/certs/
$ sudo cp server.key.pem /etc/ipsec.d/private/
```
### 6. StrongSwan 設定ファイル
```sh:
$ sudo pico /etc/ipsec.conf
```
```conf:/etc/ipsec.conf
config setup
conn ikev2
  keyexchange=ikev2
  ike=aes256-sha1-modp1024
  esp=aes256-sha1
  left=192.168.2.254 #サーバーのIPまたはFQDN
  leftid=192.168.2.254 #サーバーの識別子（通常はleftと同じ）
  leftcert=/etc/ipsec.d/certs/server.cert.pem
  leftsendcert=always
  leftsubnet=0.0.0.0/0 # VPNクライアントからの全ての接続を許可
  right=%any
  rightauth=eap-mschapv2
  rightdns=8.8.8.8 # 付与するDNS設定
  rightsourceip=192.168.2.0/24  # VPNクライアントの割当IPアドレス範囲
  eap_identity=%identity
  auto=start
```
### 7. ユーザー名とパスワードの設定
```sh:
$ sudo pico /etc/ipsec.secrets
```
user => vpnuser
password => vpnpassword
本来はもっと複雑なのに変更する
```sh:/etc/ipsec.secrets
: RSA server.key.pem
vpnuser : EAP "vpnpassword"
```
### 8. パケット転送の設定
Ubuntuはそれ自体がルータになることができる。
+ システムのIPv4パケット転送機能を有効
カーネルパラメータ net.ipv4.ip_forward を 1 (有効) に設定
※これにより、システムがネットワークパケットを異なるネットワークインターフェイス間で転送できるようになる。ルーターやゲートウェイとして機能するために必要な設定。

```sh:
sudo sysctl -w net.ipv4.ip_forward=1
```
+ 設定の永続化
上記のコマンドは一時的な変更であり、システムの再起動で失われる。
永続的に設定するには
```sh:
sudo nano /etc/sysctl.conf
```
以下の部分のコメントアウトを外す
```sh:/etc/sysctl.conf
net.ipv4.ip_forward = 1
```
### 9. iptablesの設定
+ ①NATテーブルの設定
-sはipsec.confのrightsourceip(192.168.2.0/24)、-oはip aで出てくるインターフェイス名
```sh:
$ sudo iptables -t nat -A POSTROUTING -s 192.168.2.0/24 -o eth0 -j MASQUERADE
```
+ ②NAT確認
```sh:
$ sudo iptables -t nat -L -n -v
```
+ ③FORWARD設定
-sソースと-d宛先　両方を設定する
rightsourceip(192.168.2.0/24)
```sh:
$ sudo iptables -A FORWARD -s 192.168.2.0/24 -j ACCEPT
$ sudo iptables -A FORWARD -d 192.168.2.0/24 -j ACCEPT
```
+ ④FORWARD確認
```sh:
$ sudo iptables -L FORWARD -n -v
```
+ ⑤永続化
これをしないと再起動でiptablesの設定が消える
```sh:
$ sudo apt install iptables-persistent
$ sudo netfilter-persistent save
```
### 10. VPNで接続するIPを追加する場合
/etc/ipsec.confのleftsubnetに追加する
iptablesやnetplanでルーティングを追加する必要はない
```:/etc/ipsec.conf
leftsubnet=128.20.1.0/24,10.0.0.0/8,192.168.33.0/24
```
### 11. サービス起動・確認
```sh:
$ sudo systemctl daemon-reload
$ sudo systemctl restart strongswan-starter
$ sudo ipsec statusall
```

### 12. クライアントからローカルIPで接続テスト
+ iOSの場合はサーバで作成した「ca.cert.pem」をAirDropなどで転送してインストールしておく。macOSは無くても接続できる。
+ クライアント側の設定
サーバ: 192.168.2.254
リモートID: 192.168.2.254
ユーザー名: vpnuser
パスワード: vpnpassword
+ サーバの設定が間違っていて変更した場合でも、クライアントの設定を削除してから再設定したほうが無難。経験上。

### 13. journalでリアルタイム監視
サーバ側でjournalを起動しておくとリアルタイム監視が可能
```sh:
$ sudo journalctl -fu strongswan-starter
```