Ubuntu に WireGuard VPN サーバー 構築した

network server ubuntu

Ubuntu に WireGuard で VPN サーバーをたててみます。
OpenVPN とかよりパフォーマンスがよさそうなので。

WireGuard は apt ではいるけど、
18.04 だとリポジトリを追加する必要があるみたい。
(20.04 とかならいらないっぽい。)

$ sudo add-apt-repository ppa:wireguard/wireguard
$ sudo apt update
$ sudo apt install wireguard

これでインストールはおわり。設定をしていく。
まずはサーバー。

$ wg genkey | sudo tee server.key | wg pubkey > server.pub

これで秘密鍵と公開鍵がいっきにつくれます。
wg genkeywg pubkey も標準出力されるから、
べつにファイルにしておかなくてもいいんだけど、念のためファイルにとっといた。
そしていちおう秘密鍵はパーミッションをおとしておく。

$ sudo chmod 600 server.key 
$ cat server.key 
ENW7kA3J8+oT0rcBYUihqsMTPHc2DDLq7ihVcOFvlFE=
$ cat server.pub 
Zu4yboEsvujtgtbFQFQCqk4kfMVUzqjrjG5+wUrQ3CM=

いちおう鍵はこんなかんじになっている。これは設定ファイルでつかいます。

つぎはクライアント。こんかいは Mac から接続する。
まずは Homebrew で WireGuard をインストールする。
Homebrew のいれかたはじぶんでしらべてね。

% brew install wireguard-tools

そしてサーバーとおなじように鍵をつくる。

% wg genkey | sudo tee client.key | wg pubkey > client.pub
$ cat client.key
aDca+QPHgp/wGNF2aTX+oclSEgtwfKGso+/2LVcJXXk=
$ cat client.pub
IL3SJUe3I9dNj4MzspOL9WaDQip/43yhtDz13jFkgzI=

パーミッションもいちおうおとす。

% sudo chmod 600 client.key

サーバーにもどって、設定ファイルを用意します。
/etc/wireguard/ に、今回は wg0.conf というファイル名でつくります。
wg0.conf の部分はつくりたいインターフェイス名でもいいけどね。

sudo vi /etc/wireguard/wg0.conf

中身はこんなの。

[Interface]
PrivateKey = ENW7kA3J8+oT0rcBYUihqsMTPHc2DDLq7ihVcOFvlFE=
Address = 192.168.1.1/24
ListenPort = 51820
SaveConfig = true
PostUp = iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; ip6tables -A FORWARD -o %i -j ACCEPT; ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; ip6tables -D FORWARD -o %i -j ACCEPT; ip6tables -t nat -D POSTROUTING -o eth0 -j MASQUERADE

[Peer]
PublicKey = IL3SJUe3I9dNj4MzspOL9WaDQip/43yhtDz13jFkgzI=
AllowedIPs = 192.168.1.2/24

[Interface] はサーバーの設定で、 [Peer] はクライアントの設定です。
今回は WireGuard に 192.168.1.0/24 のサブネットを割り当てて、
サーバーのインターフェイスに 192.168.1.1
クライアントに 192.168.1.2/24 を割り当てることにする。 

PostUpPostDown は WireGuard が起動しているあいだだけ、
iptables の IP マスカレードをする設定です。
eth0 は適宜じぶんの物理インターフェイスにかきかえてください。

[Peer]PublicKey はクライアントの公開鍵です。

いちおう、設定ファイルのパーミッションもおとしておく。

$ sudo chmod 600 wg0.conf

つぎは WireGuard のネットワークから、
インターネットへトラフィックをながす設定をします。
Ubuntu はデフォルトでパケットのフォワーディングを禁止しているので、
/etc/sysctl.conf を編集しておく。

$ sudo vi /etc/sysctl.conf

該当のばしょのコメント化を解除する。

# Uncomment the next line to enable packet forwarding for IPv4
net.ipv4.ip_forward=1
# Uncomment the next line to enable packet forwarding for IPv6
# Enabling this option disables Stateless Address Autoconfiguration
# based on Router Advertisements for this host
net.ipv6.conf.all.forwarding=1

そして sysctl コマンドで変更を反映させます。

$ sudo sysctl -p
net.ipv4.ip_forward = 1
net.ipv6.conf.all.forwarding = 1

iptables または ufw のファイアウォールをつかっているばあいは、
ポート番号の許可もしておきます。

$ sudo iptables -A INPUT -p udp --dport 51820 -j ACCEPT

ufw だったら以下ね。

$ sudo ufw allow 51820/udp

あとは、じっさいに WireGuard を起動していきます。
起動と停止には、 wg-quick というラッパースクリプトをつかうよ。
systemd のユニットファイルは wg-quick@インターフェイス名 です。

$ sudo systemctl enable wg-quick@wg0
$ sudo systemctl start wg-quick@wg0

ip コマンドでインターフェイスが生成されていることを確認します。

$ ip a
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1200 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none 
    inet 192.168.1.1/24 scope global wg0
       valid_lft forever preferred_lft forever

これでサーバー側は完了です。おつかれさま。
…といいたいところだけど、以下のようなエラーがでることがある。

$ sudo systemctl start wg-quick@wg0
Job for [email protected] failed because the control process exited with error code.
See "systemctl status [email protected]" and "journalctl -xe" for details.

だいたいの場合、 WireGuard のカーネルモジュールがロードされていない。
以下のコマンドを実行してみる。

$ sudo modprobe wireguard

エラーがでるなら、いったん再起動をしてみよう。だいたいなおる。
ぼくはなおりました。

それじゃ、 App Store で WireGuard クライアントをダウンロードしてきて、接続してみる。

Add Empty Tunnel... から設定をかきこむ。

[Interface]
PrivateKey = aDca+QPHgp/wGNF2aTX+oclSEgtwfKGso+/2LVcJXXk=
Address = 192.168.1.2/32
DNS = 1.1.1.1

[Peer]
PublicKey = Zu4yboEsvujtgtbFQFQCqk4kfMVUzqjrjG5+wUrQ3CM=
Endpoint = example.com:51820
AllowedIPs = 0.0.0.0/0,::/0

サーバーとくらべると、だいぶシンプルね。

[Interface]PublicKey はさいしょのほうにつくった秘密鍵、
[Peer]PublicKey はサーバーの公開鍵です。

DNS のところは Cloudflare の Public DNS を指定してみたけど、
Google の 8.8.8.8 でもいいし、 LAN 内のやつでもよいです。

AllowedIPs を上記のようにすると、すべてのトラフィックをサーバーにながします。
もちろん 10.0.0.0/24 のように、特定の宛先を指定してもよいです。

保存をして Activate ボタンを押せば Handshake がおこなわれて接続されます!
おつかれさまでした。
やったね!!