2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WireGuard + AdGuard Home + ProtonVPN でVPNサーバーを構築する方法

Posted at

WireGuard + AdGuard Home + ProtonVPN でVPNサーバーを構築する方法

この記事では、AdGuard HomeProtonVPNWireGuard を組み合わせた 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

手動作業:

# アップロード後、ファイル名を確認
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 に変更
  • updown の行をコメントアウト

設定ファイルの例:

~/protonvpn-configs/jp.protonvpn.udp.ovpn
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-passwordOpenVPN / IKEv2 ユーザー名 とパスワードを以下の形式で記入します(実際の認証情報に置き換え):

~/protonvpn-configs/login.txt
your_openvpn_username
your_password
# パーミッション設定
chmod 600 ~/protonvpn-configs/login.txt

2.4 ProtonVPN systemdサービス作成

ProtonVPN を systemd サービスとして設定し、自動起動できるようにします。

# サービスファイルを作成
sudo nano /etc/systemd/system/protonvpn.service

以下を記入:

/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

注意: ExecStartjp.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

以下を記入:

/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 にアクセスして初期設定を行います:

  1. Admin Web Interface: ポート 80 に変更
  2. DNS Server: ポート 53 のまま
  3. Admin Account: ユーザー名とパスワードを設定
  4. 完了

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を実際の鍵に置き換え):

/etc/wireguard/wg0.conf
[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/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 クライアント側

  1. WireGuardアプリをインストール

  2. 設定ファイル(client1.conf)をインポート

  3. 接続をオン

接続後、以下を確認:

# 公開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 サーバーの構築が完了です。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?