2026年6月16日
2026年6月16日
WireGuardで社内VPNを構築する方法:Ubuntuサーバーの設定から端末追加・管理画面のIP制限まで
WireGuard で社内VPNを作るなら、Ubuntu のサーバー1台に wg-quick で VPN インターフェースを立て、社員の端末ごとに鍵ペアを1組ずつ発行する構成がいちばん扱いやすい方法です。この記事では、サーバーの設定、社内ネットワークへの転送、端末の追加と失効、つながらないときの確認方法、そして VPN の出口 IP を使って WordPress の管理画面を社内だけに絞る方法までを順に説明します。
構成を先に決める
作業を始める前に、次の2点を決めておくと設定が迷いません。
1つ目は VPN サーバーをどこに置くか です。社内のファイルサーバーや業務システムに外から入りたいなら、VPN サーバーは社内 LAN の中に置き、ルーターで UDP の 51820 番を転送します。社内に固定の機器を置けない場合や、クラウド上のサーバー群だけが目的なら、VPS やクラウドの仮想マシンに置きます。
2つ目は どの通信をトンネルに通すか です。社内宛ての通信だけを VPN に通す「スプリットトンネル」と、インターネット宛ても含めてすべて通す「フルトンネル」があります。社内VPNでは、社内のサブネットだけを通すスプリットトンネルが一般的です。帯域を食わず、VPN サーバーが止まっても普段のネット利用に影響しないためです。
この記事では例として次の値を使います。手元の環境に合わせて読み替えてください。
- VPN 用のアドレス帯:
10.8.0.0/24(サーバーは10.8.0.1) - 社内 LAN:
192.168.10.0/24 - VPN サーバーの外向きインターフェース:
eth0 - 待ち受けポート: UDP
51820
VPN 用のアドレス帯は、社内 LAN や自宅のルーターがよく使う 192.168.0.0/24・192.168.1.0/24 と重ならないものを選びます。重なると、自宅から接続したときにどちらへ送るべきか分からなくなり、通信が届きません。
サーバーに WireGuard を入れて鍵を作る
WireGuard は Linux カーネル 5.6 以降に組み込まれており、Ubuntu のサポート中の LTS(2026年10月現在)である 22.04・24.04・26.04 などではパッケージを入れるだけで使えます。
sudo apt update
sudo apt install wireguard
# 鍵ファイルを他のユーザーが読めない権限で作る
sudo -i
cd /etc/wireguard
umask 077
wg genkey | tee server.key | wg pubkey > server.pub
exit
umask 077 を先に設定するのは、秘密鍵が作られた瞬間から所有者だけが読める状態にするためです。秘密鍵(server.key)はサーバーの外に出しません。相手に渡すのは公開鍵(server.pub)だけです。
サーバー側の設定ファイル
/etc/wireguard/wg0.conf を作ります。PrivateKey には先ほどの server.key の中身を貼ります。
[Interface]
Address = 10.8.0.1/24
ListenPort = 51820
PrivateKey = サーバーの秘密鍵をここに貼る
# VPN から社内 LAN・外部への転送と、送信元アドレスの変換
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
# 端末1: 営業部 山田さんのノートPC
[Peer]
PublicKey = 端末1の公開鍵
PresharedKey = 端末1用の事前共有鍵
AllowedIPs = 10.8.0.2/32
%i は wg-quick が起動時にインターフェース名(ここでは wg0)へ置き換えます。
MASQUERADE で送信元アドレスを VPN サーバーのものに変換しているので、社内 LAN の機器から見ると通信は VPN サーバーから来たように見えます。そのため社内の機器に戻りの経路を設定する必要がありません。代わりに、社内機器のログには VPN サーバーのアドレスしか残らず、誰の通信かが分からなくなります。利用者ごとのアクセスを社内機器のログで追いたい場合は、NAT をやめて社内ルーターに「10.8.0.0/24 は VPN サーバーへ」という経路を追加します。
サーバー側の AllowedIPs は「この端末から受け取ってよい送信元アドレス」と「この端末へ送るべき宛先」を兼ねています。端末ごとに /32 で1つずつ割り当てると、他人のアドレスを名乗った通信は受け付けられません。
SaveConfig = true は書かないでおくことをおすすめします。有効にすると停止時に実行中の状態でファイルが上書きされ、手で書いたコメントや変更が消えることがあります。
IP 転送とファイアウォール
社内 LAN へ通信を流すには、カーネルの IP 転送を有効にします。
echo 'net.ipv4.ip_forward=1' | sudo tee /etc/sysctl.d/99-wireguard.conf
sudo sysctl --system
UFW を使っている場合は、待ち受けポートを開けるだけでは足りません。UFW は転送(FORWARD)を既定で拒否するため、VPN から LAN への転送も許可します。
sudo ufw allow 51820/udp
sudo ufw route allow in on wg0 out on eth0
sudo ufw status verbose
クラウドの仮想マシンでは、OS のファイアウォールとは別にセキュリティグループなどの外側のファイアウォールがあります。UDP 51820 番をそちらでも許可してください。社内に置く場合は、ルーターのポート転送設定が必要です。
起動と自動起動
sudo systemctl enable --now wg-quick@wg0
sudo wg show
wg show に interface: wg0 と listening port: 51820 が表示されれば待ち受けています。端末がつながると、その端末の欄に latest handshake が表示されます。
端末(クライアント)を追加する
端末の鍵は、端末側のアプリで作るのが安全です。WireGuard の公式アプリは Windows・macOS・iOS・Android 向けに提供されており、トンネルを新規作成すると鍵ペアが作られます。公開鍵だけを管理者に送ってもらえば、秘密鍵はその端末から出ません。
端末側の設定は次のとおりです。
[Interface]
PrivateKey = 端末の秘密鍵(アプリが自動で入れる)
Address = 10.8.0.2/32
DNS = 192.168.10.1
[Peer]
PublicKey = サーバーの公開鍵
PresharedKey = 端末1用の事前共有鍵
Endpoint = vpn.example.com:51820
AllowedIPs = 10.8.0.0/24, 192.168.10.0/24
PersistentKeepalive = 25
端末側の AllowedIPs は「どの宛先をトンネルに通すか」です。ここに社内の2つのサブネットだけを書くとスプリットトンネルになります。0.0.0.0/0 にするとフルトンネルです。
DNS は社内の名前解決が必要な場合だけ指定します。指定すると、接続中は端末のすべての名前解決がそのサーバーに向かうため、そのサーバーが外部の名前も引けることを確かめてから設定してください。
PersistentKeepalive = 25 は、家庭のルーターや携帯回線の NAT で無通信の接続が切られるのを防ぎます。サーバー側から端末へ通信を始める必要がない構成なら、端末側にだけ書けば十分です。
事前共有鍵は wg genpsk で端末ごとに作ります。なくても動きますが、鍵交換の上に共通鍵の層を1枚足す仕組みで、端末ごとに別の値にしておくのが基本です。
サーバーに端末を追加したら、接続中のほかの端末を切らずに反映できます。
sudo bash -c 'wg syncconf wg0 <(wg-quick strip wg0)'
スマートフォンには、端末用の設定ファイルを QR コードで渡す方法もあります(qrencode -t ansiutf8 < client.conf)。ただしこの方法ではサーバー側で端末の秘密鍵を作ることになるので、作業後に設定ファイルを消してください。
退職・紛失時の失効
WireGuard にはユーザー名やパスワードの仕組みがなく、「公開鍵が登録されているかどうか」がそのまま接続の可否です。端末を紛失した、社員が退職した、というときは、その端末の [Peer] を wg0.conf から消して wg syncconf で反映します。急ぐときは実行中の設定から先に外せます。
sudo wg set wg0 peer 端末の公開鍵 remove
設定ファイルの [Peer] の上に、誰のどの端末かをコメントで書いておくと、この作業で迷いません。1人が複数の端末を使う場合も、端末ごとに鍵とアドレスを分けます。
つながらないときの確認順
- **
wg showでlatest handshakeが出ているか**。出ていなければ、通信がサーバーに届いていないか、鍵が合っていません。サーバーでsudo tcpdump -ni eth0 udp port 51820を実行しながら端末から接続し、パケットが来ているかを見ます。来ていなければ、ルーターのポート転送やクラウドのファイアウォールの問題です。 - パケットは来ているのにハンドシェイクしない。サーバーと端末で公開鍵の貼り間違いがないか、事前共有鍵が両側で同じかを確かめます。
- ハンドシェイクはするが社内に届かない。IP 転送(
sysctl net.ipv4.ip_forward)と UFW のroute allow、PostUpのeth0が実際のインターフェース名と合っているか(ip -br addrで確認)を見ます。 - 一部のサイトだけ表示が遅い・途中で止まる。経路上の MTU の問題のことがあります。端末側の
[Interface]にMTU = 1380のように小さめの値を入れて試します。
VPN の出口 IP で WordPress の管理画面を絞る
社内VPNができると、WordPress の管理画面を「VPN 経由の通信だけ」に制限できます。WordPress が VPN サーバーとは別のサーバーにある場合、端末側の AllowedIPs に WordPress サーバーの公開 IP(例: 203.0.113.50/32)を足すと、その宛ての通信だけがトンネルを通り、VPN サーバーの公開 IP(例: 198.51.100.10)から届くようになります。
WordPress 側の Apache では、wp-admin ディレクトリの .htaccess を次のようにします。admin-ajax.php はサイトの表側の機能からも呼ばれるため、制限の対象から外します。
# wp-admin/.htaccess
Require ip 198.51.100.10
<Files admin-ajax.php>
Require all granted
</Files>
wp-login.php はサイトのルートにあるので、ルートの .htaccess に <Files wp-login.php> で同じ Require ip を書きます。
作業の前に .htaccess のバックアップを取り、VPN サーバーが止まったときに備えて、ホスティング会社のファイルマネージャーやコンソールから .htaccess を戻せることを確かめておいてください。VPN だけが管理画面への入口になると、VPN の障害がそのまま管理画面の障害になるためです。
まとめ
- 構成は「サーバー1台+端末ごとに鍵ペア1組」。VPN のアドレス帯は社内や自宅の LAN と重ならないものを選ぶ。
- サーバー側の
AllowedIPsは端末ごとに/32、端末側のAllowedIPsは通したい社内サブネットだけにするとスプリットトンネルになる。 - LAN へ流すには IP 転送と、UFW の
route allow、クラウド側のファイアウォールの許可が要る。 - 失効は
[Peer]を消してwg syncconf。誰の端末かをコメントで残しておく。 - 不通時は
wg showのハンドシェイク →tcpdump→ 鍵 → 転送設定 → MTU の順に確かめる。 - 出口 IP で管理画面を絞る場合は、
admin-ajax.phpを外し、VPN 障害時の戻し方を用意しておく。