Ubuntu Server 18.04 + SoftEther VPN + AdGuard Homeで広告ブロック機能付きVPNを構築する

どんなWi-Fiネットワークにいるときも広告をブロックしたいので、自前でAdGuard Home(DNSサーバ)とSoftEther VPN Serverを構築した。

しかし、Ubuntuではデフォルトでsystemd-resolvedがDNSサーバとして53/udpをListenしているので、自分で別のDNSコンテンツサーバを立ち上げる際にはこのStub Serverを止める必要がある。

さらにサーバ再起動後、VPNクライアントからのDNSリクエストが来た時、きちんとAdGuard Home DNSサーバに転送してくれないので、追加の設定が必要だった。

インストール(要約)

SoftEther VPN Server

SoftEther ダウンロードセンターから、「SoftEther VPN Server」「Linux」「Intel x64/AMD64 (64bit)」を選択してダウンロード。 また、ビルドに必要なパッケージもインストールして、ビルドを実行する。

sudo apt update
sudo apt install make gcc

wget https://github.com/SoftEtherVPN/SoftEtherVPN_Stable/releases/download/v4.32-9731-beta/softether-vpnserver-v4.32-9731-beta-2020.01.01-linux-x64-64bit.tar.gz
tar xvf softether-vpnserver-v4.32-9731-beta-2020.01.01-linux-x64-64bit.tar.gz

cd vpnserver
sudo make

sudo mv vpnserver/ /usr/local/
cd /usr/local/vpnserver

sudo chmod 600 *
sudo chmod 700 vpn*

次にシステム起動時に自動でSoftEtherも起動してほしいので、systemd用のUnitファイルも作成する。

sudo nano /etc/systemd/system/vpnserver.service
[Unit]
Description=SoftEther VPN Server
After=network.target network-online.target

[Service]
ExecStart=/usr/local/vpnserver/vpnserver start
ExecStop=/usr/local/vpnserver/vpnserver stop
Type=forking
RestartSec=3s

[Install]
WantedBy=multi-user.target

Unitファイルを作成したら、有効化する。

sudo systemctl daemon-reload
sudo systemctl enable vpnserver
sudo systemctl start vpnserver

AdGuard Home

GitHubのReleaseから最新版をダウンロードして、インストール。

ここでは/usr/local/adguardにインストールした。

wget https://github.com/AdguardTeam/AdGuardHome/releases/download/v0.100.9/AdGuardHome_linux_amd64.tar.gz
tar xvf AdGuardHome_linux_amd64.tar.gz

sudo mkdir /usr/local/adguard
sudo mv ./AdGuardHome/* /usr/local/adguard

これでAdGuard Home自体はインストールできたが、このままではsystemd-resolvedが起動したままなので、 53/udpをListenしていてAdGuard Homeが起動できない。

なのでUbuntu 18.04 の systemd-resolved で local DNS stub listener の利用をやめるに記述された無効化が必要。

まずは/etc/systemd/resolved.confを次のように編集。

[Resolve]
DNSStubListener=no

次に/etc/resolv.conf/run/systemd/resolve/resolv.confにリンク。

sudo rm /etc/resolv.conf
sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf

systemd-resolvedを再起動。

sudo systemctl restart systemd-resolved

これで53/udpが解放されたので、AdGuard Homeが起動できるはず。

cd /usr/local/adguard
sudo ./AdGuardHome -s install

ここでシステムを再起動しても自動でnetplanの設定内容が/etc/resolv.confに反映される。

ネットワーク設定と初期設定

AWSやGCPなどを利用している場合、ネットワーク・セキュリティの設定で、外部に開放するポートを設定する必要がある(私はAWS Lightsailで行った)。

SoftEther VPNで使うポートと、AdGuard Homeの管理ページのポートを開放しておく。

DDoS攻撃の踏み台にされる可能性があるので、外部に向けて53/udpの開放はしない。

ブラウザからAdGuard Homeの初期設定等を行っておく。

あとはSoftEther VPN Server Manager for WindowsかコマンドラインでVPNサーバを設定する。

接続するユーザとパスワードを作成し、Secure NAT機能を有効にしておく(VPNクライアントにDHCPでDNSサーバ情報を配布するため)。

SoftEther VPNクライアントからのDNSリクエストが広告ブロックできない現象への対応

カーネルのアップデートで再起動した後にクライアントからVPN接続すると、 SoftEtherでSecure NATで自分(デフォルトでは192.168.30.1)をDNSサーバに指定しているのに、ブロックがきかない現象が発生した。

AdGuard Homeのログにも出ないので、もしかしたらSoftEtherのSecure NATでは、起動時(または設定変更時)の/etc/resolv.confにあるDNSサーバにクエリーを転送しているのかもしれない。

この仮説が正しいかどうかは確認していないが、試行錯誤の結果、以下の2通りの解決方法を発見した。

解決先1: netplan経由で/etc/resolv.confに自サーバを追加

上記のsystemd-resolvedのStub Serverを無効化した場合は、netplanの設定内容が/etc/resolv.confに(間接的に)反映される。

netplanではDHCPでアドレスを受け取る場合も、DNSサーバの情報を追加できるので、追加して設定する。

sudo nano /etc/netplan/50-cloud-init.yaml
network:
    version: 2
    ethernets:
        eth0:
            dhcp4: true
            match:
                macaddress: 06:15:3e:a7:4c:30
            set-name: eth0
            nameservers:
                addresses: [ 127.0.0.1 ]

下の2行が追加部分。

AWS Lightsailの場合、DHCPでAWS内のDNSサーバ(172.26.0.2など)が指定されるのだが、上記により127.0.0.1が優先DNSサーバに指定される。

確認するには、下記のコマンドを実行。

systemd-resolve --status
(中略)
         DNS Servers: 127.0.0.1
                      172.26.0.2

これでVPNクライアントからのDNSリクエストに対して、127.0.0.1が応答するようになる。

ちなみに、この設定を行うと、VPNクライアント以外のDNSリクエストもすべて127.0.0.1(AdGuard Home)に向くので、AdGuard Homeの管理画面でログを見ることができる。

解決先2: SecureNATで配布するDNSに、内部アドレスを指定する

AWSやGCPのように、サーバが直接グローバルIPアドレスを持っておらず、プライベートIPアドレスを持っている場合のみ使用可能な方法。

SoftEther VPN ServerのSecure NATの設定で、DNSサーバがデフォルトで192.168.30.1となっている部分をサーバのプライベートIPアドレス(172.26.0.57など)に指定すると、きちんと広告ブロックできる。

ただしプライベートIPアドレスが変更されるとSoftEtherの設定変更が必要。