2021年11月8日月曜日

WireGuardを使って自宅にVPN接続する方法

自宅環境ではインターネット経由でVPN接続をできるように、QNAP NASのQVPN Serviceの機能を利用してOpenVPNサーバを構築している。OpenVPNによる接続手順は以下記事にて記載している。

最近はWireGuardと呼ばれる比較的新しいOSSのVPNソフトウェアが存在する。ソースコードが4,000行程度と非常にコンパクトで、Linuxのカーネルモジュールとして動作するという特徴がある。

QNAP NASの最新OSであるQTS 5.0.0でもWireGuardによるVPN接続がサポートされたとのことだが、残念ながらx86のCPUのみ利用可能となっており、私のQNAP TS-231Pでは対応していなかった。

そこで、今回はWireGuardをLinux上に構築し、Windows用のWireGuardクライアントからインターネット越しに自宅にVPN接続する手順を記載する。

環境

今回はRHELクローンであるAlmaLinuxにて構築を行ったが、CentOSや本家RHELでも同様の手順で構築できるだろう。なお、8.xと9.xのOSにおいて一部手順に差異がある。

  • OS : AlmaLinux 8.3、AlmaLinux 9.2

なお、スマホからもWireGuardでVPN接続は可能であり、設定方法は別記事「WireGuardを使ってスマホから自宅にVPN接続する」を参照いただきたい。

WireGuard構築手順 (Linux)

1. パッケージのインストール

今回はRed Hat系LinuxにおけるWireGuardの構築手順となる。その他のディストリビューションにおける構築手順は、以下公式サイトの内容を確認いただきたい。

WireGuardは、RHEL 8.xはEPELのリポジトリに用意されており、RHEL 9は通常のリポジトリ存在する。したがって、dnfyumを用いてパッケージによるインストールが可能となる。注意点として、RHEL 8.xの場合は、一度OSを再起動しなければ以降の手順でエラーとなるため注意すること(RHEL 9.xの場合は再起動は不要)。

★RHEL 8.xの場合
# dnf install elrepo-release epel-release -y
# dnf install kmod-wireguard wireguard-tools -y
# reboot
★RHEL 9.xの場合
# dnf install wireguard-tools -y

以下に、RHEL 8.xのパッケージインストール後にリブートしなかった場合のエラー情報を参考までに記載する。WireGaurd用のインタフェースを作成しようとしても、以下の通りError: Unknown device typeにてエラーとなる。

# ip link add dev wg0 type wireguard
Error: Unknown device type.
# modprobe wireguard
modprobe: FATAL: Module wireguard not found in directory /lib/modules/4.18.0-240.el8.x86_64

2. サーバ用の秘密鍵と公開鍵を作成

WireGuardは、サーバもクライアントも必ず秘密鍵と公開鍵のペアを設定する必要がある。wgコマンドにて鍵作成をすることができるたため、以下の通りサーバとクライアント用の鍵を作成する。

ファイル名 説明
wgserver.key サーバ用秘密鍵
wgserver.pub サーバ用公開鍵
wgclient.key クライアント用秘密鍵
wgclient.pub クライアント用公開鍵
# cd /etc/wireguard
# wg genkey > wgserver.key
# wg pubkey < wgserver.key > wgserver.pub
# wg genkey > wgclient.key
# wg pubkey < wgclient.key > wgclient.pub

# chmod 600 wgserver.key
# chmod 600 wgclient.key
# ls -l wg*
-rw------- 1 root root  45 10月 30 19:52 wgclient.key
-rw-r--r-- 1 root root  45 10月 30 19:52 wgclient.pub
-rw------- 1 root root  45 10月 27 06:46 wgserver.key
-rw-r--r-- 1 root root  45 10月 27 06:46 wgserver.pub

3. ポートフォワードの設定

WireGuardはVPN用途としてインタフェースとIPアドレスが作成される。このインタフェースとLinuxサーバの本来の通信を行うインタフェース間で通信をできるようにする必要があるため、以下の通りポートフォワードを有効にする。

# echo "net.ipv4.ip_forward=1" >> /etc/sysctl.conf
# sysctl -p
net.ipv4.ip_forward = 1

4. WireGuardのconfファイル作成

WireGuardの設定はwgコマンドによる設定もできるが、今回はwg0.confというファイル名で設定ファイルを作成し、wg-quickコマンドを用いて読み込ませることで設定反映を行う。

設定ファイルの内容は以下の通りとなる。[Interface]は自分側の設定となり、[Peer]は対向側の設定となる。

[Interface]

設定値 設定内容
Address WireGuardで使用するIPアドレスを指定。
MTU 接続時のMTUを記載。デフォルトでは1420が設定されるが、環境によってはリモートデスクトップ接続がうまく動作しない (黒い画面が表示され接続・切断を繰り返す) ため1400や1380に設定する。私の環境では1380に設定すると問題なく動作するようになった。
PrivateKey wgserver.keyの内容を指定。
ListenPort WireGuardが使用するポート番号を指定。デフォルトは51820。
PostUp WireGuard起動時に実行するコマンドを指定。WireGuardで使用するIPアドレスはセグメントが異なることから、そのままでは通信ができないため、iptablesを用いてNATを有効にする。
PostDown WireGuard停止時に実行するコマンドを指定。

[Peer]

設定値 設定内容
PublicKey wgclient.pubの内容を指定。
AllowedIPs 対向先の接続機器と通信をさせるIPアドレスを記載する。通常はクライアントに割り当てるIPアドレスを指定すればよい。

設定ファイルは、以下のように新規作成する。

# cat << EOF > /etc/wireguard/wg0.conf
[Interface]
Address = 10.0.33.1/32
MTU = 1380
PrivateKey = [wgserver.keyの内容を指定]
ListenPort = 51820
PostUp = iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens192 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens192 -j MASQUERADE

[Peer]
PublicKey = [wgclient.pubの内容を指定]
AllowedIPs = 10.0.33.11/32
EOF

5. WireGuard起動確認

設定ファイルを作成後、一度手動でWireGuardを起動させる。コマンドはwg-quick upコマンドを使用する。

# wg-quick up wg0
[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.0.33.1/32 dev wg0
[#] ip link set mtu 1400 up dev wg0
[#] ip -4 route add 10.0.33.11/32 dev wg0
[#] iptables -A FORWARD -i wg0 -j ACCEPT; iptables -t nat -A POSTROUTING -o ens192 -j MASQUERADE

WireGuardを停止する際は、wg-quick downコマンドを使用する。

# wg-quick down wg0
[#] ip link delete dev wg0
[#] iptables -D FORWARD -i wg0 -j ACCEPT; iptables -t nat -D POSTROUTING -o ens192 -j MASQUERADE

6. systemctlにて自動起動設定

先ほどの起動・停止が問題なくできることを確認したら、systemctlにてWireGuardを自動起動するよう設定する。

# systemctl start wg-quick@wg0
# systemctl enable wg-quick@wg0
# systemctl status wg-quick@wg0
● wg-quick@wg0.service - WireGuard via wg-quick(8) for wg0
   Loaded: loaded (/usr/lib/systemd/system/wg-quick@.service; enabled; vendor p>
   Active: active (exited) since Sat 2021-10-30 15:42:05 JST; 2s ago
     Docs: man:wg-quick(8)
           man:wg(8)
           https://www.wireguard.com/
           https://www.wireguard.com/quickstart/
           https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
           https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
  Process: 8128 ExecStop=/usr/bin/wg-quick down wg0 (code=exited, status=0/SUCC>
  Process: 8156 ExecStart=/usr/bin/wg-quick up wg0 (code=exited, status=0/SUCCE>
 Main PID: 8156 (code=exited, status=0/SUCCESS)

10月 30 15:42:05 t3036vpns systemd[1]: Starting WireGuard via wg-quick(8) for w>
10月 30 15:42:05 t3036vpns wg-quick[8156]: [#] ip link add wg0 type wireguard
10月 30 15:42:05 t3036vpns wg-quick[8156]: [#] wg setconf wg0 /dev/fd/63
10月 30 15:42:05 t3036vpns wg-quick[8156]: [#] ip -4 address add 10.0.33.1/32 d>
10月 30 15:42:05 t3036vpns wg-quick[8156]: [#] ip link set mtu 1400 up dev wg0
10月 30 15:42:05 t3036vpns wg-quick[8156]: [#] ip -4 route add 10.0.33.11/32 de>
10月 30 15:42:05 t3036vpns wg-quick[8156]: [#] iptables -A FORWARD -i wg0 -j AC>
10月 30 15:42:05 t3036vpns systemd[1]: Started WireGuard via wg-quick(8) for wg

ブロードバンドルータの設定

WireGuardはUDPの58120ポートを使うため、ブロードバンドルータでポート開放を行う必要がある。設定方法は各社のルーターのマニュアルを確認すること。通常は「ポートマッピング」といった呼ばれ方の設定項目があるはずで、外部からの特定ポートのアクセスをLAN側の特定のサーバに転送する設定を行えばよい。

以下NECのAtermでの設定例を記載する。

  • LAN側ホスト:WireGuardサーバのIPアドレスを設定
  • プロトコル : UDP
  • 変換対象ポート番号:任意で指定
  • 宛先ポート番号:58120

WireGuard接続手順 (Windows)

1. WireGuardクライアントのインストール

Windows用のWireGuardクライアントは、以下公式サイトからダウンロードする。

インストーラのサイズは約80KBと極めて容量が小さく、インターネット経由でダウンロードしてインストールをするようだ。

2. WireGuardのconfファイル作成

Windows用のWireGuardクライアントも設定ファイルを読み込ませることで設定投入が可能となる。

設定ファイルの内容は以下の通りとなる。[Interface]は自分側の設定となり、[Peer]は対向側の設定となる。

[Interface]

設定値 設定内容
Address WireGuardクライアントで使用するIPアドレスを指定。
PrivateKey wgclient.keyの内容を指定。

[Peer]

設定値 設定内容
PublicKey wgserver.pubの内容を指定。
AllowedIPs 対向先の接続機器と通信をさせるIPアドレスを記載する。通常はWireGuardサーバのIPアドレスと自宅のプライベートアドレスを指定すればよい。もしすべての通信をWireGuardのVPN経由とさせる場合は、0.0.0.0/0を指定する。
Endpoint 自宅のグローバルIPまたはDDNS名などを設定している場合はFQDNを用いて[IP or FQDN]:[ポート番号]の形式で接続先のWireGuardサーバを指定する。

今回は以下のように設定ファイルを作成した。

[Interface]
PrivateKey = [wgclient.keyの内容を指定]
Address = 10.0.33.11/32

[Peer]
PublicKey = [wgserver.pubの内容を指定]
AllowedIPs = 10.0.33.1/32, 192.168.0.0/16
Endpoint = [自宅のグローバルIP or FQDN]:[ポート番号]

3. 設定ファイルのインポート

WireGuardクライアントにて「トンネルの追加」→「トンネルをファイルからインポート」を選択し、先ほど作成した設定ファイルをインポートする。

4. 接続確認

インポート後「有効化」ボタンを押す。ただし、WireGuardサーバと接続の成功・失敗に関係なく有効化はされるので、実際の接続状況はPingなどで確認をすること。

WireGuardサーバ側ではwgコマンドにて接続状態を確認することができる。

# wg
interface: wg0
  public key: XXXX
  private key: (hidden)
  listening port: 51820

peer: XXXX
  endpoint: 1.2.3.4:1025
  allowed ips: 10.0.33.11/32
  latest handshake: 18 seconds ago
  transfer: 902.41 KiB received, 897.92 KiB sent

以上でWireGuardサーバを構築しインターネット経由で自宅環境へアクセスすることができた。

参考

更新履歴

  • 2021/11/6 新規作成
  • 2021/11/8 リモートデスクトップ接続不可の事象を解消するため、MTUを設定する旨を追記

5 件のコメント:

  1. 大変参考になりました。ありがとうございます。
    こちらは複数接続できるのでしょうか?
    サーバ側に対して複数のクライアントから同時接続させたいと思っています。
    ヒントなど頂けるとありがたいです。
    よろしくお願いします。

    返信削除
    返信
    1. コメントありがとうございます。
      クライアント側の設定でAddressを重複させないようにすれば、複数のクライアントから同時接続可能になると思います。

      [Interface]
      PrivateKey = [wgclient.keyの内容を指定]
      Address = 10.0.33.11/32 ★

      削除
  2. JVN#85572374
    pfSense-pkg-WireGuard におけるディレクトリトラバーサルの脆弱性
    と出てました。関係ありそうですね?

    返信削除
    返信
    1. 情報ありがとうございます。pfsenseでwireguard使う場合に影響ありそうな感じがします。

      通常のLinuxでwireguard使う場合は大丈夫かなと。

      削除
  3. はじめまして、ツイッターから見に来ました。
    最近、vpsからkvmで立てた仮想環境にvpnで通そうとしている者です。
    ただ、vpn初学者で結構苦労しております。
    1点気になったので質問させて下さい。
    vpnを通すにあたって、市販のルータで必要な機能等はありますでしょうか。

    返信削除

人気の投稿