前書き
今まで家庭内にある http サーバを外部に公開するために、固定IPのプロバイダを使っていたのだが、サーバマシンが壊れたのを契機に VPS に移行することにした。
ついでに、ネットワークが遅い問題を解決するのと、IPv6 が使えるようにしたかったので、IPoE のプロバイダに乗り換えることにした。
IPoE で IPv4 を使うためには、いろいろな方式があるが、最近の流行りは DS-LITE か MAP-E らしい。
当初、DS-LITE のプロバイダをお試ししてみたのだが、時間帯によって非常に遅く、今までのプロバイダよりも遅い始末で、すぐに解約した。(が、解約が有効になるのが月末と言う罠があり、翌月まで次のプロバイダが試せなかった)
次に試したのが MAP-E のプロバイダで、こちらは混雑している時間帯でも 200Mpbs 以上の速度が出た。
また、これらを試すために、フレッツ貸し出しのルータの代わりに、 YAMAHA の NVR510 と言うルータを購入した。これは、 GUI だけでなくコマンドを使って細かい設定ができるのがウリである。
良くなったこと
- 速くなった
- IPv6 が使えるようになった
- 外部向けのサービスを VPS に移行したことで、家庭内にサーバを置かなくて良くなった。
悪くなったこと
- MAP-E なので、外から家にアクセスする方法がなくなった。(厳密には、指定されたポートを foraward すればできないことはないらしい)
- NVR510 は光電話のクライアントになれるが、SIPサーバになれないので、光電話の子機として iPhone を使うことや、asterisk に留守番電話をさせることができなくなった。
対策案
NVR510 には IPsec/L2TP の VPN の機能があるので、当初固定IPのプロバイダの契約を残したまま、そこをエンドポイントにして VPN を張ることを考えた。
しかし、iPhone からの VPN の接続はうまくいくものの、FreeBSD の VPS からの接続がどうしてもうまくいかない。
OpenVPN は iPhone も FreeBSD もうまく行くことがわかっていたが、NVR510 が対応していない。
そんなとき、WireGuard の存在を知った。
WireGuard
- 職場の slack で以下の記事を知った。
第614回 WireGuardでVPNサーバーを構築する:Ubuntu Weekly Recipe|gihyo.jp … 技術評論社 - 公式サイトは https://www.wireguard.com/
いろいろ試行錯誤をしたのだが、最終形態だけ書くことにする。
黒が実際の接続、青がVPNとなっている。
VPS(FreeBSD) の設定
今回の構成の中で、このマシンだけが外向きの固定IPを持っているので、これをサーバとする。
- wireguard は、ports/pkg にあるので、そこからインストールする。
- 設定ファイルは /usr/local/etc/wireguard/ に置く。
- 当初、wg0一つだけで実現しようとしたのだが、iPhoneと家庭内で通信ができず、wg0とwg1の二つのインターフェイスを使うことに。
- 同様の問題は Connection between two clients にあったが、解決したか不明だった。
- 二つのインターフェイスを使う方法は、Routing between wg interfaces with WireGuard – JRS Systems: the blog を参考にした。
- 鍵の生成方法については、公式含めいろいろなところに書いてあるので省略する。
[Interface]
Address = 192.168.1.1
ListenPort = 51820
PrivateKey = <private key of server>
[Peer]
PublicKey = <public key of raspberry pi>
AllowedIPs = 192.168.1.2/32, 192.168.0.0/24
[Interface]
Address = 192.168.2.1
ListenPort = 51821
PrivateKey = <private key of server>
[Peer]
# iphone
PublicKey = <public key of iphone>
AllowedIPs = 192.168.2.2/32
gateway_enable="YES"
wireguard_enable="YES"
wireguard_interfaces="wg0 wg1"
他のやってみた系の記事では、サーバ側に NAT の設定があるが、このVPNの目的は出先のFreeWiFi等からの通信を全てVPNを通すことではなく、出先から家庭内LANにアクセスすることなので、サーバ側にはNATの設定はない。
肝は、wg0.conf の AllowedIPs に家庭内LANの192.168.0.0/24 が書いてあること。
上記設定でOS起動時に起動するが、手動で起動する場合は以下のようにする。
# service routing start
# service wireguard start
Rasipberry PI の設定
- Raspberry PI は家庭内にあり、Raspbian buster がインストールされている。
-
sudo apt install wireguard
でインストール - 設定ファイルは /etc/wireguard に置く。
[Interface]
PrivateKey = <private key of raspberry pi>
Address = 192.168.1.2
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT
[Peer]
PublicKey = <public key of server>
EndPoint = <host name or ip address of server>:51820
AllowedIPs = 192.168.1.0/24, 192.168.2.0/24
PersistentKeepalive = 25
PersistentKeepalive = 25
は、NATの内側にある場合は必須だそうで、これがないとサーバ→Raspberry PIの通信ができなかった。
肝は、AllowedIPsにiPhoneに割り当てる 192.168.2.0/24 が書いてあること。
参考にしたサイトでは、PostUpにroute add -net 192.168.2.0/24 gw 192.168.1.1 ; ping -c1 192.168.1.1
的なことを書けと書いてあったが、なくても問題なかった。
また、VPSはこのルートを使ってインターネットに出る必要はないので、他のサイトに書いてあったiptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
も削除した。
-
sudo systemctl enable wg-quick@wg0
でsystemctlに登録。 -
sudo systemctl start wg-quick@wg0
で手動起動。
iPhoneの設定
- iPhone の WireGuard は AppStore にある。
- 設定はGUIから行うが、スクリーンショット1枚に収まらないのでwg0.conf形式で書く
[Interface]
PrivateKey = <private key of iphone>
Address = 192.168.2.2
[Peer]
PublicKey = <public key of server>
EndPoint = <host name or ip address of server>:51821
AllowedIPs = 192.168.2.0/24, 192.168.1.0/24 192.168.0.0/24
PersistentKeepalive = 25
肝は、AllowedIPsに家庭内LANの192.168.0.0/24 と、Raspberry PI に割り当てる 192.168.1.0/24 が書いてあること。
NVR510 の設定
家庭内LAN上のマシンから、VPN 経由で VPS に通信が行くように、静的ルーティングを追加する。
ip route 192.168.1.0/24 gateway 192.168.0.2
ip route 192.168.2.0/24 gateway 192.168.0.2
動作確認
お互いに ping を打ってみたり、traceroute してみたりすると良いと思うよ。
雑多なこと
VPN に割り当てる IP アドレスは、プライベートネットワークのアドレスを使う。
上記では、192.168.1.0/24 と 192.168.2.0/24 を使ったが、これが iPhone が所属する WiFi のネットワークと被るとうまく通信ができないと思われる。3オクテット目は、0, 1, 2, 10, 100あたりは避けろとどこかで読んだ気がする。
ここには書かなかったが、Macのクライアントは homebrew等で入れるオリジナルと、Mac AppStore で入るGUI版がある。
GUI版は簡単に使えるが、PostUp 等が使えないので、手動でルーティングテーブルを追加したいときなどは微妙である。
また、WireGuard自体は IPv6 に対応しているので、v6 を使ってもいろいろできるが、ここでは割愛した。
IPsec/L2TP は FreeBSD でどう頑張っても接続できなかったのだが、WireGuard は設定が非常にシンプルで、OpenVPNより速いと言う噂(試してない)なので、今後に期待。
ただし、鍵の長さが寂しいように感じるのだが、これはこう言うものなのだろうか?