OpenVPNのpacket loss
以前OpenVPN Cloudを利用してVPNを作成し,使用していたのですが,通信が安定しませんでした.2拠点間の通信をpingコマンドで確認したところ,18.4% packet loss という結果でした.同時にそれぞれの拠点からgoogle.comに対してpingコマンドを実行したところ,packet lossはありませんでした.OpenVPNが関与するとpacket lossが発生するわけです.
--- 10.0.0.2 ping statistics --- 38 packets transmitted, 31 packets received, 18.4% packet loss round-trip min/avg/max/stddev = 34.296/86.453/141.667/30.424 ms
みーの設定がいまいちだったのかもしれませんが,どうしても解決できなかったので,WireGuardを使用してみることにしました.
WireGuardでVPNを構築する
Global IP アドレスを付与したRaspberry PIをサーバーとして使用します.WireGuardを設定し,サービスとして登録し,常時実行するようにします.
サーバーのIPアドレスを設定
Ubuntu 20.04.4 LTS (GNU/Linux 5.4.0-1065-raspi aarch64) $ sudo apt install wireguard $ cat /etc/netplan/50-cloud-init.yaml network: ethernets: eth0: dhcp4: true optional: true version: 2 $ cat /etc/netplan/60-global.yaml network: version: 2 ethernets: eth0: addresses: - xx.xx.xx.xx/24 nameservers: addresses: [ ... ] routes: - to: default via: xx.xx.xx.yy $ sudo netplan apply $ ip addr 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000 link/ether dc:a6:32:xx:xx:xx brd ff:ff:ff:ff:ff:ff inet xx.xx.xx.xx/24 brd xx.xx.xx.255 scope global eth0 valid_lft forever preferred_lft forever inet zz.zz.zz.zz/18 brd zz.zz.zz.255 scope global dynamic eth0 valid_lft 604584sec preferred_lft 604584sec
まず,上記の如くnetplan.ioを用いて,グローバルIPアドレスxx.xx.xx.xxおよびローカルエリアネットワーク(LAN)用のプライベートIP アドレスzz.zz.zz.zzをeth0に付与しました.
グローバルIPアドレスはあまり管理したくないので,適当にドメインを取得してDNSレコードに登録しておくと便利です.以下ではserver.example.com
に対してAレコードをxx.xx.xx.xxで設定することを前提とします.
WireGuardを設定
公式サイトに記載されている方法に従ってwg0.confを作成します.なお,以下のキーはテスト用の値です.
$ wg genkey | tee privatekey | wg pubkey > publickey $ ls privatekey publickey $ cat privatekey SJXOK9m2xB5pLZ5RMG7a0RjLhyxSsDFmwgDMgfkCwUA= $ cat publickey bkXTeN98sJGeE4YACpcclmzDgcFGJeZQlItli2ejqzo= $ nano wg0.conf
Serverのwg0.conf
[Interface] Address = 10.0.0.1/32 ListenPort = 51820 PrivateKey = [Server PRIVATE KEY] [Peer] # Client PublicKey = [Client PUBLIC KEY] AllowedIPs = 10.0.0.2/32 Endpoint = zz.zz.zz.aa:51820
Clientのwg0.conf
[Interface] Address = 10.0.0.2/32 ListenPort = 51820 PrivateKey = [Client PRIVATE KEY] [Peer] # Server PublicKey = [Server PUBLIC KEY] AllowedIPs = 10.0.0.1/32 Endpoint = server.example.com:51820 # PersistentKeepalive = 25
これら2個の設定において,ClientのEndpoint = server.example.com:51820
および,server.example.comはインターネットで名前解決が可能であることから,ClientからServerへのアクセスが可能になります.したがって,Endpointはserver.example.com:51820のみ指定します.
もしClientがNATの内側に存在する場合は,PersistentKeepalive = 25
を有効にして,定期的に keepalive パケットを送信するようにします.
LANにFORWARDするならばiptablesやufwなどを使用してそのように設定しますが,ひとまずは不要です.
以下のコマンドで動作するか確認します.
$ wg-quick /full/path/to/wg0.conf $ ip addr ... 4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000 link/none inet 10.0.0.1/32 scope global wg0 valid_lft forever preferred_lft forever $ ping 10.0.0.2 PING 10.0.0.2 (10.0.0.2) 56(84) bytes of data. ... --- 10.0.0.2 ping statistics --- 15 packets transmitted, 15 received, 0% packet loss, time 14251ms
問題なければ,これを/etc/wireguard/wg0.confにrootをownerとして保存します.プライベートキーが平文で記載されたファイルが外部に漏洩すると大変なので,rootのみが読み書きできるよう最低限のパーミッションを付与します.
$ sudo -s $ chown root:root wg0.conf $ mv wg0.conf /etc/wireguard/ $ chmod 600 /etc/wireguard/wg0.conf $ ls /etc/wireguard/ -l total 4 -rw------- 1 root root 239 Jun 8 17:53 wg0.conf
WireGuardをサービスとして登録
wg-quick@wg0.service は /etc/wireguard/wg0.conf を読み込んでWireGuardを起動してくれますので,systemdのサービスとして有効化します.
$ sudo systemctl enable wg-quick@wg0.service $ sudo systemctl start wg-quick@wg0.service
ファイアウォールを設定
ufwを使用して51820/udpの通信を許可します.
$ sudo ufw allow 51820/udp $ sudo ufw status verbose 51820/udp ALLOW IN Anywhere
OpenVPNとWireGuardの比較
同じ2拠点間においてOpenVPNまたはWireGuardを用いてVPNを作成し,pingコマンドで往復の通信状況を確認しました.
OpenVPN
冒頭のデータと同じです.
--- 10.0.0.2 ping statistics --- 38 packets transmitted, 31 packets received, 18.4% packet loss round-trip min/avg/max/stddev = 34.296/86.453/141.667/30.424 ms
WireGuard
--- 10.0.0.2 ping statistics --- 35 packets transmitted, 35 received, 0% packet loss, time 34051ms rtt min/avg/max/mdev = 12.712/70.402/119.046/30.159 ms
packet lossがなくなりました.安定した通信ができているようです.レイテンシは同じぐらいでした.
各OSのClient
WireGuardのClientはとても充実しており,有名なOSならばそのまま使用できるように開発されています.
Linuxならばコマンドでもよいですが,MacOSやWindowsならばマウスで操作できると便利なので,このあたりの使い勝手もよいです.
MacOS
apps.apple.comGUIによる設定が可能で,直感的にWireGuardの切り替えが可能です.
また,汎用的なVPNなので,MacOSのシステム環境設定のネットワークにも馴染むよう設計されています.