フレッツ網内折り返し通信での快適VPN。Wireguardのパフォーマンスを引き出す

# はじめに

https://qiita.com/tinoue@github/items/ebcdf5423d87df0ad7cc

この記事で書いたように、設定が超簡単なtailscale VPNをRaspberry Pi4で動かしてVPN環境を構築していました。その後環境が変わり両方の拠点でV6プラス(OCNバーチャルコネクト)に移行。事実上グローバルIPアドレスが固定となるため、VPNをtailscaleからWireguardに移行してみました。

また、インターネットを経由せずにフレッツ網内での接続となるため、そちらの面でも通信速度の向上が望めます。

## フレッツIPv6網内折り返し通信でのWireguard VPN接続

基本的には以下の記事の内容そのままです。

https://internet.watch.impress.co.jp/docs/column/shimizu/1296873.html

### Wireguard及びルータ設定のポイント

- WireguardはIPv6で接続するが、サーバー側のIPv6名前解決に https://i.open.ad.jp を利用する
- Wireguardサーバーだけでなくクライアント側でも使用するポート番号を指定する
- サーバ側のブロードバンドルーターにて、IPv6パケットフィルタリングを設定する際、上記送信元・送信先ポートの両方を設定することでフィルタリング条件を絞る。

### Raspberry PiのIPv6グローバルアドレスを固定にする

自分の環境ではVPNを利用した拠点間同一セグメントネットワークを構築しているため、Raspberry Pi上で仮想ブリッジインタフェースを定義しています。デフォルトではこのブリッジインタフェースのMACアドレスはランダムなため、Raspberry Piが取得するIPv6アドレスが起動のたびに代わってしまいます。

アドレスを直接/etc/network/interfacesに記述してもいいのですが、今回は固定したMACアドレスを同ファイルに記述しました。

/etc/network/itnerfaces

```
auto br_lan
iface br_lan inet dhcp
     hwaddress ether 92:6a:68:ed:97:03
     pre-up ip link add name br_lan type bridge
<略>
```

## フレッツ網折り返しWireguard VPNの速度測定

測定は夜間以外で行いました。

### まずはインターネットのスピード

- 拠点A：ドコモ光V6プラス

```
$ speedtest

   Speedtest by Ookla

     Server: i3D.net - Tokyo (id = 21569)
        ISP: JPNE
    Latency:     4.37 ms   (0.19 ms jitter)
   Download:   301.65 Mbps (data used: 243.8 MB )                               
     Upload:   487.73 Mbps (data used: 457.2 MB )                               
Packet Loss:     0.0%
```

下り301Mbps、上り487Mbps。
マンションタイプなのでこんなものでしょう。

- 拠点B：フレッツ光OCNバーチャルコネクト

```
$ speedtest

   Speedtest by Ookla

     Server: IPA CyberLab 400G - Tokyo (id = 48463)
        ISP: NTT
    Latency:     3.31 ms   (0.33 ms jitter)
   Download:   740.45 Mbps (data used: 599.3 MB )                               
     Upload:   855.04 Mbps (data used: 440.4 MB )                               
Packet Loss:     0.0%
```

下り740Mbps、上り855Mbps。
マンションタイプなのに妙に速いです。ただ、夜間はOCNの公平制御が入って100Mbps前後になる場合もあります。

### 拠点間のRaspberry Pi4同士でのping

- Wireguard

```
$ ping -c 3 10.0.0.2
PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data.
64 bytes from 10.0.0.2: icmp_seq=1 ttl=64 time=4.60 ms
64 bytes from 10.0.0.2: icmp_seq=2 ttl=64 time=5.36 ms
64 bytes from 10.0.0.2: icmp_seq=3 ttl=64 time=4.94 ms

--- 10.0.0.2 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 4.598/4.964/5.356/0.309 ms
```

- GRETAP over Wireguard（L2トンネル環境）

```
$ ping -c 3 192.168.2.9
PING 192.168.2.9 (192.168.2.9) 56(84) bytes of data.
64 bytes from 192.168.2.9: icmp_seq=1 ttl=64 time=5.05 ms
64 bytes from 192.168.2.9: icmp_seq=2 ttl=64 time=5.46 ms
64 bytes from 192.168.2.9: icmp_seq=3 ttl=64 time=5.58 ms

--- 192.168.2.9 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 5ms
rtt min/avg/max/mdev = 5.049/5.362/5.576/0.241 ms
```

これはVPN + GRETAP L2トンネルで拠点間を同一セグメントネットワークとしているものです。L2トンネル環境下でもそれほど悪くない応答時間です。

- tailscale

```
$ ping -c 3 100.98.154.122
PING 100.98.154.122 (100.98.154.122) 56(84) bytes of data.
64 bytes from 100.98.154.122: icmp_seq=1 ttl=64 time=27.1 ms
64 bytes from 100.98.154.122: icmp_seq=2 ttl=64 time=8.96 ms
64 bytes from 100.98.154.122: icmp_seq=3 ttl=64 time=6.66 ms

--- 100.98.154.122 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 4ms
rtt min/avg/max/mdev = 6.659/14.246/27.126/9.156 ms
```

tailscaleのping応答時間も最初の一回を除き悪くありません。それもそのはずで、`tailscale status`でステータスを見ると、tailscaleもIPv6網内折り返しで直接接続していました。面倒な設定なしでこれをやってくれるのはすごいです。


### 拠点間のRaspberry Pi4同士でのiperf

- Wireguard

```
pi@raspberrypi4:/sys/devices/system/cpu/cpufreq/ondemand $ iperf -M 1250 -c 10.0.0.2
WARNING: attempt to set TCP maximum segment size to 1250, but got 536
------------------------------------------------------------
Client connecting to 10.0.0.2, TCP port 5001
TCP window size: 67.5 KByte (default)
------------------------------------------------------------
[  3] local 10.0.0.1 port 48668 connected with 10.0.0.2 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   423 MBytes   354 Mbits/sec
```

354Mbps。なお、拠点間のWireguard接続はIPv6を使用していますが、WireguardのインタフェースアドレスはIPv4です。

- GRETAP over Wireguard（L2トンネル環境）

```
$ iperf -M 1250 -c 192.168.2.9
WARNING: attempt to set TCP maximum segment size to 1250, but got 536
------------------------------------------------------------
Client connecting to 192.168.2.9, TCP port 5001
TCP window size: 90.0 KByte (default)
------------------------------------------------------------
[  3] local 192.168.2.196 port 60534 connected with 192.168.2.9 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   406 MBytes   341 Mbits/sec
```

340Mbps。Wireguardの素のスピードが354Mbpsなので、L2トンネル環境でもそれほどオーバーヘッドなく接続できています。

- tailscale

```
pi@raspberrypi4:/sys/devices/system/cpu/cpufreq/ondemand $ iperf -M 1250 -c 100.98.154.122
WARNING: attempt to set TCP maximum segment size to 1250, but got 536
------------------------------------------------------------
Client connecting to 100.98.154.122, TCP port 5001
TCP window size: 45.0 KByte (default)
------------------------------------------------------------
[  3] local 100.92.41.28 port 52662 connected with 100.98.154.122 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.0 sec   209 MBytes   175 Mbits/sec
```

175Mbps。Wireguard(354Mbps)がtailscaleの2倍速いということになりました。

以前、フレッツ網内折り返しではなくIPv4インターネット経由(V6プラス)でVPN接続していた場合は、Wireguardとtailscaleの速度差は数割程度でした。IPv6折り返し通信でWireguardを使用する価値は高いと思います。

## さらにWireguardのパフォーマンスの向上を目指してみる

Wireguardの暗号化アルゴリズムを軽いものにしてパフォーマンスを上げられないかと思ったのですが、以下の記事を見るとRaspberry Pi4で普通に800Mbps越えの模様。特にいじるところはなさそうです。

https://www.reddit.com/r/WireGuard/comments/eeafds/wireguard_throughput_on_raspberry_pi_4/

### カーネルパラメータのチューニング

上記Redditの情報に、気になるリンクがありました。Linuxカーネルのパケットスケジューラ周りの設定で改善の余地があるようです。

https://www.reddit.com/r/WireGuard/comments/du22vg/wireguard_strange_3_node_slowness/

```
net.core.default_qdisc=pfifo_fast
net.ipv4.tcp_congestion_control=cubic
```

このデフォルトの設定を

```
net.core.default_qdisc=fq
net.ipv4.tcp_congestion_control=bbr
```

こう変更するとパフォーマンスが上がるとのことで上記設定を/etc/sysctl.confに追加して試してみました。ちなみにこのBBR、Googleが開発した新しい輻輳制御アルゴリズムだそうです。

### パラメータチューニング後の速度測定

```
pi@raspberrypi4:/proc/sys/net $ iperf -M 1250 -c 10.0.0.2
WARNING: attempt to set TCP maximum segment size to 1250, but got 536
------------------------------------------------------------
Client connecting to 10.0.0.2, TCP port 5001
TCP window size:  122 KByte (default)
------------------------------------------------------------
[  3] local 10.0.0.1 port 50138 connected with 10.0.0.2 port 5001
[ ID] Interval       Transfer     Bandwidth
[  3]  0.0-10.2 sec   590 MBytes   484 Mbits/sec
```

354Mbpsから484Mbpsと、37%のスピードアップです。これはすばらしい。ただ、BBRはパケットロスが多い環境なので有効だそうなので、品質高そうなフレッツ網で有効なのはちょっとわからないところです。

## 参考記事

環境が違いますが、以前のtailscale使用時の速度測定はこちら。フレッツ網内折り返しでのWireguard接続＋カーネルパラメータチューニングをすることで、トータルで約3倍の高速化ができました。

https://qiita.com/tinoue@github/items/4caa47e77a496294b3d7