Yamaha RTXからさくらVPSへのIKEv2 VPN

# 目的

Yamaha RTX をルーターとして使用している LAN があるとする．この LAN に外部のホストを参加させることを目的とする．具体的には

- Yamahaルーター (例：Yamaha RTX830) ．以下 RTX とする．
  - LAN側：192.168.100.1
    - 配下に Host1 (192.168.100.100) が存在．
  - WAN側：何らかのグローバルIP, FQDNは rtx.example.com
- 外部ホスト（例：さくらのVPS）．以下 VPS とする．
  - WAN側：111.222.333.444, FQDNは vps.example.net

という状況において，VPS を 192.168.100.254 として LAN に参加させ，Host1 と VPS の間でローカルアドレスを介した通信が行える状態を目指す．特に「RTX から VPS に向かって」VPN を張るように設定する（通常とは逆）．

# お断り

半日で調べて設定しただけなので，勘違いや見落としがあるかもしれません．本記事に基づいて何を行うにしても自己責任でお願いします．

# 背景

LAN 内のさまざまなネットワークサービスを提供するサーバが必要だが，CPU・メモリ・ストレージ・ネット帯域は最低限で問題ない．できれば故障が少なく，初期状態からのインストールもバックアップからの復旧も容易で，停電の際も復電と同時に勝手に起動して欲しい．消費電力は少なく，ファンレスで騒音ゼロが望ましい…と考え，

1. Raspberry-Pi など SBC
1. [OpenBlocks](https://www.plathome.co.jp/product/openblocks/) などマイクロサーバー
1. [QNAPのVirtualization Station](https://www.qnap.com/en/software/virtualization-station)など出来合いの NAS 上で動く VM や Docker

などをこれまで運用してきた．しかしどれも実機を自分で管理する必要があることには変わりがない．

一方で手元の LAN 環境は Yamaha RTX をルーターとして使っており，[VPN拠点間接続の機能]()がある．この VPN 機能を使うことで外部で契約した VPS を仮想的に同一 LAN に参加させ，内部サーバとして運用することにする．特に，RTX 側から外部 VPS に対して IKEv2 による VPN 接続を行うことにする．この結果，RTX 側の WAN アドレスは何でもよく，また RTX 側で何らかのポート公開を行う必要もないこととなる．

# VPS側の設定

VPS は Ubuntu24.04 Server が新規インストールされた状態から開始して，最終的に StrongSwan を使って IKEv2 接続を受け付けることができるようにする．なおさくらの VPS のように[初期状態でパケットフィルターが設定されている](https://manual.sakura.ad.jp/vps/network/packetfilter.html)場合，UDP500番と4500番を許可しておく．

まず VPS に 192.168.100.254 を新たに割り当てる．以下では `netplan` で `ens4` に割り当てているが，どう構成してもよい．単純に `ens3` がもともとグローバルIPが割り当てられていた NIC で，`ens4` が未使用だったため，分かりやすく `ens4` にしているだけ．

```:/etc/netplan/01-netcfg.yaml
network:
  version: 2
  ethernets:
    "ens3":
      gateway4: ....
      addresses:
        - 111.222.333.444/24
    "ens4":
      addresses:
        - 192.168.100.254/24
```

つぎに StrongSwan を構成する．

```:bash
sudo apt install strongswan strongswan-pki libcharon-extra-plugins libcharon-extauth-plugins libstrongswan-extra-plugins
```

StrongSwan の設定には `ipsec.conf` を使うパターンと `swanctl` を使うパターンがあるが，今回は後者を採用する．このため `/etc/strongswan.conf` に `swanctl = /usr/sbin/swanctl -q` を追加する．


```:/etc/strongswan.conf
charon {
        load_modular = yes
        plugins {
                include strongswan.d/charon/*.conf
        }
        start-scripts {
                swanctl = /usr/sbin/swanctl -q
        }
}

include strongswan.d/*.conf
```

続いて `/etc/swanctl/conf.d/rtx.conf` として下記を作成する． `secret` の文字列はRTX側との事前共有鍵なので適当に決める．

```
connections {
    gw-gw {
        version = 2
        local_addrs = vps.example.net
        remote_addrs = rtx.example.com
        proposals = aes256-sha256-modp2048,default
        local {
            auth = psk
            id = 192.168.100.254
        }
        remote {
            auth = psk
            id = 192.168.100.1
        }
        children {
            net-net {
                esp_proposals = aes256-sha256-modp2048,default
                local_ts = 192.168.100.0/24
                remote_ts = 192.168.100.0/24
                mode = tunnel
                start_action = start
                close_action = start
            }
        }
        encap = yes
    }
}
secrets {
    ike-1 {
        secret = "12345678"
    }
}
```

またパケット通信を許可するためにufwを設定する．

```:/etc/ufw/sysctl.conf
net/ipv4/ip_forward=1
net/ipv4/conf/all/accept_redirects=0
net/ipv4/conf/all/send_redirects=0
net/ipv4/ip_no_pmtu_disc=1
```

```:bash
sudo ufw allow 22
sudo ufw allow 500
sudo ufw allow 4500
sudo ufw enable
```

最後に StrongSwan を再起動する．

```:bash
sudo systemctl restart strongswan-starter
```

# RTX側

`lan1`がLAN側で192.168.100.1，`lan2`がWAN側とする．また既存のトンネル設定は無い（いまから作成するIKEv2 VPNが `tunnnel 1`）とする．

```
ip lan1 proxyarp on
ip route 192.168.100.254 gateway tunnel 1
tunnel select 1
 ipsec tunnel 1
  ipsec sa policy 1 1 esp aes256-cbc sha256-hmac
  ipsec ike version 1 2
  ipsec ike always-on 1 on
  ipsec ike encryption 1 aes256-cbc
  ipsec ike group 1 modp2048
  ipsec ike hash 1 sha256
  ipsec ike keepalive log 1 off
  ipsec ike keepalive use 1 on rfc4306
  ipsec ike local name 1 192.168.100.1 ipv4-addr
  ipsec ike nat-traversal 1 on
  ipsec ike pre-shared-key 1 text 12345678
  ipsec ike remote address 1 vps.example.net
  ipsec ike remote name 1 192.168.100.254 ipv4-addr
  ipsec auto refresh 1 on
 tunnel enable 1
```

- `ip lan1 proxyarp on` は LAN 内の Host1 などが VPS への通信を RTX に送るようにするため
- `ipsec ike keepalive use 1 on rfc4306` は RTX 側から接続を開始するため
  - 参考：[strongSwanとRTX1210の拠点間VPN接続(IKEv2, IPv4 over IPv6) - Qiita](https://qiita.com/kerorinfather/items/286b9647bdb7068b367d)

# 確認

VPS側で

```:bash
sudo swanctl --list-sas
```

を行うと，下記のように接続状態を確認することができる．

```
gw-gw: #2, ESTABLISHED, IKEv2, ...
  local  '192.168.100.254' @ ...
  remote '192.168.100.1' @ ...
  AES_...
  established ....s ago, rekeying in ....s
  net-net: #2, reqid 1, INSTALLED, ...
    installed ....s ago, rekeying in ....s, expires in ....s
    in  ........,   .... bytes,    .... packets,     0s ago
    out ........,   .... bytes,    .... packets,     0s ago
    local  192.168.100.0/24
    remote 192.168.100.0/24
```

また

```:bash
ping 192.168.100.1
```

で疎通確認ができる．

逆にRTXのコンソールから

```
ping 192.168.100.254
```

も通るはずであり，さらに Host0 からも同様に ping ができるはず．

# まとめ

以上により，LAN内の Host1 から VPS に対して，アドレス 192.168.100.254 で SSH などができるようになった．あとは VPS に適宜サーバをセットアップすればよい．

なおさくらのVPSのように，VPSとは別レイヤーのパケットフィルターをWEBインターフェースから設定できるなら，SSHアクセスを遮断してもよい．この場合，

- グローバルIPからのSSHは受け付けない
  - WEBインターフェースで許可すれば受け付ける状態に戻る
  - あるいはWEBインターフェースからシリアルコンソールにアクセスすれば何でもできる
- VPN側からのSSHは受け付ける

という状態になり，グローバルIP側でSSHサーバを守ることを考える必要が無くなる．あるいは逆に，VPSをLANに対するSSHのジャンプサーバとして運用することもできる（特にRTXが外部からSSHを受け付けることができない場合など）．

また VPS から特定のサーバやサブネットへのアクセスを RTX 経由で行いたい（VPS から直接外に出るのではなく，トンネルして RTX から出ていきたい）場合，`/etc/swanctl/conf.d/rtx.conf` の `remote_ts` にカンマ区切りで指定することができる．

```:/etc/swanctl/conf.d/rtx.conf
                remote_ts = 192.168.100.0/24,AAA.BBB.CCC.0/24
```

# 参考にした情報

- [リモートアクセスVPN(IKEv2)の設定手順](https://www.rtpro.yamaha.co.jp/RT/docs/ipsec/ikev2_ras/index.html)
- [strongSwanとRTX1210の拠点間VPN接続(IKEv2, IPv4 over IPv6) - Qiita](https://qiita.com/kerorinfather/items/286b9647bdb7068b367d)
- [RTX1200とstrongSwanをIPsecトンネルモードでVPN接続する](https://tydk27.hatenadiary.com/entry/20210102/1609599324)