LoginSignup
21
10

More than 3 years have passed since last update.

WireGuardでVPN接続を利用してプライベートネットワークにアクセスする

Last updated at Posted at 2020-12-06

はじめに

プライベートネットワークへ外部からVPNで繋げるようにしてみた。
VPNには最近流行りのWireGuardを用いた。

introduction.png

WireGuard

WireGuardは比較的新しいL3VPNプロトコル。
UDPベースで速いのが特徴。
しかも、設定がSSHの設定と同じくらい簡単だと謳っている。
たしかに、wgwg-quickのmanページを見ると、設定できるパラメータが少なくてシンプルなことがわかる。

環境

インターネット越しにプライベートネットワークへアクセスする。
詳細な構成は以下の通り。

  • サーバー
    • Ubuntu 18.04(Public IP付き)
  • クライアント
    • Ubuntu 18.04
    • Android

architecture.png

アクセスしたいサーバーのアドレスは172.16.6.1/24
プライベートアドレスなのでインターネットから直接アクセスすることはできない。
せっかくなのでAndroidからの接続も試した。

設定

クライアントだけでなくサーバーも公開鍵を作り、お互いの公開鍵を事前に知っておく必要があるのがSSHと違うところ。

サーバー (Ubuntu 18.04)

まずはインストールから。
昔はPPAの設定が必要だったが今はいらない。
/etc/apt/sources.listに以下のような記述があれば大丈夫。
universeの前後にmain, multiverse, restrictedのような単語が入っていても問題ない。
該当箇所が見つからない場合は以下の内容を追記する。

/etc/apt/sources.list
deb http://jp.archive.ubuntu.com/ubuntu/ bionic-updates universe

リポジトリの設定ができたらインストール。

sudo apt update
sudo apt install wireguard

次は鍵の作成。
rootで作業する。
秘密鍵は/etc/wireguard/privatekeyに保存され、公開鍵は/etc/wireguard/publickeyに保存される。

cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey

作った鍵を使ってサーバーのコンフィグ(/etc/wireguard/wg0.conf)を作成

/etc/wireguard/wg0.conf
[Interface]
ListenPort = 51820
PrivateKey = [さっき作成したサーバーのPrivate Key]
Address = 10.0.1.1/24

PostUp = ufw limit proto udp from any to [サーバーのPublic IP] port 51820
PostUp = ufw route allow in on %i out on [プライベートネットワークと接続しているインターフェース名]
PostUp = iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -d 172.16.6.0/24 -o [プライベートネットワークと接続しているインターフェース名] -j MASQUERADE
PostDown = ufw delete limit proto udp from any to [サーバーのPublic IP] port 51820
PostDown = ufw route delete allow in on %i out on [プライベートネットワークと接続しているインターフェース名]
PostDown = iptables -t nat -D POSTROUTING -s 10.0.1.0/24 -d 172.16.6.0/24 -o [プライベートネットワークと接続しているインターフェース名] -j MASQUERADE

[Peer]
PublicKey = [これから作成するUbuntuクライアントのPublic Key]
AllowedIPs = 10.0.1.2/32


[Peer]
PublicKey = [これから作成するAndroidクライアントのPublic Key]
AllowedIPs = 10.0.1.3/32
  • Address
    • WireGuardの起動時に作成されるwg0インターフェースに振るアドレス
    • 好きなPrivateアドレスを使えば良いが、NATの設定もそれに応じて変更する
  • PostUp, PostDown
    • ファイアウォール
      • ufw limit proto udp from any to [サーバーのPublic IP] port 51820
        • 外部からVPNサーバーにアクセスできるようにするための設定
    • NAT
      • iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -d 172.16.6.0/24 -o [プライベートネットワークと接続しているインターフェース] -j MASQUERADE
        • プライベートネットワーク(この場合は172.16.6.0/24)で通信するときにちゃんと送信元アドレスをそのサブネット内のアドレスにするための設定
    • IPフォワード
      • ufw route allow in on %i out on [外部と接続しているインターフェース]
        • wg0からインターフェースからのパケットが外へ出られるようにするための設定
      • カーネルの設定
        • IPフォワードは本当はカーネルの設定でも許可する必要がある
          • 今回はサーバーにdockerdが入っているので、カーネルの設定をする必要はない
          • dockerdデフォルトの設定では自動的に設定してくれる
        • dockerdが入っていない場合や明示的にdockerdのIPフォワードを無効化している場合は、echo 1 > /proc/sys/net/ipv4/ip_forwardでIPフォワードを有効化する必要がある
  • AllowedIPs
    • Peerへフォワードするサブネット
    • サーバ側の設定では対向のPeerのプライベートアドレスを書いておけば良い

クライアント (Ubuntu 18.04)

サーバーと同じようにWireGuardをインストールし、鍵を作成する。

sudo apt update
sudo apt install wireguard
# ここからroot
cd /etc/wireguard
wg genkey | tee privatekey | wg pubkey > publickey

作った鍵をもとにコンフィグ(/etc/wireguard/wg0.conf)を書く

/etc/wireguard/wg0.conf
[Interface]
ListenPort = 51820
PrivateKey = [いま作成したUbuntuクライントの秘密鍵]
Address = 10.0.1.2/24

[Peer]
PublicKey = [さっき作成したサーバーの公開鍵]
AllowedIPs = 10.0.1.0/24, 172.16.6.0/24
Endpoint = [サーバーのPublic IP]:51820
PersistentKeepalive = 15
  • AllowedIPs
    • サーバーとは設定が少し違う
    • WireGuardのVPNネットワークとプライベートネットワークとの通信を許可する
  • PersistendKeepAlive
    • NATの裏からクライアントがVPN接続した際に、接続が途切れないようにするための設定

最後に今作ったクライアントの公開鍵の情報をサーバーの/etc/wireguard/wg0.confに書き込む。

クライアント (Android)

一旦パソコンでコンフィグを書いて、QRで読み込むのが楽。
WireGuardとqrencodeがインストールしてあるパソコンなら何でもOK。

sudo apt update
sudo apt install wireguard qrencode
# ここからroot
cd /etc/wireguard
wg key | tee android_privatekey | wg pubkey > android_publickey

鍵を作成したらコンフィグを書く。
Ubuntuクライアントと異なる箇所はPrivateKeyAddress

/etc/wireguard/android.conf
[Interface]
ListenPort = 51820
PrivateKey = [いま作成したAndroidクライントの秘密鍵]
Address = 10.0.1.3/24

[Peer]
PublicKey = [さっき作成したサーバーの公開鍵]
AllowedIPs = 10.0.1.0/24, 172.16.6.0/24
Endpoint = [サーバーのPublic IP]:51820
PersistentKeepalive = 15

以下のコマンドで表示されたQRコードをAndroidから読み込む。
ターミナルにQR表示できるのすごい!

qrencode -t ansiutf8 < /etc/wireguard/android.conf 

こちらも、今作ったクライアントの公開鍵の情報をサーバーの/etc/wireguard/wg0.confに書き込むのを忘れずに。

接続

VPNをつなげて疎通を確認してみる。

サーバー (Ubuntu 18.04)

以下のコマンドでVPNサーバーを立ち上げる。
再起動時も自動で立ち上がる。

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

クライアント (Ubuntu 18.04)

こちらは常にVPN接続している必要がないのでenableしない。

systemctl start wg-quick@wg0

サーバーのPrivate IP(10.0.1.1)と疎通できるのが確認できる。
VPNはきちんと繋がっているのがわかる。

$ ping 10.0.1.1 -c 3
PING 10.0.1.1 (10.0.1.1) 56(84) bytes of data.
64 bytes from 10.0.1.1: icmp_seq=1 ttl=64 time=267 ms
64 bytes from 10.0.1.1: icmp_seq=2 ttl=64 time=267 ms
64 bytes from 10.0.1.1: icmp_seq=3 ttl=64 time=267 ms

--- 10.0.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 267.387/267.566/267.858/0.632 ms

次はプライベートネットワークとの疎通の確認。
UFWはデフォルトでICMPのフォワードを許可しているので、プライベートネットワークとの疎通はTCPで確認する。

$ mtr 172.16.6.1 -r -c 3 --tcp -P 22
Start: 2020-12-03T12:12:25+0200
HOST: XXXXXXXXXXX                 Loss%   Snt   Last   Avg  Best  Wrst StDev
  1.|-- 10.0.1.1                   0.0%     3  260.6 260.5 260.4 260.7   0.2
  2.|-- 172.16.6.1                 0.0%     3  261.2 261.2 261.1 261.3   0.1

クライアント (Android)

VPNの接続はトグルボタンを押すだけ。

wireguard-android.jpg

同様にサーバーのPrivate IP(10.0.1.1)と疎通できるのが確認できる。
このとき「トンネル対象アプリ」にPingのアプリを選択するのを忘れずに。

ping-android.jpg

TCPの疎通確認はUbuntuで試せたので割愛。

おわりに

VPN接続してプライベートネットワーク内のホストと通信できるのが確認できました。
Androidは設定をQRで読み込め、しかも、VPNで通信するアプリを選べるというのは便利ですね。

この記事を読んで「面白かった」「学びがあった」と思っていただけた方、よろしければ LGTM、Twitter や Facebook、はてなブックマークにてコメントをお願いします!

また DeNA 公式 Twitter アカウント @DeNAxTech では、 Blog 記事だけでなく色々な勉強会での登壇資料も発信しています。ぜひフォローして下さい!
Follow @DeNAxTech

21
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
10