SummerWind

Web, Photography, Space Development

BoringTun で WireGuard を使う

Cloudflare が先日公開した WireGuard の Rust 実装である BoringTun を使って VPN 接続できるかを検証した。WireGuard 自体使うのが初めてだったが、結果としてはうまく接続できた。

ネットワーク構成

以下のような構成で仮想マシンを構築し、client から hidden に VPN を介して接続する。今回は server が WireGuard サーバーになり、client が WireGuard クライアントになる。

+---------------+    +---------------+    +---------------+
| client        |    | server        |    | hidden        |
| 192.168.10.12 |<-->| 192.168.10.11 |    |               |
|               |    | 192.168.20.11 |<-->| 192.168.20.12 |
+---------------+    +---------------+    +---------------+

セットアップ

各マシンのセットアップをしていく。今回は全てのマシンで Ubuntu 18.04 を使用する。

まず最初に hidden サーバーに以下のようにして nginx をインストールしておく。hidden サーバーのセットアップはこれで完了。

$ sudo apt update
$ sudo apt install -y nginx

次に、serverclient で以下のようにして、WireGuard をパッケージをインストールする。このパッケージで WireGuard のカーネルモジュールがインストールされるので、これだけで WireGuard 自体は利用可能だったりするのだけど、今回はあえてさらに BoringTun を使ってみる。

$ sudo add-apt-repository ppa:wireguard/wireguard
$ sudo apt install -y wireguard-tools

次に BoringTun をビルドするために、Rust をインストールする。

$ curl https://sh.rustup.rs -sSf | sh
$ source $HOME/.cargo/env

Rust のインストールが完了したら、BoringTun をビルドしてインストールする。

$ git clone https://github.com/cloudflare/boringtun
$ cd boringtun
$ cargo build --bin boringtun --release
$ sudo cp ./target/release/boringtun /usr/local/bin/boringtun

最後に WireGuard で利用する鍵ペアを生成しておく。serverclient でそれぞれ別の鍵ペアを生成する必要があることに注意する。

$ umask 077
$ wg genkey | tee private-key | wg pubkey > public-key

これで全てのマシンのセットアップが完了した。

WireGuard サーバーの起動

つづいて、server で WireGuard サーバーを起動する。デバイス名 wg0 を指定して boringtun コマンドを起動する。

$ sudo /usr/local/bin/boringtun wg0

次に WireGuard のデバイスを設定する wg コマンドを使用して、接続情報を次のように設定する。${CLIENT_PUBLIC_KEY} には client で生成した公開鍵の値 (ファイルパスではなく値であることに注意) を指定する。allowed-ips の値は client の WireGuard デバイスに付与する IP アドレスを指定する。

$ sudo wg set wg0 \
    listen-port 51820 \
    private-key private-key \
    peer "${CLIENT_PUBLIC_KEY}" \
    allowed-ips 172.16.1.2/32

設定が正しく反映されているかは wg コマンドで確認できる。

interface: wg0
  public key: lbwK4p0cLAqFaHFJSkOLkq0geLukzEMZdHWOnn5dLnc=
  private key: (hidden)
  listening port: 51820

peer: S9TZo5n6X+/NEaXPwYTe2NS84Tp69a7CHAsSB8N3JGQ=
  allowed ips: 172.16.1.2/32

WireGuard の設定が完了したら、デバイスに IP アドレスを付与して起動する。

$ sudo ip addr add 172.16.1.1/24 dev wg0
$ sudo ip link set up wg0

今回 serverhidden への通信を中継するので、IP マスカレードを有効にしておく。wg0 で受けたパケットを enp0s9 に転送する場合は以下のようになる。このあたりの設定はネットワーク構成によって変わってきそう。

$ sudo sh -c 'echo 1 > /proc/sys/net/ipv4/ip_forward'
$ sudo iptables -A FORWARD -i wg0 -j ACCEPT
$ sudo iptables -t nat -A POSTROUTING -o enp0s9 -j MASQUERADE

これで WireGuard サーバーとして使えるようになった。

WireGuard クライアントの接続

最後に client から server の WireGuard サーバーに接続する。サーバーと同様に、まず boringtun コマンドを起動する。

$ sudo /usr/local/bin/boringtun wg0

次に wg コマンドを使用して、クライアント用の設定をする。サーバーとは反対に ``${SERVER_PUBLIC_KEY} に *server* の公開鍵の値を指定する。allowed-ips には *server* の先にいるネットワーク IP アドレスを指定しておく。endpoint` には WireGuard サーバーのアドレスを指定する。

$ sudo wg set wg0 \
    private-key private-key \
    peer "${SERVER_PUBLIC_KEY}" \
    allowed-ips 0.0.0.0/0 \
    endpoint 192.168.10.12:51820

wg コマンドを実行して設定した内容を確認しておく。

$ sudo wg
interface: wg0
  public key: S9TZo5n6X+/NEaXPwYTe2NS84Tp69a7CHAsSB8N3JGQ=
  private key: (hidden)
  listening port: 32958

peer: lbwK4p0cLAqFaHFJSkOLkq0geLukzEMZdHWOnn5dLnc=
  endpoint: 192.168.10.12:51820
  allowed ips: 0.0.0.0/0

設定が完了したら、デバイスに IP アドレスを付与して起動する。

$ sudo ip addr add 172.16.1.2/24 dev wg0
$ sudo ip link set up wg0

デバイスが起動したら、wg0 デバイス経由で、WireGuard サーバーに接続できる。

$ ping 172.16.1.1
PING 172.16.1.1 (172.16.1.1) 56(84) bytes of data.
64 bytes from 172.16.1.1: icmp_seq=2 ttl=64 time=0.757 ms
64 bytes from 172.16.1.1: icmp_seq=3 ttl=64 time=0.631 ms
...

clienthidden サーバーのネットワークに対するルーティング情報を持たないので、以下のようにして設定する。

$ sudo ip route add 192.168.20.0/24 via 172.16.1.2

hidden サーバーの nginx に HTTP リクエストを送信すると、WireGuard 経由でレスポンスを取得できた。

$ curl --head http://192.168.20.12
HTTP/1.1 200 OK
Server: nginx/1.14.0 (Ubuntu)
Date: Mon, 08 Apr 2019 12:18:47 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Mon, 08 Apr 2019 12:17:50 GMT
Connection: keep-alive
ETag: "5cab3bee-264"
Accept-Ranges: bytes

まとめ

BoringTun を使って WireGuard による VPN 環境を構築できた。BoringTun はまだ荒削りな印象がものの、ユーザー空間で動作するので WireGuard クライアントとして利用するとよさそう。ただ自前ビルドが面倒なので公式リリースに期待したい。WireGuard はシンプルな仕組みで使い勝手がいいことが分かったので今後も使っていきたい。コンテナとの相性もよさそうだ。

Moto Ishizawa

Moto Ishizawa
ソフトウェアエンジニア。ロケットの打上げを見学するために、たびたびフロリダや種子島にでかけるなど、宇宙開発分野のファンでもある。