WireGuard + AdGuard Home + ProtonVPN でVPNサーバーを構築する方法
この記事では、AdGuard Home、ProtonVPN、WireGuard を組み合わせた VPN サーバーの構築方法を解説します。
この構成により、以下の機能を実現できます。
- WireGuard VPN: 高速でセキュアな VPN 接続
- AdGuard Home: DNS ベースの広告ブロック
- ProtonVPN: インターネット接続の匿名化(ローカルネットワークは直接接続)
システム構成
クライアント端末
↓ (WireGuard VPN)
VPNサーバー (10.8.0.1)
├─ AdGuard Home (DNS広告ブロック)
├─ 192.168.11.0/24 → ローカル直接
└─ その他 → ProtonVPN経由
↓
インターネット
前提条件
- Ubuntu/Debian系Linux
- ProtonVPNアカウント
- グローバルIPまたはドメイン
1. システム準備
# システム更新
sudo apt update && sudo apt upgrade -y
# 必要なパッケージをインストール
sudo apt install curl wget unzip openvpn gnupg dnsutils iptables-persistent ufw -y
# IP Forwardingを有効化
sudo sysctl -w net.ipv4.ip_forward=1
echo "net.ipv4.ip_forward=1" | sudo tee -a /etc/sysctl.conf
2. ProtonVPN設定
2.1 OpenVPN設定ファイルの準備
ProtonVPN の OpenVPN 設定ファイルをダウンロードします。
# 作業ディレクトリを作成
mkdir -p ~/protonvpn-configs
cd ~/protonvpn-configs
手動作業:
- https://account.protonvpn.com/downloads にアクセス
- OpenVPN設定ファイル(標準サーバーの設定ファイル)をダウンロード
- サーバーにアップロード
# アップロード後、ファイル名を確認
ls ~/protonvpn-configs/*.ovpn
2.2 設定ファイルの最適化
設定ファイルを編集して、認証情報ファイルを使用するように変更します。
# 設定ファイルをバックアップ
cp ~/protonvpn-configs/*.ovpn ~/protonvpn-configs/original.ovpn.backup
# メインの設定ファイル名を統一
mv ~/protonvpn-configs/*.ovpn ~/protonvpn-configs/jp.protonvpn.udp.ovpn
# 設定ファイルを編集
sudo nano ~/protonvpn-configs/jp.protonvpn.udp.ovpn
編集内容:
-
auth-user-passを/root/protonvpn-configs/login.txtに変更 -
upとdownの行をコメントアウト
設定ファイルの例:
client
dev tun
proto udp
remote x.x.x.x x
remote x.x.x.x x
remote x.x.x.x x
remote x.x.x.x x
remote x.x.x.x x
remote-random
resolv-retry infinite
nobind
cipher AES-256-GCM
setenv CLIENT_CERT 0
tun-mtu 1500
mssfix 0
persist-key
persist-tun
reneg-sec 0
remote-cert-tls server
auth-user-pass /root/protonvpn-configs/login.txt
script-security 2
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
<ca>
(証明書の内容はそのまま)
</ca>
key-direction 1
<tls-auth>
(TLS認証キーの内容はそのまま)
</tls-auth>
2.3 認証情報ファイル作成
ProtonVPN の認証情報を保存するファイルを作成します。
# 認証情報ファイルを作成
nano ~/protonvpn-configs/login.txt
https://account.protonvpn.com/account-password の OpenVPN / IKEv2 ユーザー名 とパスワードを以下の形式で記入します(実際の認証情報に置き換え):
your_openvpn_username
your_password
# パーミッション設定
chmod 600 ~/protonvpn-configs/login.txt
2.4 ProtonVPN systemdサービス作成
ProtonVPN を systemd サービスとして設定し、自動起動できるようにします。
# サービスファイルを作成
sudo nano /etc/systemd/system/protonvpn.service
以下を記入:
[Unit]
Description=ProtonVPN OpenVPN Connection
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
ExecStart=/usr/sbin/openvpn --config /root/protonvpn-configs/jp.protonvpn.udp.ovpn
Restart=no
KillMode=process
[Install]
WantedBy=multi-user.target
注意:
ExecStartのjp.protonvpn.udp.ovpnは実際のファイル名に書き換えてください
# サービスを有効化・起動
sudo systemctl daemon-reload
sudo systemctl enable protonvpn
sudo systemctl start protonvpn
# 接続確認
sudo systemctl status protonvpn
ip a | grep tun0
curl https://api.ipify.org
curl https://api.ipify.org で ProtonVPN の IP アドレスが表示されれば成功です。
3. AdGuard Home設定
3.1 systemd-resolvedを無効化
AdGuard Home を DNS サーバーとして使用するため、systemd-resolved を無効化します。
# systemd-resolvedを停止
sudo systemctl stop systemd-resolved
sudo systemctl disable systemd-resolved
# resolv.confを作成
sudo rm /etc/resolv.conf
sudo nano /etc/resolv.conf
以下を記入:
nameserver 127.0.0.1
nameserver 1.1.1.1
nameserver 8.8.8.8
# 変更不可にする(systemd-resolvedが上書きしないように)
sudo chattr +i /etc/resolv.conf
3.2 AdGuard Homeインストール
AdGuard Home をインストールします。
# AdGuard Homeをインストール
curl -s -S -L https://raw.githubusercontent.com/AdguardTeam/AdGuardHome/master/scripts/install.sh | sh -s -- -v
3.3 初期設定
ブラウザで http://server-ip:3000 にアクセスして初期設定を行います:
-
Admin Web Interface: ポート
80に変更 -
DNS Server: ポート
53のまま - Admin Account: ユーザー名とパスワードを設定
- 完了
3.4 DNSの設定
管理画面 (http://server-ip/) にログイン後、DNSの設定をします。
Settings → DNS settings に移動:
Upstream DNS servers:
https://dns.cloudflare.com/dns-query
https://dns.google/dns-query
1.1.1.1
8.8.8.8
Bootstrap DNS servers:
1.1.1.1
8.8.8.8
Rate limit: 0 に設定
Apply をクリック
3.5 ブロックリストの設定
Filters → DNS blocklists に移動:
Add blocklistからお好みのフィルタを設定してください。
4. WireGuard VPNサーバー設定
4.1 WireGuardインストール
WireGuard をインストールします。
sudo apt install wireguard -y
4.2 サーバー鍵の生成
WireGuard サーバーの鍵ペアを生成します。
cd /etc/wireguard
umask 077
# サーバーの秘密鍵を生成
sudo wg genkey | sudo tee /etc/wireguard/server_private.key
# サーバーの公開鍵を生成
sudo cat /etc/wireguard/server_private.key | wg pubkey | sudo tee /etc/wireguard/server_public.key
# 鍵の表示(後で使用するためメモしておく)
sudo cat /etc/wireguard/server_private.key
sudo cat /etc/wireguard/server_public.key
4.3 サーバー設定ファイル作成
WireGuard サーバーの設定ファイルを作成します。
sudo nano /etc/wireguard/wg0.conf
以下を記入(SERVER_PRIVATE_KEYを実際の鍵に置き換え):
[Interface]
PrivateKey = SERVER_PRIVATE_KEY
Address = 10.8.0.1/24
ListenPort = 51820
SaveConfig = false
PostUp = iptables -A FORWARD -i wg0 -o eth0 -d 192.168.11.0/24 -j ACCEPT; iptables -A FORWARD -i eth0 -o wg0 -s 192.168.11.0/24 -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -d 192.168.11.0/24 -o eth0 -j MASQUERADE; iptables -A FORWARD -i wg0 -o tun0 ! -d 192.168.11.0/24 -j ACCEPT; iptables -A FORWARD -i tun0 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -A POSTROUTING -s 10.8.0.0/24 ! -d 192.168.11.0/24 -o tun0 -j MASQUERADE
PostDown = iptables -D FORWARD -i wg0 -o eth0 -d 192.168.11.0/24 -j ACCEPT; iptables -D FORWARD -i eth0 -o wg0 -s 192.168.11.0/24 -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.8.0.0/24 -d 192.168.11.0/24 -o eth0 -j MASQUERADE; iptables -D FORWARD -i wg0 -o tun0 ! -d 192.168.11.0/24 -j ACCEPT; iptables -D FORWARD -i tun0 -o wg0 -m state --state RELATED,ESTABLISHED -j ACCEPT; iptables -t nat -D POSTROUTING -s 10.8.0.0/24 ! -d 192.168.11.0/24 -o tun0 -j MASQUERADE
この設定により:
- ローカルネットワーク(192.168.11.0/24)への通信は直接接続
- その他の通信は ProtonVPN(tun0)経由
4.4 ファイアウォール設定
UFW で必要なポートを開放します。
# UFWの設定
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 51820/udp
sudo ufw allow 80/tcp
sudo ufw enable
# 状態確認
sudo ufw status
4.5 WireGuard起動
WireGuard を起動します。
# WireGuardを起動
sudo systemctl enable wg-quick@wg0
sudo systemctl start wg-quick@wg0
# 状態確認
sudo systemctl status wg-quick@wg0
sudo wg show
ip a | grep wg0
5. クライアント追加スクリプト
クライアントを簡単に追加できるスクリプトを作成します。
5.1 スクリプト作成
sudo nano /usr/local/bin/wg-add-peer.sh
以下のスクリプトを記入:
#!/usr/bin/env bash
# WireGuard クライアント追加スクリプト
# 目的:
# - 機器名を指定してクライアント鍵生成と wg0.conf へのコメント付き追記
# - wg0 インターフェースを自動クリーンアップ後に再起動
# - Endpoint(サーバーのグローバルIPまたはFQDN)を必須引数に変更
#
# 使い方:
# sudo ./wg-add-peer.sh <endpoint> <device_name> [client_ip_last_octet]
# 例: sudo ./wg-add-peer.sh 203.0.113.10 client0
# sudo ./wg-add-peer.sh vpn.example.com laptop01 23
set -euo pipefail
# ============ 環境設定 ======================================
WG_IFACE="wg0"
SERVER_CONF="/etc/wireguard/${WG_IFACE}.conf"
WG_DIR="/etc/wireguard/${WG_IFACE}"
CLIENT_CONF_DIR="/etc/wireguard"
SERVER_PRIV="/etc/wireguard/wg0/server.key"
SERVER_PUB="/etc/wireguard/wg0/server.pub"
ENDPOINT_PORT="51820"
TUN_NET_BASE="10.8.0"
TUN_NET="${TUN_NET_BASE}.0/24"
LAN_NET="192.168.11.0/24"
CLIENT_DNS="10.8.0.1"
# =============================================================
usage() {
echo "使い方: sudo $0 <endpoint> <device_name> [client_ip_last_octet]"
echo " 例: sudo $0 203.0.113.10 client0"
echo " sudo $0 vpn.example.com laptop01 23"
exit 1
}
require_root() {
if [[ $EUID -ne 0 ]]; then
echo "このスクリプトは root で実行してください。" >&2
exit 1
fi
}
check_prereqs() {
command -v wg >/dev/null 2>&1 || { echo "wg コマンドが見つかりません。wireguard-tools をインストールしてください。"; exit 1; }
[[ -f "$SERVER_CONF" ]] || { echo "サーバ設定が見つかりません: $SERVER_CONF"; exit 1; }
[[ -f "$SERVER_PRIV" ]] || { echo "サーバ秘密鍵が見つかりません: $SERVER_PRIV"; exit 1; }
if [[ ! -f "$SERVER_PUB" ]]; then
umask 077
wg pubkey < "$SERVER_PRIV" > "$SERVER_PUB"
chmod 644 "$SERVER_PUB"
fi
mkdir -p "$WG_DIR" "$CLIENT_CONF_DIR"
chmod 700 /etc/wireguard
}
ensure_saveconfig_false() {
if grep -qE '^\s*SaveConfig\s*=' "$SERVER_CONF"; then
sed -i -E 's/^\s*SaveConfig\s*=.*/SaveConfig = false/' "$SERVER_CONF"
else
awk 'BEGIN{done=0}
/^\[Interface\]/{print; print "SaveConfig = false"; done=1; next}
{print}
END{if(done==0) print "[Interface]\nSaveConfig = false"}' "$SERVER_CONF" > "${SERVER_CONF}.tmp" && mv "${SERVER_CONF}.tmp" "$SERVER_CONF"
fi
}
cleanup_wg_iface() {
echo "=== wg0 のクリーンアップ ==="
wg-quick down "${WG_IFACE}" 2>/dev/null || true
ip addr flush dev "${WG_IFACE}" 2>/dev/null || true
ip link del "${WG_IFACE}" 2>/dev/null || true
systemctl reset-failed "wg-quick@${WG_IFACE}" 2>/dev/null || true
}
find_free_ip_last_octet() {
local used last
used=$(grep -hoE "AllowedIPs\s*=\s*${TUN_NET_BASE}\.[0-9]+/32" "$SERVER_CONF" 2>/dev/null \
| grep -oE "${TUN_NET_BASE}\.[0-9]+" \
| awk -F. '{print $4}' | sort -n | uniq)
for last in $(seq 2 254); do
if ! grep -q -w "$last" <<< "$used"; then
echo "$last"
return 0
fi
done
echo "10.8.0.2〜254 に空きIPがありません。" >&2
exit 1
}
append_peer_to_server_conf() {
local name="$1" ip="$2" pub="$3" psk="$4"
ensure_saveconfig_false
{
echo ""
echo "# ${name}"
echo "[Peer]"
echo "PublicKey = ${pub}"
[[ -n "$psk" ]] && echo "PresharedKey = ${psk}"
echo "AllowedIPs = ${TUN_NET_BASE}.${ip}/32"
} >> "$SERVER_CONF"
}
reload_wg() {
echo "=== WireGuard を再起動(コメント保持モード) ==="
cleanup_wg_iface
systemctl enable --now "wg-quick@${WG_IFACE}"
echo "WireGuard 再起動完了。"
}
main() {
require_root
[[ $# -lt 2 || $# -gt 3 ]] && usage
local ENDPOINT_HOST="$1"
local NAME="$2"
local LAST_OCTET="${3:-}"
if [[ -z "$ENDPOINT_HOST" ]]; then
echo "エラー: Endpoint (サーバーのIPまたはFQDN) は必須です。" >&2
usage
fi
check_prereqs
# クライアントIP決定
if [[ -z "$LAST_OCTET" ]]; then
LAST_OCTET="$(find_free_ip_last_octet)"
else
if ! [[ "$LAST_OCTET" =~ ^[0-9]+$ ]] || (( LAST_OCTET < 2 || LAST_OCTET > 254 )); then
echo "不正な末尾: $LAST_OCTET(2〜254)" >&2; exit 1
fi
if grep -q "AllowedIPs\s*=\s*${TUN_NET_BASE}\.${LAST_OCTET}/32" "$SERVER_CONF"; then
echo "既に使用中のIPです: ${TUN_NET_BASE}.${LAST_OCTET}" >&2; exit 1
fi
fi
local CLIENT_TUN_IP="${TUN_NET_BASE}.${LAST_OCTET}"
# 鍵生成
local KEY="${WG_DIR}/${NAME}.key"
local PUB="${WG_DIR}/${NAME}.pub"
local PSK="${WG_DIR}/${NAME}-preshared.key"
umask 077
wg genkey | tee "$KEY" >/dev/null
<"$KEY" wg pubkey | tee "$PUB" >/dev/null
wg genkey | tee "$PSK" >/dev/null
chmod 600 "$KEY" "$PSK"
chmod 644 "$PUB"
# 値読み込み
local CLIENT_PRIV CLIENT_PUB SERVER_PUB_KEY PSK_VAL
CLIENT_PRIV="$(cat "$KEY")"
CLIENT_PUB="$(cat "$PUB")"
SERVER_PUB_KEY="$(cat "$SERVER_PUB")"
PSK_VAL="$(cat "$PSK")"
# クライアント設定出力
local CLIENT_CONF="${CLIENT_CONF_DIR}/${NAME}.conf"
cat > "$CLIENT_CONF" <<EOF
# ${NAME} (generated $(date -Iseconds))
[Interface]
Address = ${CLIENT_TUN_IP}/32
DNS = ${CLIENT_DNS}
PrivateKey = ${CLIENT_PRIV}
[Peer]
PublicKey = ${SERVER_PUB_KEY}
PresharedKey = ${PSK_VAL}
AllowedIPs = 0.0.0.0/0
Endpoint = ${ENDPOINT_HOST}:${ENDPOINT_PORT}
PersistentKeepalive = 25
EOF
chmod 600 "$CLIENT_CONF"
append_peer_to_server_conf "$NAME" "$LAST_OCTET" "$CLIENT_PUB" "$PSK_VAL"
reload_wg
echo "=== 追加完了 ================================"
echo "Endpoint : ${ENDPOINT_HOST}:${ENDPOINT_PORT}"
echo "デバイス名 : ${NAME}"
echo "クライアントIP : ${CLIENT_TUN_IP}/32"
echo "クライアントconf : ${CLIENT_CONF}"
echo "公開鍵ファイル : ${PUB}"
echo "事前共有鍵ファイル : ${PSK}"
echo "サーバ設定 : ${SERVER_CONF} に追記済み (# ${NAME} ブロック)"
echo "============================================="
echo -n -e "\n"
echo "${CLIENT_CONF_DIR}/${NAME}.conf"
echo -n -e "\n"
cat "$CLIENT_CONF"
}
main "$@"
# 実行権限を付与
sudo chmod +x /usr/local/bin/wg-add-peer.sh
5.2 サーバー鍵の配置
スクリプトが使用するサーバー鍵を適切な場所に配置します。
# ディレクトリを作成
sudo mkdir -p /etc/wireguard/wg0
# 既存の鍵をコピー
sudo cp /etc/wireguard/server_private.key /etc/wireguard/wg0/server.key
sudo cp /etc/wireguard/server_public.key /etc/wireguard/wg0/server.pub
# パーミッション設定
sudo chmod 600 /etc/wireguard/wg0/server.key
sudo chmod 644 /etc/wireguard/wg0/server.pub
5.3 クライアント追加
スクリプトを使用してクライアントを追加します。
# サーバーのIPまたはドメインを確認
MYIP=$(curl -s https://api.ipify.org)
echo "Server IP: $MYIP"
# または独自ドメインを使用
MYDOMAIN="vpn.yourdomain.com"
# クライアントを追加
sudo /usr/local/bin/wg-add-peer.sh $MYIP client1 2
# または
sudo /usr/local/bin/wg-add-peer.sh $MYDOMAIN client1 2
5.4 クライアント設定の確認
生成されたクライアント設定を確認します。
# クライアント設定を表示
sudo cat /etc/wireguard/client1.conf
6. 動作確認
6.1 サーバー側
すべてのサービスが正常に動作しているか確認します。
# すべてのサービス状態を確認
# ProtonVPN
sudo systemctl status protonvpn --no-pager
# AdGuard Home
sudo systemctl status AdGuardHome --no-pager
# WireGuard
sudo systemctl status wg-quick@wg0 --no-pager
sudo wg show
# ネットワークインターフェース確認
ip a | grep -E "tun0|wg0"
# 公開IP確認(ProtonVPNのIPが表示されるはず)
curl https://api.ipify.org
6.2 クライアント側
-
WireGuardアプリをインストール
- Windows/Mac/Linux: https://www.wireguard.com/install/
- Android: Google Play
- iOS: App Store
-
設定ファイル(
client1.conf)をインポート -
接続をオン
接続後、以下を確認:
# 公開IP確認(ProtonVPNのIPになる)
curl https://api.ipify.org
# 詳細情報
curl https://ipinfo.io
# DNS確認(AdGuard Home経由)
nslookup google.com
# ローカルネットワークへのアクセス
ping 192.168.11.1
# 広告ドメインのブロック確認
nslookup ads.google.com
# 0.0.0.0が返ればブロックされている(フィルタ設定による)
7. トラブルシューティング
ProtonVPN接続失敗
# ログ確認
sudo journalctl -u protonvpn -n 50
# 手動接続テスト
sudo openvpn --config /root/protonvpn-configs/jp.protonvpn.udp.ovpn
# tun0インターフェース確認
ip a | grep tun0
WireGuard接続失敗
# ログ確認
sudo journalctl -u wg-quick@wg0 -n 50
# ポート確認
sudo ss -tulpn | grep 51820
# ファイアウォール確認
sudo ufw status
sudo iptables -L INPUT -n -v | grep 51820
DNS解決失敗
# AdGuard Home状態確認
sudo systemctl status AdGuardHome
# DNS解決テスト
nslookup google.com 127.0.0.1
# resolv.conf確認
cat /etc/resolv.conf
8. 追加クライアントの作成
複数のクライアントを追加する場合:
# 2台目のクライアントを追加
sudo /usr/local/bin/wg-add-peer.sh $MYDOMAIN client2 3
# 設定確認
sudo cat /etc/wireguard/client2.conf
9. メンテナンス
サービスの再起動
# ProtonVPN再起動
sudo systemctl restart protonvpn
# AdGuard Home再起動
sudo systemctl restart AdGuardHome
# WireGuard再起動
sudo systemctl restart wg-quick@wg0
ログ確認
# ProtonVPN
sudo journalctl -u protonvpn -f
# AdGuard Home
sudo journalctl -u AdGuardHome -f
# WireGuard
sudo journalctl -u wg-quick@wg0 -f
接続中のクライアント確認
sudo wg show
以上で、WireGuard + AdGuard Home + ProtonVPN による VPN サーバーの構築が完了です。