WireGuardでVPNサーバーを構築してスマホやPCから接続する手順

公開日:2020/01/22 更新日:2020/01/22
WireGuardでVPNサーバーを構築してスマホやPCから接続する手順のサムネイル

はじめに

WireGuardはOpenVPNよりもシンプルで高速、より安全なVPNとして開発が進められており、OpenVPNに代わるVPNとして期待されています。端末間だけでなく拠点間のVPN接続にも対応しています。この記事ではWireGuardを使ってVPNサーバーを構築し、そのVPNサーバーにUbuntuやiPhoneから実際に接続してみるまでの手順をまとめます。 だいぶ前ですがOpenVPNサーバーを構築してUbuntuから接続しようとしたこともありましたが、設定が面倒だったり接続速度が遅かったりで結局使用しませんでした。ただ、WireGuardはまず設定がOpenVPNに比べて間違いなく簡単で、速度も十分です。さらにWireGuard公式のクライアントアプリがWindows、macOSに加えてiOS、Anrdoid用も配布されているので簡単に接続できます。

www.wireguard.com

WireGuard® is an extremely simple yet fast and modern VPN that utilizes state-of-the-art cryptography.

できるようになること

構築するシステムイメージ図が以下です。

wireguard-configuration.png

WireGuardを使用してクライアント(PC、スマホ)とサーバー間をVPN接続します。クライアントは全てのトラフィックをサーバー経由にしてインターネットに接続することができます。カフェや空港などの公衆WiFiを使用する場合にも役立ちます。 以降ではWireGuardのクライアントを単にクライアント、WireGuardのサーバーを単にサーバーと呼びます。 WireGuardのざっくりした仕組みとしては、サーバー側とクライアント側それぞれにWireGuardによるVPN接続用にネットワークインターフェースを追加し、それらを使ってVPN接続します。 そしてこれらは設定ファイルを作成すれば後はWireGuardがよしなにやってくれます。 なお、WireGuardはサーバーで生成した公開鍵をクライアント側で使用し、クライアント側で使用した公開鍵をサーバー側で使用します。そのためサーバー側とクライアント側で並列して作業が必要になります。以降で説明します。

前提と環境

以下の環境でWireGuardによるVPN接続を構築しました。

  • WireGuardサーバーOS : Ubuntu 18.04
  • WireGuardクライアントOS : Ubuntu 18.04、iOS(Windows、macOS、Android用の公式クライアントアプリも配布されています。)

WireGuardはまだ正式リリースに至っておらず、潜在的なバグを持っている可能性もあります。使用は自己責任でお願い致します。 ちなみに、WireGuardの公式ドキュメントでは、設定ファイルの作成をコマンドで順番に行っていく方法が説明されていますが、ここでは最初から設定ファイルを作成してそこに設定内容を記述していく方法を説明しています。やっていること自体は同じになります。

www.wireguard.com

You'll first want to make sure you have a decent grasp of the conceptual overview, and then install WireGuard. After that, read onwards here.

サーバー側での作業

ここではWireGuardのサーバーとしてUbuntu 18.04を使用します。

WireGuardをUbuntuにインストールする

以下でWireGuardをインストールします。

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

以上でWireGuardのインストールが完了です。

秘密鍵と公開鍵を作成する

WireGuardが使用する秘密鍵と公開鍵を以下のコマンドで同時に生成します。

$ wg genkey | tee privatekey | wg pubkey > publickey

上記を実行すると、実行時のディレクトリにprivatekeypublickeyの2つが生成されます。 秘密鍵privatekeyは決して誰とも共有してはいけないので、以下で権限を変更しておきます。

$ chmod 600 privatekey

なお、秘密鍵の中身を確認すると以下のようになっています。この値を次の設定ファイルの中で使用します。

$ cat privatekey
weohtowetu08230j2083j09203k9dALijF3h2KPA=

公開鍵は以下です。この値を次の設定ファイルの中で使用します。

$ cat publickey
geIEmgepi0123noige93jpt482jfALiei=

サーバー用のWireGuardの設定ファイルを作成する

以降の作業は全てroot権限が必要です。  続いて、/etc/wireguardwg0.confという設定ファイルを作成します。

$ sudo vi /etc/wireguard/wg0.conf

/etc/wireguard/wg0.confの中身を以下のようにします。

/etc/wireguard/wg0.conf
[Interface]
PrivateKey = weohtowetu08230j2083j09203k9dALijF3h2KPA=
Address = 10.0.0.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 = slwtj2o39jAofo428jAPJD8f038j20f=
AllowedIPs = 10.0.0.2/24

上記のうち[Interface]はサーバーの設定、Peerはサーバーに接続するクライアントに関する設定になります。[Interface]の設定項目は以下です。

項目 内容
PrivateKey サーバー側の秘密鍵。この記事ではweohtowetu08230j2083j09203k9dALijF3h2KPA=が該当。
Address VPN用のIPアドレス。WireGuardで構成するVPNにて、サーバー用に使用したい適当なアドレスを設定します。192.168.0.1/24などでもOK。ここでは10.0.0.1/24
ListenPort WireGuardがListenするポート番号。デフォルトが51820。他のポート番号でもOKですが、後ほどファイアウォールの設定で許可する必要があります。
SaveConfig trueにすることでWireGuardの起動時、停止時にこの設定ファイルの内容を保存します。
PostUp, PostDown WireGuardの起動直前(PostUp)、停止直前(PostDown)に実行する処理を記述します。ここでは、WireGuardの起動、停止それぞれの直前にiptablesのフォワーディング用の設定を追加しています。上記のiptablesルール内にあるeth0は私のサーバーの外部IP(WAN側IP)を持つインターフェースです。各自置換してください
[Peer]の設定項目は以下です。
項目 内容
PublicKey サーバーに接続するクライアント側で生成した公開鍵。ここではslwtj2o39jAofo428jAPJD8f038j20f=が該当。これはクライアント側で生成するものになります。
AllowedIPs サーバーへの接続を許可するクライアントのVPN用のIPアドレス。これも次節で説明します。

上記を保存して最後に設定ファイルの権限も変更して完了です。

$ sudo chmod 600 wg0.conf

iptablesもしくはufwでポート番号を許可する

iptablesやufw等のファイアウォールを使用している場合は、それらにてWireGuardが使用するポート(UDP)を許可する必要があります。WireGuardのデフォルトのポート番号51820をiptablesで許可する場合は、以下のルールを追加してください。

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

ufwの場合は以下でルールを追加できると思います。

$ sudo ufw allow 51820/udp

フォワーディングを許可する

WireGuardのサーバー側でクライアント側のトラフィックを受けてインターネットに流すには、サーバー側でフォワーディングを有効化しておく必要があります。 Ubuntuの場合は、/etc/sysctl.confを編集することでフォワーディングを有効化できます。具体的には/etc/sysctl.confの以下の部分を非コメント化します。

/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 # 先頭の#を消して非コメント化する

上記を上書きした後、以下で変更を反映させます。

$ sudo sysctl -p

これでフォワーディングが許可されました。

WireGuardサーバーを起動、停止する

WireGuardサーバーを起動するには、wgコマンドを使用して以下のようにします。

$ sudo wg-quick up /etc/wireguard/wg0.conf

以降は以下でも起動できます。

$ sudo wg-quick up wg0

上記を実行すると、ネットワークインターフェースとしてwg0が作成され、クライアントからの接続を待機する状態になります。ipコマンドを使用して確認すると、wgが追加されていることを確認できます。

$ ip addr

停止する場合はwg-quick downを使用します。

$ sudo wg-quick down wg0

クライアント側での作業

Ubuntuをクライアントとして使用する場合の作業

ここでは、Ubuntu 18.04をクライアントとして使用します。iOSをクライアントとして使用する場合の方法は後述します。 サーバー側で行った作業と同じように以下でWireGuardをインストール、秘密鍵と公開鍵の生成、権限の設定を行います。

$ sudo add-apt-repository ppa:wireguard/wireguard
$ sudo apt-get update
$ sudo apt-get install wireguard
$ wg genkey | tee privatekey | wg pubkey > publickey
$ chmod 600 privatekey

秘密鍵の中身を確認します。

$ cat privatekey
Sk9joFowprh80DSoehg98Ahgeiywg=

公開鍵の中身を確認します。

$ cat publickey
slwtj2o39jAofo428jAPJD8f038j20f=

この値は前節で説明したサーバー側の設定ファイル/etc/wireguard/wg0.conf内の[Peer]PublicKeyで指定します。

クライアント用の設定ファイルを作成する

サーバー側と同様にクライアント側でも設定ファイルを作成します。

/etc/wireguard/wg0.conf
[Interface]
PrivateKey = Sk9joFowprh80DSoehg98Ahgeiywg=
Address = 10.0.0.2/32

[Peer]
PublicKey = geIEmgepi0123noige93jpt482jfALiei=
Endpoint = 160.200.2.1:51820
AllowedIPs = 0.0.0.0/0,::/0

クライアント側の設定ファイルはサーバー側よりも少ない内容です。以下が[Interface]部分の設定項目です。

項目 内容
PrivateKey クライアント側の秘密鍵。ここではSk9joFowprh80DSoehg98Ahgeiywg=が該当。
Address VPN用のIPアドレス。WireGuardで構成するVPNにて、クライアント用に使用したい適当なアドレスを設定します。ここでは10.0.0.2/24
[Peer]部分の設定項目は以下です。
項目 内容
PublicKey サーバー側で生成した公開鍵。ここではgeIEmgepi0123noige93jpt482jfALiei=が該当。
Endpoint 接続先となるWireGuardサーバーの外部IP(WAN側IP)。ポート番号も指定する。
AllowedIPs WireGuard経由にするIPアドレスの範囲。0.0.0.0/0(IP6では::/0)を指定すると、クライアント側の全てのトラフィックをWireGuard宛にします。すなわちサーバーを経由させます。もしここで10.0.0.0/24のように特定のIPアドレス範囲を指定すれば、そのIPアドレス範囲に含まれる宛先トラフィックのみWireGuardサーバーに転送します。

クライアントからサーバーに接続する

WireGuardサーバーを起動した時と同じで、wgコマンドを使用して以下のようにします。

$ sudo wg-quick up /etc/wireguard/wg0.conf

上記を実行してWireGuardのネットワークインターフェースwg0が作成された時点でサーバーと接続します。 試しにサーバー側のVPN用IP10.0.0.1にpingを打てば応答が返ってきます。

$ ping 10.0.0.1

また、試しにIPアドレスを表示しくれるWebサイト等にアクセスしてみると、クライアントのIPではなくサーバーのIPが表示されると思います。

停止する場合はwg-quick downを使用します。

$ sudo wg-quick down wg0

なお、WireGuardのサーバーとしてVPS等を使用している場合は、必ずVPSに対するトラフィック制限や規約等を確認してください。上記の設定はクライアントのトラフィックを全てサーバー経由にするため、クライアント側で大量にネットワークを使用すると、当然ながらサーバー側でも同じだけネットワークを消費します。公衆WiFiに接続している時だけ使用するようにするなど各自の状況に合わせて使用してください。

iPhoneからWireGuardサーバーに接続する

iOSとAndroidそれぞれでWireGuardの公式クライアントアプリが用意されています。iOSの場合はApp Storeで検索すると以下のような感じです。

wireguard-in-app-store.png

これをインストールして起動すると以下のような画面が開きます。「Add a tunnel」をクリックして新しいVPN接続を追加します。

add-tunnel.png

「Add a tunnel」をクリックすると、以下のように設定方法のメニューが表示されます。

create-menu.png

設定ファイル、QRコード、手動での設定がそれぞれ可能です。

項目 内容
Create from file or archive 設定ファイルから作成
Create from QR code QRコードから作成
Create from Scratch ゼロから手動で各項目を入力して作成

1番簡単なのは「Create from QR code」です。もしクライアントとしてUbuntuを使っていれば、qrencodeを使用して作成済の設定ファイルをQRコード化し、それを「Create from QR code」を選択して開いたカメラで読み取ればOKです。 Ubuntuの場合qrencodeaptでインストールできます。

$ sudo apt install qrencode

後は以下で設定ファイルからQRコードを生成します。

$ sudo qrencode -t ansiutf8 < /etc/wireguard/wg0.conf

その他のOS用のクライアントアプリについては以下の公式ドキュメントを見てみてください。

www.wireguard.com

Installation

WireGuardの状態を確認する

wgコマンドで以下を使用することで追加したWireGuardのネットワークインターフェースのステータスを確認できます。

$ sudo wg show
interface: wg0
  public key: geIEmgepi0123noige93jpt482jfALiei=
  private key: (hidden)
  listening port: 51820

peer: slwtj2o39jAofo428jAPJD8f038j20f=
  endpoint: 172.65.16.202:43741
  allowed ips: 10.0.0.2/32
  latest handshake: 19 hours, 34 minutes, 14 seconds ago
  transfer: 1.12 MiB received, 2.94 MiB sent

WireGuard経由でインターネットに接続できない場合

2020/2/16 追記

上記までに記載した方法でWireGuardでインターネットに接続できていたものの、誤ってクライアント側のWireGuardの設定ファイルを削除してしまいました。そして全く同じ手順で設定し、WireGuardサーバーに接続できたもののWebサイトを表示できない状態になりました。調べてみるとPingは外部にも届いていましたが、DNSサーバーが分からずに名前解決できない状態になっていました。対策としては、クライアント側の設定ファイルに以下のようにDNSを指定する記述を追記しました。

/etc/wireguard/wg0.conf
[Interface]
PrivateKey = Sk9joFowprh80DSoehg98Ahgeiywg=
Address = 10.0.0.2/32
DNS = 8.8.4.4 # 追記

[Peer]
PublicKey = geIEmgepi0123noige93jpt482jfALiei=
Endpoint = 160.200.2.1:51820
AllowedIPs = 0.0.0.0/0,::/0

以下でWireGuard用のインターフェースを再起動します。

$ sudo wg-quick down wg0
$ sudo wg-quick up /etc/wireguard/wg0.conf

なお、もし再起動した際に以下のようにresolvconf: command not foundというエラーが出る場合があります。

$ sudo wg-quick up /etc/wireguard/wg0.conf
[#] ip link add configfile type wireguard
[#] wg setconf configfile /dev/fd/63
[#] ip link set mtu 1420 dev configfile
[#] ip link set configfile up
[#] resolvconf -a configfile -m 0 -x
/usr/bin/wg-quick: line 31: resolvconf: command not found
[#] ip link delete dev configfile

これは、WireGuardが内部で使用しようとしたresolvconfコマンドが見つからないことが原因なので、以下でインストールすれば解決します。

$ sudo apt install openresolv

これについては、トラブルシューティング - ArchLinux wikiに記載れており参考になりました。

DNSについての設定がWireGuardの設定ファイルになくても、元々パブリックなDNSサーバーを使っていたり、DNSサーバーについてルーティング設定を行っていればこの状態にはなりませんが念の為メモしておきます。

参考文献

以下の記事が大変参考になりました。

wiki.archlinux.jp

Wireguard は最先端の暗号技術を使用する非常にシンプルで高速な VPN です。

angristan.xyz

Learn how to setup your own Wireguard server, the new fast and modern VPN protocol!

github.com

Wireguard VPN - Forward all traffic to server

まとめ

WireGuardを使ったVPNサーバーの構築手順と実際にクライアントから接続するまでの手順をまとめました。OpenVPN等に比べて遥かに簡単に構築できます。

関連記事

開発アプリ

nanolog.app

毎日の小さな出来事をなんでも記録して、ログとして残すためのライフログアプリです。