WireGuard をつかってみる

今[話題](https://twitter.com/majek04/status/1025111540381495296)の Wireguard を使ってみます。
詳しい中身は[Fadis さんの発表「作って理解するWireGuard」](https://www.youtube.com/watch?v=grDEBt7oQho)を見るのがいいんじゃないでしょうか。



# 構成

今回構築してみる構成は物凄く雑ですが以下のような感じ。

![](https://d2mxuefqeaa7sj.cloudfront.net/s_9F15B12200700102896D288515E314569B24CD7D06AF39A9A239037C77F35B53_1533312135188_wireguard.png)

# Setup
## Server-side

サーバ側は RaspberryPi で OS は Raspbian (stretch) で動作しているものとして仮定します。
Raspbian では Wireguard のパッケージがないので、Debian のものを利用します。


    $ curl https://ftp-master.debian.org/keys/archive-key-9.asc | sudo apt-key add -

まず、Debian のパッケージ署名に利用されている鍵を追加します。


    $ sudo apt update
    $ sudo apt install wireguard

**鍵の生成**

    $ wg genkey | tee privatekey | wg pubkey > publickey
    $ cat publickey
    MI0xoT46YvrlpudVEMC0zNTSvhFydLZsTTB+a64WPHA=
    $ cat privatekey
    4HtcVyAy2sk7jiTcFI7hmFkbEmEd99XK7TKbQrMUiHQ=

**Add wireguard device**


    ＄ sudo ip link add dev wg0 type wireguard

**Create wireguard configuration**

    $ cat <<EOF > /etc/wireguard/wg0
    [Interface]
    ListenPort = 51823
    PrivateKey = 4HtcVyAy2sk7jiTcFI7hmFkbEmEd99XK7TKbQrMUiHQ=
    
    [Peer]
    PublicKey = L/lfwlWKAATzPXf8ZAarLEtq/g0bqh2jXTxbJpVmCg4=
    AllowedIPs = 172.16.0.0/31, 192.168.0.0/24
    EOF

ここで指定している、`PrivateKey` はServer sideのもので、`PublicKey` は Client side のものです。
後程記述しますが、Client sideでも同様に鍵の生成を行います。

`AllowedIPs` は、ここで指定したレンジが Wireguard で通信できる IP アドレスレンジになります。

**Set wireguard config**


    $ sudo wg setconf wg0 /etc/wireguard/wg0

**Linkup**

    $ sudo ip addr add 172.16.0.0/31 dev wg0
    $ sudo ip link set up wg0

172.16.0.0/31 は Point-to-point な接続でのみで利用します。

**(Optional) NATの設定**

    $ sudo iptables -t nat -A POSTROUTING -o eth0 -s 172.16.0.0/31 -j MASQUERADE

必要に応じて、内部ネットワークへ接続するときはNATするとか行います。
設定をしている機器がルータであれば、特に必要ないかなと思います。


これでサーバ側のセットアップは完了です。


## Client-side

Client は Gentoo Linux で動作しているものとします。
Gentoo には `net-vpn/wireguard` というパッケージが用意されていますので、`emerge` コマンドでコマンドラインツールや、カーネルモジュールをインストールすることができます。


    $ sudo emerge net-vpn/wireguard

**鍵の生成**

    $ wg genkey | tee privatekey | wg pubkey > publickey
    $ cat publickey
    MI0xoT46YvrlpudVEMC0zNTSvhFydLZsTTB+a64WPHA=
    $ cat privatekey
    IPHWHdwUx3wYwUJAOUtKLZEE/XmCFPmdXPVRTStf20E=

**Add wireguard device**


    ＄ sudo ip link add dev wg0 type wireguard

**Create wireguard configuration**


    $ cat <<EOF > /etc/wireguard/wg0
    [Interface]
    ListenPort = 51823
    PrivateKey = IPHWHdwUx3wYwUJAOUtKLZEE/XmCFPmdXPVRTStf20E=
    
    [Peer]
    PublicKey = MI0xoT46YvrlpudVEMC0zNTSvhFydLZsTTB+a64WPHA=
    AllowedIPs = 172.16.0.0/31, 192.168.0.0/24
    Endpoint = 192.0.2.1
    PersistentKeepalive = 25
    EOF

`Endpoint` で指定するアドレスはサーバのグローバルIPアドレスです。

**Set wireguard config**


    $ sudo wg setconf wg0 /etc/wireguard/wg0

**Link up**


    $ sudo ip addr add 172.16.0.1/31 dev wg0
    $ sudo ip link set up wg0

**Add route**
内部ネットワークである 192.168.0.0/24 は wg0 経由で通信することになります。
そのために必要なルートをルートテーブルに追加します。


    $ sudo ip route add 192.168.0.0/24 via 172.16.0.0



## Test connectivity

**Client to Server**

    $ ping -c 4 172.16.0.0
    PING 172.16.0.0 (172.16.0.0) 56(84) bytes of data.
    64 bytes from 172.16.0.0: icmp_seq=1 ttl=64 time=122 ms
    64 bytes from 172.16.0.0: icmp_seq=2 ttl=64 time=138 ms
    64 bytes from 172.16.0.0: icmp_seq=3 ttl=64 time=137 ms
    64 bytes from 172.16.0.0: icmp_seq=4 ttl=64 time=126 ms
    
    --- 172.16.0.0 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3003ms
    rtt min/avg/max/mdev = 122.268/131.354/138.562/7.090 ms

**Client to Internal Network**

    $ ping -c 4 192.168.0.1
    PING 192.168.0.1 (192.168.0.1) 56(84) bytes of data.
    64 bytes from 192.168.0.1: icmp_seq=1 ttl=63 time=186 ms
    64 bytes from 192.168.0.1: icmp_seq=2 ttl=63 time=134 ms
    64 bytes from 192.168.0.1: icmp_seq=3 ttl=63 time=124 ms
    64 bytes from 192.168.0.1: icmp_seq=4 ttl=63 time=123 ms
    
    --- 192.168.0.1 ping statistics ---
    4 packets transmitted, 4 received, 0% packet loss, time 3004ms
    rtt min/avg/max/mdev = 123.024/142.028/186.595/26.095 ms