WireGuard のインストール
〜 UDP と TCP を VPN 〜
2025-11-11 作成 福島
TOP > tips > wireguard
[ TIPS | TOYS | OTAKU | LINK | MOVIE | CGI | AvTitle | ConfuTerm | HIST | AnSt | Asob | Shell ]

0. 前置き

TCP でポートを使用したトンネリングなら Linux や Windows に搭載されている ssh コマンドで簡単に実現できますが、
ICMP や UDP の場合は VPN を構築する必要があります。

昔の VPN というと、自ノードのインタフェースがすべて VPN に属してしまい、VPN 以外の通信ができなくなることがよくありましたが、これでは使い勝手がよくありません。
今は、一時的に別の LAN を自ノードに取り付けるように VPN を運用することができます。
ガチガチに VPN でしか動作しないノードは珍しい存在になっています。

本稿は WireGuard を使用した VPN の構築について記述します。
Linux ⇔ Windows の VPN です。Linux ⇔ Linux の VPN ならもう少し簡単に構築できます。

WireGuard は技術的に高速かつセキュアな VPN ですが、ユーザ管理という概念がありません。
このため、組織で運用するには注意が必要です。

動作環境
項目内容備考
サーバOSAlmaLinux release 10.0 (Purple Lion)本稿記述時の最新版
IP アドレス192.168.11.20NIC に割り振られたアドレス
IP アドレス (仮想)10.10.0.1VPN で使用するアドレス
VPN ソフトWireGuard 1.0.0WireGuard は Alma10 に組み込まれている
追加するのは wireguard-tools
疎通確認ソフトsocat 1.7.4.1dnf でインストールできる最新版
クライアント基本ソフトWindows11 Pro 24H2-
IP アドレス192.168.11.40NIC に割り振られたアドレス
IP アドレス (仮想)10.10.0.2VPN で使用するアドレス
VPN ソフトwireguard-amd64-0.5.3本稿記述時の最新版
疎通確認ソフトPacket Sender 8.9.1
VPN名前SampleVPN設定を保存する名称
ポート (サーバ)51820/UDP51820/UDP は WireGuard の標準ポート
他のポートは使用しない
ポート (クライアント)動的/UDP-
(WireGuard にサーバ / クライアントの区別はありませんが、運用の便宜上サーバ / クライアントという言葉を使用しています)


1. WireGuard のインストール (Linux)

1-1. WireGuard をインストールする。
$ su
# dnf install -y wireguard-tools
# which wg wg-quick
/bin/wg
/bin/wg-quick  
# wg --version
wireguard-tools v1.0.20210914 - https://git.zx2c4.com/wireguard-tools/  
# modinfo wireguard | head | fold
filename:       /lib/modules/6.12.0-55.40.1.el10_0.x86_64/kernel/drivers/net/wir
eguard/wireguard.ko.xz
alias:          net-pf-16-proto-16-family-wireguard
alias:          rtnl-link-wireguard
version:        1.0.0
author:         Jason A. Donenfeld <Jason@zx2c4.com>
description:    WireGuard secure network tunnel
license:        GPL v2
rhelversion:    10.0
srcversion:     6FC1E1261D4D834B105C922
depends:        udp_tunnel,ip6_udp_tunnel,curve25519-x86_64,libcurve25519-generi
c
1-2. サーバの設定をする。
# cd /etc/wireguard
/etc/wireguard/# umask 077 # <- これをしないと wg コマンドから警告が出る。
/etc/wireguard/# wg genkey > privatekey
/etc/wireguard/# cat privatekey | wg pubkey > publickey
/etc/wireguard/# chmod 644 publickey
/etc/wireguard/# cat > wg0.conf << EOF
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = `cat ./privatekey`
EOF

/etc/wireguard/# ls -l
合計 8
-rw-------. 1 root root  45 10月 27 20:32 privatekey  ← 秘密鍵
-rw-r--r--. 1 root root  45 10月 27 20:33 publickey   ← 公開鍵 (クライアントへ渡す)  
-rw-------. 1 root root 130 10月 27 20:43 wg0.conf
/etc/wireguard/# cat wg0.conf
[Interface]
Address = 10.10.0.1/24        ← WireGuard が使う仮想インタフェースの IP アドレス
ListenPort = 51820            ← WireGuard のデフォルトポート (待ち受け)
PrivateKey = PrivateKeyb3smPa3yJoHwdDPnEDnUNEWfHZtUOoMjU= ← `cat …` で取り込んだ秘密鍵
1-3. 仮想インタフェースの起動と確認をする。
/etc/wireguard/# systemctl start wg-quick@wg0
/etc/wireguard/# systemctl enable wg-quick@wg0

/etc/wireguard/# wg show
interface: wg0
  public key: PublicKeyZ38z6BgLv0rtF+InPHHzbqWeaWYfLCz9L0= ← ./publickey の内容と同じ
  private key: (hidden)
  listening port: 51820
/etc/wireguard/# ip a show wg0 | fold
6: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN gro
up default qlen 1000
    link/none
    inet 10.10.0.1/24 scope global wg0
       valid_lft forever preferred_lft forever
/etc/wireguard/# ping -c 4 10.10.0.1
PING 10.10.0.1 (10.10.0.1) 56(84) バイトのデータ
64 バイト応答 送信元 10.10.0.1: icmp_seq=1 ttl=64 時間=0.032ミリ秒  
64 バイト応答 送信元 10.10.0.1: icmp_seq=2 ttl=64 時間=0.046ミリ秒
64 バイト応答 送信元 10.10.0.1: icmp_seq=3 ttl=64 時間=0.058ミリ秒
64 バイト応答 送信元 10.10.0.1: icmp_seq=4 ttl=64 時間=0.074ミリ秒

--- 10.10.0.1 ping 統計 ---
送信パケット数 4, 受信パケット数 4, 0% packet loss, time 3079ms
rtt min/avg/max/mdev = 0.032/0.052/0.074/0.015
1-4. トンネリング用ポートを許可する。
/etc/wireguard/# firewall-cmd --permanent --add-port="51820/udp"
/etc/wireguard/# firewall-cmd --reload
/etc/wireguard/# firewall-cmd --list-ports
51820/udp 
/etc/wireguard/# exit
$


2. WireGuard のインストール (Windows)

2-1. インストーラをダウンロード&実行する。
ここから Windows 版のインストーラをダウンロードする。
今回は wireguard-amd64-0.5.3.msi だった。
wireguard-installer.exe は起動すると本体のダウンロードが開始される。

 UAC が表示される。
ボタンをクリックする。
 ⇓
 インストールが終了し、いきなり設定画面が表示される。
 ↓ インストールフォルダはここ。
 %ProgramFiles%\WireGuard\
2-2. トンネル (VPN クライアント) を設定する。
 トンネルの追加 の から を選択する。

 ⇓
 公開鍵ペア (秘密鍵 / 公開鍵) が自動的に生成される
 以下を記入し ボタンをクリックする。
項目内容備考
名前(N):SampleVPN当該ノードのトンネル名
Address = 10.10.0.2/24当該ノードの IP アドレス
[Peer]接続する WireGuard サーバの定義開始
PublicKey = PublicKeyZ38z…Cz9L0=上記 1-3 の wg show で確認した  public key:  の内容
AllowedIPs = 10.10.0.0/24取り扱うネットワーク範囲
Endpoint = 192.168.11.20:51820WireGuard サーバの IP アドレスと UDP ポート番号

 ⇓
 公開鍵が確定する。
 この公開鍵を使用して当該ノードを WireGuard サーバに登録する。(→ 3-1)
 公開鍵の登録が完了しないと接続できない。
(有効化は出来るが、接続したことにならない)


3. クライアントの登録

WireGuard サーバで作業する

3-1. WireGuard の定義ファイルにクライアント情報を追加する。
$ su
# vim /etc/wireguard/wg0.conf
[Interface]
Address = 10.10.0.1/24
ListenPort = 51820
PrivateKey = PrivateKeyb3smPa3yJoHwdDPnEDnUNEWfHZtUOoMjU=

[Peer]
PublicKey = 6/QCOnvN9b7EoloMD6ydaN0o2LTZmyLAX/3GHu27YCo=  # 上記 2-2 で確定した公開鍵
AllowedIPs = 10.10.0.2/32     # 10.10.0.2 への送信経路は当該 Peer を使う
[Peer] セクションは、接続するクライアントの数だけ定義する。
3-2. WireGuard を再起動する。
# systemctl restart wg-quick@wg0
# exit
$


4. クライアントから接続

4-1. 上記 2 で用意した WireGuard クライアントを起動する。(Windows)
Microsoft Defender でポート開放を設定する必要はない。
4-2. トンネルを有効化する。
 作成したトンネルを選択して
ボタンをクリックする。
4-3. トンネルの有効化を確認する。
 ピア (WireGuard サーバ) のペインが以下であることを確認する。
 • 項目 直前のハンドシェイク: が存在すること。
 • 項目 転送: の「受信済み」が 0 のままでないこと。

4-4. おまけ : 無効化 (切断) する場合。
 トンネルを無効化し VPN から切り離すには
ボタンをクリックする。


5. 疎通確認

上記 1 ~ 4 の作業により、以下のネットワークが形成されている。
サーバ
Linux
192.168.11.20
 10.10.0.1  WireGuard 

 ← LAN → 
 ← VPN → 
クライアント
Windows11
192.168.11.40
 WireGuard  10.10.0.2 

5-1. 疎通確認(1) サーバ  ← ping  クライアント
クライアント (Windows) で作業する。

− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # 通常の疎通確認
PS C:\> ping 10.10.0.1 

10.10.0.1 に ping を送信しています 32 バイトのデータ:
10.10.0.1 からの応答: バイト数 =32 時間 =2ms TTL=64
10.10.0.1 からの応答: バイト数 =32 時間 =1ms TTL=64
10.10.0.1 からの応答: バイト数 =32 時間 =36ms TTL=64
10.10.0.1 からの応答: バイト数 =32 時間 =1ms TTL=64

10.10.0.1 の ping 統計:
    パケット数: 送信 = 4、受信 = 4、損失 = 0 (0% の損失)、
ラウンド トリップの概算時間 (ミリ秒):
    最小 = 1ms、最大 = 36ms、平均 = 10ms

PS C:\> exit 

5-2. 疎通確認(2) サーバ  ping →  クライアント
サーバ (Linux) で作業する。

$ ping -c 4 10.10.0.2
PING 10.10.0.2 (10.10.0.2) 56(84) バイトのデータ
64 バイト応答 送信元 10.10.0.2: icmp_seq=1 ttl=128 時間=35.8ミリ秒
64 バイト応答 送信元 10.10.0.2: icmp_seq=2 ttl=128 時間=1.35ミリ秒
64 バイト応答 送信元 10.10.0.2: icmp_seq=3 ttl=128 時間=1.14ミリ秒
64 バイト応答 送信元 10.10.0.2: icmp_seq=4 ttl=128 時間=34.6ミリ秒

--- 10.10.0.2 ping 統計 ---
送信パケット数 4, 受信パケット数 4, 0% packet loss, time 3005ms
rtt min/avg/max/mdev = 1.137/18.218/35.814/16.980 ms
5-3. 疎通確認(3) サーバ  ← UDP  クライアント
5-3-1. 簡易 UDP サーバを動作させる。(Linux)
$ socat -v UDP4-LISTEN:10013,fork SYSTEM:'date +UDP\:\\ %Y-%m-%d\\ %H\:%M\:%S'
< 2025/11/01 20:17:00.000297953  length=25 from=0 to=24  
UDP: 2025-11-01 20:17:00
ログが表示されるが、今回はあまり関係ない。

5-3-2. UDP の疎通を確認する。(Windows の Packet Sender)
 サーバの仮想 IP アドレスに向けて空の UDP パケットを送信し、
 UDP パケットの受信を確認する。(ここでは現在時刻)
5-4. 疎通確認(4) サーバ  UDP →  クライアント
5-4-1. 簡易 UDP サーバを動作させる。(Windows の PowerShell)
中止する場合は を打鍵する。
待ち受けをループにしていないので、1 回の応答で終了する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # UDP で daytime サーバを起動する
PS C:\> @'
$u  = New-Object Net.Sockets.UdpClient(10013)
$ep = New-Object Net.IPEndPoint([Net.IPAddress]::Any,0)
$u.Receive([ref]$ep)            # UDP 受信 (受信データは破棄)
$msg  = [System.Text.Encoding]::UTF8.GetBytes((Get-Date).ToString() + "`n")
$u.Send($msg, $msg.Length, $ep) # 日時を返す
'@ | powershell -NoLogo 

PS C:\> exit 


5-4-2. UDP の疎通を確認する。(Linux)
$ echo | socat - UDP4:10.10.0.2:10013
2025/11/01 20:18:14   ← 上記 簡易 UDP サーバからの応答
5-5. 疎通確認(5) サーバ  ← TCP  クライアント
5-5-1. 簡易 TCP サーバを動作させる。(Linux)
$ socat -v TCP4-LISTEN:10013,fork SYSTEM:'date +TCP\:\\ %Y-%m-%d\\ %H\:%M\:%S'
< 2025/11/01 20:19:43.000761578  length=25 from=0 to=24  
TCP: 2025-11-01 20:19:43
ログが表示されるが、今回はあまり関係ない。

5-5-2. TCP の疎通を確認する。(Windows の Packet Sender)
 サーバの仮想 IP アドレスに向けて空の TCP 接続を行い、
 応答を確認する。(ここでは現在時刻)
5-6. 疎通確認(6) サーバ  TCP →  クライアント
5-6-1. 簡易 TCP サーバを動作させる。(Windows の PowerShell)
中止する場合は を打鍵する。
待ち受けをループにしていないので、1 回の応答で終了する。
− □ × 
 >_ Windows PowerShell ×   + |
 
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

新機能と改善のために最新の PowerShell をインストールしてください!https://aka.ms/PSWindows  

PS C:\> # TCP で daytime サーバを起動する
PS C:\> @'
$listener = [Net.Sockets.TcpListener]10013
$listener.Start()
$client = $listener.AcceptTcpClient()         # 接続待ち
$s = $client.GetStream()
$msg = [System.Text.Encoding]::UTF8.GetBytes((Get-Date).ToString() + "`n")
$s.Write($msg, 0, $msg.Length)                # 日時を返す
$client.Close()
$listener.Stop()
'@ | powershell -NoLogo 

PS C:\> exit 


5-6-2. TCP の疎通を確認する。(Linux)
$ echo | socat - TCP4:10.10.0.2:10013
2025/11/01 22:24:35   ← 上記 簡易 TCP サーバからの応答