2019-04-08

未来型 VPN : WireGuard を導入してみました

ここに特徴や説明が記載されています。

そこで Raspberry Pi 3 にインストールしてみました。

後述の「参考サイト」に導入手順が記載されており、これを参考にインストール・設定してみました。


VPN 導入目的は大きく2点です。

① 自宅ネットワークに外から安全にアクセスできるようにする。
② フリー WiFi 等で安全性を確保するために VPN を張って自宅ネットワークを経由して
  インターネットアクセスできるようにする。

これまでは OpenVPN を使っていましたが、速度低下が結構ありいま一つ、という感じでした。

今回 Wireguard の特徴を踏まえてシンプルかつ高速、というのに興味を持ち導入してみたわけです。

実際に導入してみると非常に高速(利用しているネットワークの速度からほとんど速度低下を感じない)かつ軽快な動作です。



参考サイト:https://github.com/adrianmihalko/raspberrypiwireguard

1. Wireguard のインストール (Raspberry Pi 2 v1.2 以降)


Raspibian には Wireguard はパッケージされていませんので、Debian から引っ張ってきます。

カーネルプロトコルなので、インストール後に OS の再起動をします。

pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get upgrade
pi@raspberrypi:~ $ sudo apt-get install raspberrypi-kernel-headers
pi@raspberrypi:~ $ echo "deb http://deb.debian.org/debian/ unstable main" | sudo tee --append /etc/apt/sources.list.d/unstable.list
pi@raspberrypi:~ $ sudo apt-get install dirmngr
pi@raspberrypi:~ $ sudo apt-key adv --keyserver   keyserver.ubuntu.com --recv-keys 8B48AD6246925553
pi@raspberrypi:~ $ printf 'Package: *\nPin: release a=unstable\nPin-Priority: 150\n' | sudo tee --append /etc/apt/preferences.d/limit-unstable
pi@raspberrypi:~ $ sudo apt-get update
pi@raspberrypi:~ $ sudo apt-get install wireguard
pi@raspberrypi:~ $ sudo reboot



IP フォワーディング設定をします。

pi@raspberrypi:~ $ sysctl net.ipv4.ip_forward
net.ipv4.ip_forward = 1


2. Wireguard を設定する


3. 項以降の設定をします。

WireGuard にはサーバーとクライアントという概念はなく、お互いがサーバーでありかつクライアントです。

つまり対等な扱いです。


接続しにいく側をイニシエーターといい、される方をレスポンダーといいます。

接続はどちらからでもよく、いつでもどちらもイニシエーターになり、他方がレスポンダーになります。

以下の設定ファイルは、自分の定義を [Interface] 、相手の定義を [Peer] として定義します。

便宜上、一般通念的にサーバーとクライアントと仮に呼びます。

端末側が「クライアント」、PC などが「サーバー」としておきます。


一般通念的には「クライアント」から「サーバー」に接続要求しますが、WireGuard はここでいうところの「サーバー」から「クライアント」へ接続要求できるのです。


蛇足的な説明でスミマセン。

以下は一般通念的な「サーバー」と「クライアント」として記述しているということです。


3. private / public keys を生成する(サーバーおよびクライアント用)


pi@raspberrypi:~ $ mkdir wgkeys
pi@raspberrypi:~ $ cd wgkeys 
pi@raspberrypi:~/wgkeys $ wg genkey > server_private.key 
Warning: writing to world accessible file.
Consider setting the umask to 077 and trying again.

pi@raspberrypi:~/wgkeys $ wg pubkey > server_public.key < server_private.key
pi@raspberrypi:~/wgkeys $ wg genkey > client1_private.key 
Warning: writing to world accessible file.
Consider setting the umask to 077 and trying again.

pi@raspberrypi:~/wgkeys $ wg pubkey > client1_public.key < client1_private.key
pi@raspberrypi:~/wgkeys $ ls
client1_private.key client1_public.key server_private.key server_public.key


cat コマンドで各キー等の中身を抽出します。
これらは後でサーバーおよびクライアントの設定で使用します。

pi@raspberrypi:~/wgkeys $ cat server_public.key
Aj2HHAutB2U0O56jJBdkZ/xgb9pnmUPJ0IeiuACLLmI= [文字列は一例]



4. Wireguard サーバーのインターフェース作成


pi@raspberrypi:~/wgkeys $ sudo leafpad /etc/wireguard/wg0.conf   
[Interface]
Address = 10.0.0.1/32
→ VPN の仮想アドレスを記述する
ListenPort = 1194 → 例では OpenVPN と同じ 1194 を使う設定にした
PrivateKey = [server_private.key] → cat コマンドで抽出した中身をペーストする

PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
#Client1
PublicKey =
[client1_public.key] → cat コマンドで抽出した中身をペーストする
AllowedIPs = 10.0.0.2/32


”Postup" で、起動時の wg0 インターフェースを eth0 にマスカレードします。
"Postdown" では停止時にマスカレードを削除します。


複数台のクライアントを許可する場合はそれぞれのクライアント用の public.key と private.key を client2, 3, … と生成し、[peer] セクションを追加します。

アドレスは例に従うと 10.8.0.3/32, 10.8.0.4/32, … と設定します。


5. Wireguard を起動する


pi@raspberrypi:~/wgkeys $ sudo wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip address add 10.0.0.1/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] ip route add 10.0.0.2/32 dev wg0
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -A FORWARD -o wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE


停止の場合は "sudo wg-quick down wg0" とします。



wg コマンドで動作状況を確認します。

pi@raspberrypi:~/wgkeys $ sudo wg
interface: wg0
  public key: [server_public.key]
  private key: (hidden)
  listening port: 1194

peer: [client1_public.key]
  allowed ips: 10.0.0.2/32



ラズパイ起動時に Wireguard を自動起動する設定をします。

pi@raspberrypi:~/wgkeys $ sudo systemctl enable wg-quick@wg0 
Created symlink /etc/systemd/system/multi-user.target.wants/wg-quick@wg0.service → /lib/systemd/system/wg-quick@.service.



6. クライアント側の設定


Android 端末の場合は、GooglePlay から Wireguard アプリをダウンロードして下記の設定をします。

いまは iOS 版もあるようです。







 → 任意の名前

 → [client1_private.key] を設定すると
   [client1_public.key] は自動的に設定される


→ client1 のアドレス

→ Google の DNS "8.8.8.8" でもよい




 → [server_public.key] を設定する



→ 自ネットのアドレス空間を併記する
 すべて VPN 経由時は 0.0.0.0/0とする

→ V6プラスの場合は4桁アドレスでもよい
(V6プラスはアドレスが変わらない)






Allowed IPs はすべてのパケットを VPN 経由とする場合には 0.0.0.0/0(ワイルドカード)を設定します。

特定の IP とのみ通信する場合は "10.0.0.1/32, 192.168.xxx.0/24" のように設定します。
この設定は VPN サーバーの仮想アドレスである "10.0.0.1" および自ネットのアドレス空間 "192.168.xxx.0/24" との間の通信を許可する、という意味になります。


例で示したプライベート IP と、VPN 仮想 IP のアドレスは、我が家のものとは異なっていて本記事用の架空のアドレスです。

同様に Endpont の DDNS 名とポート番号も本記事用の架空のものです。


自ネットが PPPoE でインターネット接続の場合は DDNS サービスを使ったほうがいいでしょう。

V6プラスの場合はアドレスはまず変わりませんので4桁の直接指定でもいいでしょう。



通常、ルーターとその配下は「クラス C」を使うことが多いと思います。
また、VPN 仮想アドレスは「クラス A」またはルーターとは 3 桁目が異なる「クラス C」が多いと思います。

iPhone のテザリング(ネットワーク共有)は「クラス B」のようですが。




ルーター及びその配下は 公共 WiFi での VPN 使用時にアドレス空間の競合を避ける必要があり、例えば、192.168.57.0/24 のように、3桁目は "0" や "1", "10", "11" などを避けた方がいいと思います。

実際にはコンビニ各社の場合はクラス A を割り当てているようです。




ルーター(我が家の場合は HGW : RT500KI で V6プラス)の静的NAPT 設定で、

対象プロトコル:UDP
公開対象ポート:12345(V6プラスで割り当てられたポートの一つ)
宛先アドレス :192.168.xxx.yyy(Raspberry Pi 3 のアドレス)
宛先ポート  :1194(任意ポート:ここでは OpenVPN のポートを使う設定を想定)


を設定して Wireguard への接続要求(ポート:12345)を Raspberry Pi3(許可されたポート:1194)へ振り向けるようにします。






クライアントから接続し、サーバー側とクライアント側それぞれから相手に ”ping -c 5 10.0.0.2”or “10.0.0.1”として相互に見えていることを確認します。



7. Firewall の設定



Firewall を以下のように設定します。

root@raspberrypi:~# ufw default deny
Default incoming policy changed to 'deny'
(be sure to update your rules accordingly)

root@raspberrypi:~# ufw allow in from 192.168.xxx.0/24
Rule added
root@raspberrypi:~# ufw allow in from 10.0.0.0/24
Rule added
root@raspberrypi:~# ufw allow 1194/udp → 通過許可設定

Rule added
Rule added (v6)

root@raspberrypi:~# ufw status numbered
Status: active

To Action From
-- ------ ----
[ 1] Anywhere ALLOW IN 192.168.xxx.0/24
[ 2] Anywhere ALLOW IN 10.0.0.0/24
[ 4] 1194/udp ALLOW IN Anywhere
[ 5] 1194/udp (v6) ALLOW IN Anywhere (v6) 




※※※ 留意事項


RealVNC サーバーの設定で、次の設定を追加します。

これをしないと VPN 動作時に PC (Mac) からRealVNC で Raspberry Pi 3に接続
できなくなってしまいます。

Raspberry Pi 3 の RealVNC の設定で Connections → Accept “192.168.xxx.0/24” を追加します。



また、ルーターで 10.0.0.0/24 からの外向きパケットを通過設定します。

これを忘れると端末からインターネットにアクセスできない、そもそもWireGuard での接続が不安定になる、Google FCM がエラーになってスリープで接続が切れる、などの事象に見舞われます。




Wireguard の導入と設定は OpenVPN よりも非常に簡単で、すぐに使えます。

また、速度的には VPN トンネル を張らない場合に比べても速度低下はほとんど感じられませんから、LTE 速度(またはフリー WiFi 速度)次第ということになります。


モバイルは LINE モバイルを使用しており、LTE 時でもストレスを感じることもなく VPN でのネットアクセスができます。


下記の画面は m.yahoo.co.jp にアクセスしてみた画面ですが、通知領域に鍵マークが通知されており、VPN 接続状態であることがわかります。

この画面は LTE => VPN ==トンネル==> 自宅ネット => "m.yahoo.co.jp" という経路でのアクセスになり、自宅ネットの保護下でのアクセスになります。


LTE で VPN 接続時の m.yahoo.co.jp の画面
































同様に、自宅のルーターにログインしてみました。

LTE 接続中ですが、VPN を自宅に向けて張っていますので、ログインできています。



自宅のルーターにログインしてみた画面
































このようなアクセス経路は、フリー WiFi でも同じです。


プライベート IP アドレスは自ネットワークのアドレスに合わせ、VPN で使用する仮想アドレスを適当に設定します。



フリー WiFi でどうなるかについて。

==>> 4月8〜9日に近所のコンビニで試しました。

結論的にいいますと、こちらもストレスなく VPN でネットアクセスできました。

クライアントの Allowed IPs は 0.0.0.0/0(ワイルドカード)設定しました。

WiFi の接続には NTTBP の「Japan Connected-free WiFi アプリ」によって接続しました。

フリーだからといっても直接接続するとうまくいきません。
「Japan Connected-free WiFi アプリ」による認証 OK で接続しないとダメなようです。

一度接続したことがあると「保存済みネットワーク」にあって、圏内になると自動的に接続されるのですが、これではうまく VPN で使えないようです。

また、VPN クライアントをオンのままでは WiFi 接続が失敗します。

こういう場合は、一旦 WiFi も VPN もオフにし「Japan Connected-free WiFi アプリ」を起動して「Connect」をクリックして接続するようにします。

「端末の WiFi 設定」→「SSID 接続」→「WiFi 認証」を経て接続完了になります。
この後で Wireguard VPN をオンにします。

あとは普通にウェブやその他のネットアクセス、自宅ネット内のアクセス等が可能になります。

下記コンビニのフリー WiFi はいずれも VPN は使えました。


 ❏ セブンイレブン(SSID=7SPOT) 
 ❏ ファミマ(SSID=Famima_WiFi)
 ❏ ローソン(SSID=LAWSON_Free_WiFi)



以下の画面は 7SPOT に VPN で接続されているのがおわかりでしょうか。


































この状態で m.yahoo.co.jp を閲覧した画面が下の画面です。
通知領域をご覧になると WiFi + VPN での閲覧画面であることが見て取れると思います。




































速度等はそのお店のネット環境に左右されますが、概ね 数 Mbps以上が出るようです。
いいときは 50 Mbps くらいのところもあります。

ping値は 20〜30ms 前後、ジッター値は 3ms 程度でパケロスはありません。

いずれの場合も Wireguard を使用して、ヤフー・ジャパンなどの一般サイトのウェブが問題なく行え、自宅のルーターや LAN-HDD などへのログインも問題なく行えます。

もちろん、ターミナルからの自宅サーバー等への ping や ssh も OK です。



その他のフリーWiFi での VPN はフィルタリングされていなくて使えるものと、逆に使えないものがあります。


フリーWiFi でこそ VPN が必要なのにこれが使えない WiFi は安心してインターネットを使えません。