WireGuard を使って、Android、Windows PC、Linux PC から自宅サーバーや VPS へ接続するフルトンネル VPN を構築する手順をまとめます。
今回は フルトンネル IPv4 / PSK あり の構成です。安全寄りにするため、ファイアウォールは UFW に統一し、クライアント IP は /32、クライアント側の AllowedIPs は 0.0.0.0/0 にします。
PSK は Preshared Key の略で、サーバーとクライアントの両方に同じ値を設定する追加の共有鍵です。WireGuard は通常の公開鍵・秘密鍵だけでも接続できますが、PSK を追加すると、通常の鍵にもう 1 つ秘密の値を重ねる形になります。端末ごとに PSK を分けておくと、端末を失効させたいときにも管理しやすくなります。
0. 事前に決める値
まず、設定で使う値を決めておきます。以下はこの記事で使う例です。
| 項目 | 例 |
|---|---|
| ローカルサブネット | 192.168.1.0/24 |
| WireGuard IF | wg0 |
| VPN サブネット | 10.0.0.0/24 |
| サーバー VPN IP | 10.0.0.1 |
| Android VPN IP | 10.0.0.2 |
| Windows VPN IP | 10.0.0.3 |
| Linux VPN IP | 10.0.0.4 |
| ポート | 51820/udp |
| WAN NIC | eth0(環境に合わせて確認) |
- ローカルサブネットは、ルーターの設定によって異なるので、そちらに合わせてください。(例えば、家の PC などの IP が
192.168.10.xxxのようになっている場合は192.168.10.0/24になります。) - VPN サブネット、サーバー VPN IP は、例の値をそのまま使用することを推奨します。Android VPN IP、Windows VPN IP、Linux VPN IP は、
10.0.0.xの中で被らなければなんでもよいです。(変える場合は適宜読み替えてください。) - WAN NIC は環境によって
eth0ではない場合があります。後の手順で確認して、必要なら読み替えてください。
1. サーバー準備
サーバーに WireGuard と UFW をインストールします。
sudo apt update
sudo apt install -y wireguard ufwコマンドの意味:
sudo apt update: インストールできるパッケージ情報を最新にするsudo apt install -y wireguard ufw: WireGuard と UFW をインストールする
次に、NIC 名を確認します。eth0 が違う場合は、以降の eth0 を実際の NIC 名に置き換えます。
ip -brief a
ip route
# 例: enp2s0コマンドの意味:
ip -brief a: ネットワークインターフェース名と IP アドレスを簡潔に表示するip route: デフォルトゲートウェイや外向き通信に使う NIC を確認する# 例: enp2s0: 実際に表示される NIC 名の例
2. サーバー鍵を作成
WireGuard サーバー用の秘密鍵と公開鍵を作成します。
sudo install -d -m 700 /etc/wireguard
sudo bash -c 'umask 077; wg genkey > /etc/wireguard/server_private.key'
sudo bash -c 'wg pubkey < /etc/wireguard/server_private.key > /etc/wireguard/server_public.key'
sudo chmod 600 /etc/wireguard/server_private.key /etc/wireguard/server_public.keyコマンドの意味:
sudo install -d -m 700 /etc/wireguard:/etc/wireguardディレクトリを作成し、所有者だけがアクセスできる権限にします。(mkdirとchmodを同時にやるイメージです。)sudo bash -c 'umask 077; wg genkey > /etc/wireguard/server_private.key': サーバーの秘密鍵を作成し、他ユーザーが読めない権限で保存します。umask 077を使うことで、鍵を作成した瞬間から他のユーザーが鍵を見られないようにできます。sudo bash -c 'wg pubkey < /etc/wireguard/server_private.key > /etc/wireguard/server_public.key': 秘密鍵からサーバーの公開鍵を作成します。sudo chmod 600 /etc/wireguard/server_private.key /etc/wireguard/server_public.key: 鍵ファイルを所有者だけが読み書きできる権限にします。
作成した公開鍵は、以下のコマンドで確認できます。後で各クライアント側の設定に使いますので、確認できるようにしておいてください。
sudo cat /etc/wireguard/server_public.key3. PSK を作成(サーバー)
追加の共有鍵として PSK を作成します。PSK はクライアントごとに別々に作ります。
PSK は、サーバー側の Peer 設定とクライアント側の Peer 設定の両方に同じ値を入れて使います。これは通常の公開鍵認証を置き換えるものではなく、通信の保護を追加するためのものです。端末ごとに別々の PSK を用意しておくと、特定の端末だけを無効化したり、PSK を再発行したりしやすくなります。
sudo install -d -m 700 /etc/wireguard/psk
sudo bash -c 'umask 077; wg genpsk > /etc/wireguard/psk/client1.psk'
sudo chmod 600 /etc/wireguard/psk/client1.psk
sudo cat /etc/wireguard/psk/client1.pskこれを繰り返して、使用する端末の数だけ PSK を用意します。
例では、PSK の名前を client1.psk としていますが、これは適宜どの端末用か分かるように名前を変えてください。
表示された値をクライアント側の設定にも使いますので後から確認できるようにしておいてください。以降、Android 用に控えた PSK を ANDROID_PSK、Windows 用を WINDOWS_PSK、Linux 用を LINUX_PSK として書きます。
4. サーバー共通設定 wg0.conf 作成
まず、サーバー側の WireGuard 設定ファイルに [Interface] だけを書きます。各クライアントを許可する [Peer] は、後の OS 別設定で追記します。
ListenPort は別の値でも問題ありませんが、その場合はポート開放もその値で行ってください。
以下のコマンドで設定ファイルを開きます。
sudo nano /etc/wireguard/wg0.confコマンドの意味:
sudo nano /etc/wireguard/wg0.conf: WireGuard のサーバー設定ファイルを管理者権限で開く
開いたら、以下のように入力してください。入力できたら Ctrl + o → Enter → Ctrl + x で保存します。
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>設定項目の意味:
[Interface]: サーバー自身の WireGuard 設定を書く場所Address = 10.0.0.1/24: サーバー側の VPN 内 IP アドレスを指定するListenPort = 51820: WireGuard が待ち受ける UDP ポートを指定するPrivateKey = <SERVER_PRIVATE_KEY>: サーバーの秘密鍵を指定する
<SERVER_PRIVATE_KEY> は以下で取得します。
sudo cat /etc/wireguard/server_private.key設定ファイルの権限も固定しておきます。
sudo chmod 600 /etc/wireguard/wg0.conf
sudo chown root:root /etc/wireguard/wg0.confコマンドの意味:
sudo chown root:root /etc/wireguard/wg0.conf: 設定ファイルの所有者とグループをrootにする
5. IPv4 フォワーディング有効化
デフォルトでは、サーバーに入ってきた通信を、サーバーを経由して別の場所へ送り出す機能(フォワーディング機能)は無効になっています。そのままだと、VPN を立てても VPN 経由で Web サイトを見られなくなってしまうので、以下の手順で IPv4 フォワーディングを有効にします。
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard-ipforward.conf
sudo sysctl --systemコマンドの意味:
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard-ipforward.conf: IPv4 フォワーディングを有効にする設定を書き込むsudo sysctl --system: sysctl の設定ファイルを読み込み直して反映する
以下のコマンドで IPv4 フォワーディングが有効になっているか確認できます。net.ipv4.ip_forward = 1 になっていれば OK です。
sysctl net.ipv4.ip_forwardもしなっていない場合は、別のファイルで設定を上書きされている可能性がありますので、ほかのファイルに net.ipv4.ip_forward の項目がないか探してみてください。面倒な場合は、以下のコマンドで一括で探すこともできます。
grep -r "ip_forward" /etc/sysctl.conf /etc/sysctl.d/ 2>/dev/null6. UFW で VPN/NAT 設定(iptables 直書きしない)
6-1. 先に SSH 許可(リモート接続中なら必須)
リモート作業中に UFW を有効化する場合、先に SSH を許可しておきます。既にしてある場合は必要ありません。
sudo ufw allow OpenSSHコマンドの意味:
sudo ufw allow OpenSSH: UFW で SSH 接続を許可する
6-2. WireGuard ポート許可
WireGuard で使う UDP ポートを許可します。もし、4. で [Interface] の ListenPort を 51820 以外にした場合は、その値を入れてください。
sudo ufw allow 51820/udpコマンドの意味:
sudo ufw allow 51820/udp: WireGuard で使う UDP 51820 番ポートを許可する
6-3. ルーティング許可
VPN 内の通信が外部へ出られるように、UFW のルーティングを許可します。
以下のコマンドを順に実行してください。(順番が異なると正しく動作しないので注意してください。)
sudo ufw route deny in on wg0 out on eth0 from 10.0.0.0/24 to 192.168.1.0/24
sudo ufw route allow in on wg0 out on eth0 from 10.0.0.0/24 to anyコマンドの意味:
sudo ufw route deny in on wg0 out on eth0 from 10.0.0.0/24 to 192.168.1.0/24: VPNクライアント10.0.0.0/24から LAN192.168.1.0/24への転送通信を拒否します。sudo ufw route allow in on wg0 out on eth0 from 10.0.0.0/24 to any: VPNクライアント10.0.0.0/24からeth0経由で出ていく転送通信を許可します。
UFW は上から処理されるため、このようにすることで、
- クライアント→VPN→LAN 内への接続: 拒否
- クライアント→VPN→LAN 外(Web など)への接続: 許可
という形にすることができます。
万一、VPN に侵入があった際も、この設定ならば自宅 LAN にある他の PC などへのアクセスを防ぐことができます。もしそこまで気にしない場合は、sudo ufw route allow in on wg0 out on eth0 from 10.0.0.0/24 to any のみでも OK です。
LAN 内への接続を一部許可したい場合
もし、LAN 内への接続を一部許可したい場合は、今回追加した UFW ルールよりも上に、その通信のみ許可するルールを追加します。
例えば、WoL を使いたい場合は 9 番ポートのみ LAN への転送通信を許可すればよいので、以下のようにします。insert を使うことで、UFW の何番目に追加するのかを指定できます。
sudo ufw status numbered # UFW を順番付きで表示
sudo ufw insert 1 route allow in on wg0 out on eth0 proto udp from 10.0.0.0/24 to 192.168.1.0/24 port 96-4. NAT を before.rules に追加
UFW 側で NAT を設定します。編集前にバックアップを取ります。
sudo cp /etc/ufw/before.rules /etc/ufw/before.rules.bak.$(date +%F-%H%M%S)
sudo nano /etc/ufw/before.rulesコマンドの意味:
sudo cp /etc/ufw/before.rules /etc/ufw/before.rules.bak.$(date +%F-%H%M%S): UFW の既存設定を日時付きファイル名でバックアップする
*filter より前に以下を追加します。
*nat
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
COMMIT設定項目の意味:
*nat: NAT テーブルの設定を開始する:POSTROUTING ACCEPT [0:0]: POSTROUTING チェーンの初期設定をする-A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE: VPN サブネットから出る通信をeth0の IP に変換するCOMMIT: NAT 設定を確定する
これにより、VPN を経由して Web サイトを見る際などに、VPN のグローバル IP に自動で置き換わるようになります。
6-5. UFW 有効化/再読込
最後に UFW を有効化し、設定を再読み込みします。
sudo ufw enable
sudo ufw reload
sudo ufw status verboseコマンドの意味:
sudo ufw enable: UFW を有効化するsudo ufw reload: UFW の設定を再読み込みするsudo ufw status verbose: UFW の状態と許可ルールを詳しく表示する
7. クライアント OS 別設定とサーバー側 Peer 追記
ここから、接続するクライアント OS ごとに設定します。
クライアント側の鍵は、できるだけクライアント端末の中で作成します。クライアントの秘密鍵をサーバーに残さずに済むためです。
流れはどの OS でも同じです。
1. クライアント側で鍵を作る
2. クライアント側の設定を作る
3. サーバー側の wg0.conf に、そのクライアント用の [Peer] を追記する
4. サーバーの WireGuard を起動または再起動する
5. クライアントから接続するAndroid の場合
Android アプリでクライアント側の鍵を作成します。
- Android で WireGuard アプリを開く
- 右下にある + を押す → 空の状態から作成
- インターフェースに以下を入力
- 名前: なんでも OK
- 秘密鍵: 右の更新ボタンを押して作成
- 公開鍵: 秘密鍵作成時に自動で作成されるので、控えておく
- アドレス:
10.0.0.2/32 - DNS サーバー:
1.1.1.1(恐らく空欄でも大丈夫です) - Listen ポート: 空欄
- MTU: 空欄
- ピアに以下を入力
- 公開鍵:
2. サーバー鍵を作成の最後で控えた公開鍵を入力 - 事前共有鍵:
3. PSK を作成(サーバー)で控えた<ANDROID_PSK>を入力 - 持続的キープアライブ: 空欄
- エンドポイント:
<グローバルIP>:51820 - Allowed IPs:
0.0.0.0/0
- 公開鍵:
次に、サーバー側の /etc/wireguard/wg0.conf を
sudo nano /etc/wireguard/wg0.confで開き、Android 用の [Peer] を以下のように追記します。
[Interface]
Address = 10.0.0.1/24
ListenPort = 51820
PrivateKey = <SERVER_PRIVATE_KEY>
↑
ここまでは 4. サーバー共通設定 `wg0.conf` 作成で既に記述済みなので、書く必要はない。
この `[Interface]` の下に `[Peer]` のみ、以下のような形で書き足す。
[Peer]
PublicKey = <ANDROID_PUBLIC_KEY>
PresharedKey = <ANDROID_PSK>
AllowedIPs = 10.0.0.2/32
PersistentKeepalive = 25設定項目の意味:
[Peer]: 接続を許可するクライアントの設定を書く場所PublicKey = <ANDROID_PUBLIC_KEY>: Android 側の公開鍵を指定します。Android で設定を行った際に控えた公開鍵の値を入れてください。PresharedKey = <ANDROID_PSK>: Android と共有する PSK を入れます。AllowedIPs = 10.0.0.2/32: Android に割り当てる VPN 内 IP を指定します。PersistentKeepalive = 25: NAT 越えのため、25 秒ごとに接続維持用パケットを送ります。
Android の VPN 設定では、必要に応じて以下も有効にします。
- 常時接続 VPN: ON
- VPN なしの接続をブロック: ON
- バッテリー最適化から WireGuard を除外
Windows PC の場合
Windows では、WireGuard 公式アプリでクライアント側の鍵を作成します。
- Windows で WireGuard アプリを開く
Add Tunnel→Add empty tunnel...を選ぶ- 作成したトンネルを以下のように設定します。
<SERVER_PUBLIC_KEY>や<WINDOWS_PSK>は、これまでの手順で控えておいた値を入れます。<WINDOWS_PRIVATE_KEY>はトンネル作成時に自動で入力されていると思います。
[Interface]
PrivateKey = <WINDOWS_PRIVATE_KEY>
Address = 10.0.0.3/32
DNS = 1.1.1.1
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <WINDOWS_PSK>
Endpoint = <グローバルIP>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25- 自動生成された Public key を控える(
WINDOWS_PUBLIC_KEY)
設定項目の意味:
[Interface]: Windows 側の WireGuard 設定を書く場所PrivateKey = <WINDOWS_PRIVATE_KEY>: Windows 側の秘密鍵を指定するAddress = 10.0.0.3/32: Windows 側の VPN 内 IP アドレスを指定するDNS = 1.1.1.1: VPN 接続中に使う DNS サーバーを指定します[Peer]: 接続先サーバーの設定を書く場所PublicKey = <SERVER_PUBLIC_KEY>: サーバー側の公開鍵を指定するPresharedKey = <WINDOWS_PSK>: サーバーと Windows で共有する PSK を指定するEndpoint = <グローバルIP>:51820: 接続先のドメインまたは IP アドレスとポートを指定するAllowedIPs = 0.0.0.0/0: すべての IPv4 通信を VPN 経由にするPersistentKeepalive = 25: NAT 越えのため、25 秒ごとに接続維持用パケットを送る
次に、サーバー側の /etc/wireguard/wg0.conf に Windows 用の [Peer] を追記します。
[Peer]
PublicKey = <WINDOWS_PUBLIC_KEY>
PresharedKey = <WINDOWS_PSK>
AllowedIPs = 10.0.0.3/32
PersistentKeepalive = 25設定項目の意味:
[Peer]: 接続を許可するクライアントの設定を書く場所PublicKey = <WINDOWS_PUBLIC_KEY>: Windows 側の公開鍵を指定するPresharedKey = <WINDOWS_PSK>: Windows と共有する PSK を指定するAllowedIPs = 10.0.0.3/32: Windows に割り当てる VPN 内 IP を指定するPersistentKeepalive = 25: NAT 越えのため、25 秒ごとに接続維持用パケットを送る
Linux PC の場合
Linux クライアントでは、クライアント側の PC にも WireGuard をインストールします。
sudo apt update
sudo apt install -y wireguardコマンドの意味:
sudo apt update: Linux クライアント側でインストールできるパッケージ情報を最新にするsudo apt install -y wireguard: Linux クライアント側に WireGuard をインストールする
その後、クライアント側の PC で鍵を作成します。
sudo install -d -m 700 /etc/wireguard
sudo bash -c 'umask 077; wg genkey > /etc/wireguard/client_private.key'
sudo bash -c 'wg pubkey < /etc/wireguard/client_private.key > /etc/wireguard/client_public.key'
sudo chmod 600 /etc/wireguard/client_private.key /etc/wireguard/client_public.key
sudo cat /etc/wireguard/client_private.key
sudo cat /etc/wireguard/client_public.key次に、クライアント側の /etc/wireguard/wg0.conf を設定します。
sudo nano /etc/wireguard/wg0.conf以下のように入力します。<SERVER_PUBLIC_KEY> や <LINUX_PSK> は、Windows と同じようにこれまでの手順で控えておいた値を入れます。<LINUX_PRIVATE_KEY> は、sudo cat /etc/wireguard/client_private.key で表示された値を入れます。
[Interface]
PrivateKey = <LINUX_PRIVATE_KEY>
Address = 10.0.0.4/32
DNS = 1.1.1.1
[Peer]
PublicKey = <SERVER_PUBLIC_KEY>
PresharedKey = <LINUX_PSK>
Endpoint = <vpn.example.com>:51820
AllowedIPs = 0.0.0.0/0
PersistentKeepalive = 25その後、Linux クライアント側の設定ファイルの権限を固定します。
sudo chmod 600 /etc/wireguard/wg0.conf最後に、サーバー側の /etc/wireguard/wg0.conf に Linux 用の [Peer] を追記して完了です。
[Peer]
PublicKey = <LINUX_PUBLIC_KEY>
PresharedKey = <LINUX_PSK>
AllowedIPs = 10.0.0.4/32
PersistentKeepalive = 258. サーバー設定を反映して WireGuard 起動
クライアント用の [Peer] を追記したら、サーバー側で WireGuard を起動し、自動起動も有効にします。
sudo systemctl enable --now wg-quick@wg0
sudo systemctl status wg-quick@wg0コマンドの意味:
sudo systemctl enable --now wg-quick@wg0:wg0を今すぐ起動し、サーバー起動時にも自動起動するようにするsudo systemctl status wg-quick@wg0: WireGuard の起動状態やエラーを確認する
9. 動作確認
サーバー
サーバー側では、ハンドシェイクと転送量を確認します。
sudo wg showコマンドの意味:
sudo wg show: WireGuard の接続状態、ピア、ハンドシェイク、転送量を表示するlatest handshakeが更新transferが増加
クライアント
クライアント側では、VPN を ON にした状態でグローバル IP を確認します。
- VPN ON 後に
https://ifconfig.meを開く - 表示 IP がサーバー側回線なら成功
10. 端末紛失・失効時の対応(重要)
端末を紛失した場合や、接続を無効化したい場合は、サーバー側の /etc/wireguard/wg0.conf から該当クライアントの [Peer] を削除して反映します。
sudo systemctl restart wg-quick@wg0コマンドの意味:
sudo systemctl restart wg-quick@wg0: Peer 削除後の設定を反映するため、WireGuard を再起動する
必要なら PSK も再発行して再配布します。
補足: QR で Android へ取り込みたい場合
QR 方式は便利ですが、Android 秘密鍵をサーバーで扱う構成になりがちです。
セキュリティ優先なら、今回の手順(Android で鍵生成)が推奨です。
これで、Android、Windows PC、Linux PC から WireGuard サーバーへ接続し、すべての IPv4 通信を VPN 経由にする構成ができます。
実際に設定するときは、ドメイン名、グローバル IP、NIC 名、公開鍵、PSK を自分の環境に合わせて置き換えます。