VyOS ver1.5でOpenVPN Server構築

# はじめに
自分のメモ代わりに書いていますので間違えている部分があるかもしれません。
また、セキュリティには詳しくないため設定に不備があるかもしれませんので自己責任でお願いします。
### できたこと
- VyOS 1.5台でOpenVPNサーバを構築
- クライアントPCの接続
- クライアントPCのIP固定
- デフォルトゲートウェイをVyOSに設定
- DNAT

### 環境
- VyOS 1.5-rolling-202409060006
- OpenVPN GUI v11.43.0.0
- Kagoya Cloud VPS

### 参考
https://docs.vyos.io/en/latest/configuration/interfaces/openvpn.html

### アジェンダ
- なんでVyOS？
- 今回検証した構成
- 流れ
- 実際のconfig
- 結果

# 本題
### なんでVyOS？
- Sophos XG FirewallをVPNサーバとしてVPS上においていたが要求スペックが少し高めなのでVyOSなどで節約したい
- BGP・OSPFとか喋れて便利
- 自宅バックボーンは全部VyOSだから慣れてる(フルルート食ってくれてる)

などなど

### 今回検証した構成
Kagoya VPSで構築　1C/1G インスタンス
VPN経由でcontainer-node-1にもアクセスできる構造にします。
![構成図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2668438/e750e91a-db66-2c3c-e6ef-95773c49ab6c.png)

### 流れ
主な流れは下記。項番1は終わっている想定で飛ばします。
1. VyOS初期設定
   - SSHの設定
   - IFの設定(デフォルトルートとかも)
   - 必要であればfirewallの設定
1. 証明書の作成
   - CA
   - Server
   - client
1. vtun作成
1. ovpnファイル作成と接続
1. オプション
   - 一つのClient証明書で複数端末を接続
   - デフォルトゲートウェイの設定
   - DNAT
   - IPの固定

### 実際のconfig
#### 証明書の作成
configureに入って`run generate`コマンドを実行すると生成して投入してくれるのでcompareで確認して問題なければcommitします。

:::note warn
注意
この方法だとconfigに秘密鍵なども記載されるので嫌な人はファイルパスを記載する方法で設定が必要です。
:::

```
configure
run generate pki ca install ca-sample
{いろいろ聞かれるので入力}
run generate pki certificate sign ca-sample install srv-sample
{いろいろ聞かれるので入力}
run generate pki certificate sign ca-sample install client-sample
{いろいろ聞かれるので入力}
{Enter certificate type: はclientを入力}
run generate pki dh install dh-sample
compare
commit
save
exit
```

#### vtun作成

```
configure
set interfaces openvpn vtun10 local-port '1194'
set interfaces openvpn vtun10 mode 'server'
set interfaces openvpn vtun10 openvpn-option '--tun-mtu 1370'
set interfaces openvpn vtun10 persistent-tunnel
set interfaces openvpn vtun10 protocol 'udp'
set interfaces openvpn vtun10 server client-ip-pool start '192.0.2.2'
set interfaces openvpn vtun10 server client-ip-pool stop '192.0.2.199'
set interfaces openvpn vtun10 server subnet '192.0.2.0/24'
set interfaces openvpn vtun10 server push-route 203.0.113.0/24
set interfaces openvpn vtun10 tls ca-certificate 'ca-sample'
set interfaces openvpn vtun10 tls certificate 'srv-sample'
set interfaces openvpn vtun10 tls dh-params 'dh-sample'
compare
commit
save
exit
```

#### ovpnファイル作成と接続
ここまででサーバ側は準備完了なので接続に必要なファイルを作成します。
2つ前のステップで作成した証明書を使用
```
show configuration commands |match "set pki ca ca-sample certificate"
show configuration commands |match "set pki certificate client-sample"
```
下記のフォーマットに必要な情報を記載してovpn形式で保存してOpenVPN GUIにインポートすれば接続できます。
```
client
dev tun
proto udp
remote {vyosのグローバルIP}
resolv-retry infinite
nobind
persist-key
persist-tun
remote-cert-tls server
data-ciphers AES-256-GCM
<ca>
-----BEGIN CERTIFICATE-----
{ca-sampleのcertificate}
-----END CERTIFICATE-----
</ca>
<cert>
-----BEGIN CERTIFICATE-----
{client-sampleのcertificate}
-----END CERTIFICATE-----
</cert>
<key>
-----BEGIN PRIVATE KEY-----
{client-sampleのprivate key}
-----END PRIVATE KEY-----
</key>
```
`push-route 203.0.113.0/24`を設定しているため接続が完了するとPCのルートテーブルに203.0.113.0/24が載り、ネクストホップがVPNになります。

#### オプション
- 一つのClient証明書で複数端末を接続
openvpn-optionに`--duplicate-cn`を追加するだけで実現できます。
client-ip-poolの始めたら順にIPを割り当ててくれるようになります。
```
set interfaces openvpn vtun10 openvpn-option '--duplicate-cn'
```
- デフォルトゲートウェイの設定
これもopenvpn-optionに`--push redirect-gateway`を追加するだけで実現できます。
`0.0.0.0/1`と`128.0.0.0/1`の2つの経路をクライアントに設定してくれます。
```
set interfaces openvpn vtun10 openvpn-option '--push redirect-gateway'
```
- DNAT
VPNをデフォルトゲートウェイにする場合、この設定を入れないとインターネットに出られなくなります。
フィルターなどを特に設定しなければ下記でインターネットに出入りができるようになります。
```
set nat source rule 100 outbound-interface name 'eth0'
set nat source rule 100 source address '192.0.2.0/24'
set nat source rule 100 translation address 'masquerade'
```
- IPの固定
個人的にこれが一番ハマりました。
結果としては、clientの証明書を作るときに設定するパラメータが重要です。
コンフィグに設定するClient名と`common name`を一致させる必要があります。
下記の`★ここ`と書いてる部分
```
set interfaces openvpn vtun10 server client ★ここ ip '192.0.2.201'
```
```
vyos@vyos# run generate pki certificate sign ca-sample install client-sample
Do you already have a certificate request? [y/N]
Enter private key type: [rsa, dsa, ec] (Default: rsa)
Enter private key bits: (Default: 2048)
Enter country code: (Default: GB) 
Enter state: (Default: Some-State) 
Enter locality: (Default: Some-City)
Enter organization name: (Default: VyOS) 
Enter common name: (Default: vyos.io) ★ここ
Do you want to configure Subject Alternative Names? [y/N]
Enter how many days certificate will be valid: (Default: 365) 1825
Enter certificate type: (client, server) (Default: server) client
Note: If you plan to use the generated key on this router, do not encrypt the private key.
Do you want to encrypt the private key with a passphrase? [y/N]
2 value(s) installed. Use "compare" to see the pending changes, and "commit" to apply.
```

### 結果
結論としては普段使用としては全く問題なしでした。月1000円の節約は大きい。
iperf3で速度を測ると平均70Mbps(kagoyaの最大帯域は100Mbps)出ており、CPU使用率は40%程度だったので少数のクライアントであればシングルコアで運用できそうという印象でした。
ゲートウェイとして動かした際に、一部サイトが表示されない問題が起こりましたが`--tun-mtu 1370`を入れることによって解決しました。(2時間ぐらいハマった...)
mtuの値は自分の環境に合わせて修正してください。
NATなどを合わせて使用するとグローバルIPに来た通信をVPN経由でサーバに転送することも可能なので便利そうです。

以上。
間違えなどあればご指摘を
暇があればサンプルをgithubに上げとくかも