PiVPNで想像よりも簡単にVPNサーバーが構築できました。オープンソースソフトウェアのWireGuardに対応しています。
各クライアントのWindowsやmacOS、iPhoneなどからアクセスするのに、WireGuardのGUIソフトウェアが使えるので便利です。
主にインストールと設定です。手順通りなら約30分程度です。
一箇所、VPNサーバー経由で自宅LAN環境へ接続する設定だけは、ネットワークの知識が少し必要かと思われます。そこだけ頑張れば、PiVPNならばサーバー構築はかなり簡単になったな、という印象です。
少し長くなってしまいましたが、興味がある人はお付き合いください。時間が無い人は最後のまとめ欄へ。
PiVPNについて
PiVPNは簡単なセットアップで高度な機能が使えます。
- OpenVPN2.4をサポート
- WireGuardをサポート
- 512ビットまでの楕円曲線暗号化キー
- Bitwardenと統合
- iOSキーチェーンのサポート
- 複数のDNSプロバイダーをサポート
- カスタムDNSサーバーをサポート
- カスタム検索ドメイン(OpenVPNのみ)
- Pi-Hole®で動作
Piと名前が付いていますが、Raspberry Pi以外でもDebian系で動作します。
WireGuardがサポートされていて、スマホやPCにも専用のクライアントソフトウェアがあります。総合的に導入が簡単で、VPNを張りやすいと感じたので選びました。
iPhoneでもWireGuard専用アプリを使うと、接続設定もQRコードを読み込むだけという手軽さです。
VPNサーバーとは
VPNはバーチャルプライベートネットワークの略です。仮想の専用線です。暗号化して通信します。
VPNのメリットは、出先のPCやスマホを仮想的に自宅内LAN環境へ接続できます。
外から自宅のデータにアクセスが可能になります。仮にプリンターがネットワーク内にあれば、それもあたかも家のPCを操るように利用できます。
コロナ禍になってからよく言われる「リモートワーク」「テレワーク」を安全に行うことができます。
外部から暗号化して自宅に通信できる、とイメージしてください。
VPNサーバー構築の流れ
VPNサーバーとして稼働させるのに、ザッと次のような流れです。
- Raspberry Pi OSのインストール
- Raspberry Piを固定IPアドレスにする
- ルーターの設定が必要
- ダイナミックDNSサービスへ登録
- ダイナミックDNSのIPアドレス更新用ファイルの作成
- PiVPNのインストール
- PiVPNに接続するクライアントの登録
- 各OSに用意されているクライアントソフト(Wireguard)を利用
(スマホアプリ、macOS用アプリ、Windows10用など)
ほとんどはRaspberry Pi OSとPiVPNのインストールのみで完了します。
Raspberry Pi OSのインストール

ここはいつも通りにmicroSDカードへ書き込んでから起動するだけです。
Raspberry PiにインストールするOSは、本来はRaspberry Pi OS Liteが望ましい。サーバーなのでデスクトップは必要ありません。
しかし、通常のRaspberry Pi OSも対応していました。
キーボードなどを繋いでインストールの設定作業するのは、より敷居が下がりますね。テストも兼ねているので、通常のRaspberry Pi OS(フルではない)で試してみました。
Raspberry Pi 4Bにインストールしましたが、3B+でも良いでしょう。
ラズパイのIPアドレスは固定する
ラズパイダでもRaspberry Piの固定IPアドレスはdhcpcd.conf
を編集すると記事にしました。今回はPiVPNのセットアップウィザードで設定ができてしまいました、(拍子抜け!)
そのため、PiVPNのインストール内でご紹介します。
ちなみに、分かりやすく192.168.0.61
としました。後ほど。
ルーターの設定
恐らく一番厄介なのが、このルーターの設定でしょう。ポート開放をするからです。
「ポートフォーワーディング」と言います。パケットフィルタとも少し違います。この辺の名前もややこしいですね。
外部から自宅のルーターへ接続する場合、基本は全て通りません。
ポートフォーワーディングは、これをRaspberry Piで構築したVPNサーバーへ通信を通すための設定です。
予め決められた相手(クライアント)から、決まったポートに届いた通信を、これまた決められたVPNサーバーに通すことを設定します。
ルーターのメーカーによって設定メニューが異なります。メニュー名も少し異なります。
NEC製のAtermの例
ルーターの管理画面に入り設定します。

- ここのLAN側ホストにある「192.168.0.61」はRaspberry Pi を固定IPアドレスにした時に決めたIPアドレスです。
- プロトコルはUDPです。
- ポート番号はWireguardのデフォルトである「51820」にしてあります。
この場合、外から来たポート51820番の通信は、家庭内ネットワークに置いたRaspberry Pi (PiVPNサーバー)であるIPアドレス「192.168.0.61」に転送されます。
DDNSサービスの登録
ほとんどの人は、自宅のインターネット環境がパブリックIPアドレスを割り振られていません。時々、自宅のIPアドレスは変更されてしまい、外出先から特定して接続できません。(できるけど変更される)
これを回避するには、擬似的にパブリックIPとして機能させるためダイナミックDNSサービスに登録します。無料で可能です。
以前に「DuckDnsでopenmediavaultをSSL化してみた」でも触れたように、duckdnsを使いました。

有名なのはno-ipでしょうか。

ダイナミックDNS(=DDNS)は、ラズパイ側にインストールした更新用クライアントソフトとDDNSサービスを連携させ、自宅のIPアドレスが変更になっても、DDNSサービス側でIPアドレスを更新します。
アクセスするためのアドレスは、任意で設定したドメイン名でOKというわけです。ドメインは「○○○.com」であっても、実際はIPアドレスという番号なんです。(210.xxx.xxx.xxx)
このIPアドレスが変更になったとしても、○○○.comへ繋げばOKという形にしてあげます。
DDNSの更新用ファイルを作成する(またはソフトをインストール)
サービスによっては専用ソフトなどがあります。今回は、無料のダイナミックDNSサービスを使いましたので、そのサービスに従います。
他にddclientなどのソフトを使う手もあります。今回はパス。
DuckDNSを利用しました。サイトにあるように、スクリプトファイルを作成し、それをcronで更新する方法を取ります。
とても簡単に設定できます。

サイトにあるinstallの項目でOSにpiを選び、最下部の自分のサブドメインをプルダウンメニューから選択すれば、ズラズラっと設定すべき内容が表示されます。

ここに書かれているようにコマンドを打って準備します。
shファイルの作成
homeにフォルダを作成し、スクリプト(.sh)ファイルを新規作成します。
mkdir duckdns<br>cd duckdns<br>nano duck.sh
shファイルに以下を記述。サイトからコピペします。
echo url="https://www.duckdns.org/update?domains=ここに自分で決めたサブドメイン&token=トークン&ip=" | curl -k -o ~/duckdns/duck.log -K -
「ここに自分で決めたサブドメイン&token=トークン」は自分の環境になっていますか?
保存します。(ctrl + o → Enter→ ctrl + x)
作成したshファイルに権限を与えます。自分だけ実行できる700です。
chmod 700 duck.sh
cronに更新させる設定をします。
crontab -e
*/5 * * * * ~/duckdns/duck.sh >/dev/null 2>&1
保存します。(ctrl + o → Enter→ ctrl + x)
この記述の意味は、「5分毎にホームフォルダにあるduck.shを実行して、標準の出力エラーも標準の出力結果も合わせて捨てる(無くす)」となり、結果として実行後はターミナルに何も表示されないということです。
0: 標準入力
1: 標準出力
2: 標準エラー出力
cronは日時などの記述方法、書き方というフォーマットが特殊なので、個別に調べてください。

参考までに実際のターミナル
実行テスト
作成した場所で実行。
./duck.sh
ログで確認する。
cat duck.log
「OK」とだけ出ていました。
サービスに登録
設定した5分毎に実行できるようcronのサービスをスタートさせます。
sudo service cron start
これで登録が完了しました。

ここまでで事前準備は完了です。次からはPiVPNをインストールして仕上げます。
PiVPNのインストール
大本命のPiVPNをインストールウィザードに従って進めます。
sshで接続するか、実機のターミナルから以下のコマンドでインストールできます。
curl -L https://install.pivpn.io | bash
または、以下でもOK。
curl https://raw.githubusercontent.com/pivpn/pivpn/master/auto_install/install.sh | bash
どちらかでインストールします。
セットアップウィザード
ターミナルでコマンドを実行するとウェルカムメッセージから始まります。

IPアドレスの固定
現在はDHCPサーバーから自動的に振られているという案内で、Yes/NoはNOがデフォルトです。
Yes → DHCPで自動的
No → 固定IPアドレスにする
固定IPアドレスにしたいので、<No>で進めます。

ここでは61で固定IPアドレス設定します。
dhcpd.confをイジらなくて済むのは便利です。

デフォルトゲートウェイの設定をします。つまり、ルーターのIPアドレスです。

ユーザー
初期状態ではユーザーpiしか選べません。
WireGuardのインストール
ここからWireGuardのインストールを行います。

今回はOpenVPNは選びません。
Raspberry Pi のkernelをアップグレード

Raspberry Pi OSをインストールした段階でFull-Upgradeしてあればスルーできます。
今回はしていなかったため、ここでアップデートとアップグレードを行いました。
再起動に、またこのウィザードに戻るには、最初のコマンドで同じように進めます。
curl -L https://install.pivpn.io | bash
同じ手順で進めますが、既にインストールした事などはサクサクっとスキップしてくれます。
ポートの設定
続きです。アップグレードした再起動後、同じように進めると、先程よりもスムーズに進んで、ポート番号の設定になります。
WireGuardのデフォルトポート番号は「51820」です。確認でYES。
DNSプロバイダー
DNSプロバイダーを設定します。Googleがリストにありました。チェックを入れるにはスペースキー押下です。

Tabキーで<ok>に移動しEnterです。
DNSの設定
パブリックIPはありませんから、事前に登録したDuckDNSなどを利用します。
ここでは上が自分のIPアドレス、下でDNS名を選びます。


ここで入力するのは、DuckDNSであれば、「(作成した任意の名前).duckdns.org」となります。
今回の例では「vpn-raspida.duckdns.org」

セキュリティアップデートの確認
インストール完了

以上でインストールは完了です。お疲れ様でした。
再起動後に有効になります。
この後、このPiVPNサーバーに接続するクライアント用の設定ファイルを作成して利用します。
setupVars.confファイルに記述されている
このウィザードで設定した内容は、setupVars.confに記述されています。
/etc/pivpn/wireguard
にあります。
このconfファイルを手動で変更も可能です。
PiVPNに接続するクライアントの登録
次に、外から使用するクライアントを登録します。
pivpn add
実行すると名前を聞かれます。分かりやすい任意の名前を決めます。
するとファイルが/home/pi/configs
内に決めた名前.confが生成されます。
これを各クライアントのソフト(ここではWireguard)にこのconfファイルをコピーして設定を読み込ませれば、アクセスが可能になります。
接続させるクライアントデバイス毎に1つずつ作成する形になります。(スマホ用、ノートパソコン用等)
生成したconfファイルは、アクセスできるすべての情報が記述されています。むやみにコピーやアクセスできる状態にしないでください。
外出先から接続
各OSに用意されているクライアントソフト(Wireguard)を利用すると簡単です。


QRコード生成
iPhoneなどのスマホでVPN接続する場合、QRコードとして出力することが可能です。
pivpn -qr
pi@pivpn:~ $ pivpn -qr
:: Client list ::
1) macbook
Please enter the Index/Name of the Client to show: 1
::: Showing client macbook below
クライアントを数字や名前で指定して実行します。(ここではテストとしてmacbookとしました)
ターミナル内にQRコードが表示されます。
あとはスマホのアプリから読み込ませるだけです。

起動後に自動起動させる
WireGuardを再起動しても自動起動させるには以下のコマンドを実行します。
sudo systemctl enable wg-quick@wg0
VPNサーバーから自宅LAN環境へ接続する設定
ただ、このままだとRaspberry Piで構築したVPNサーバーにしか接続できません。/etc/wireguard/
にあるインターフェイス設定を自宅の環境に合わせます。
この設定をしないと、VPNサーバーに接続だけしかできません。ちょっと大変ですけど、自分のネット環境に置き換えて、IPアドレスとその範囲(レンジ)の設定に気を配ってください。
うまく行かない場合のまとめ
IPアドレスなどは環境によっても異なります。
また、複数あるconfファイルなどの役割を間違えないようにしましょう。
ここに表でまとめておきます。自分の環境に置き換えて記述してください。
設定する表現名 | 何を表しているかの意味 |
---|---|
192.168.0.1など | 自宅のルーターアドレス メーカーによっては、デフォルトが192.168.1.1、192.168.11.1などがあります。 |
/etc/wireguard/wg0.conf | VPNサーバー側の設定ファイル |
/home/configs/○○.conf | クライアント側の設定ファイル |
/etc/pivpn/wireguard/setupVars.conf | セットアップウィザードで設定した内容 |
およそ、3つのconfファイルに間違いが無ければ問題ありません。
サーバー側のwg0.confに追記する
どうやらバーチャルのブリッジとしてwg0があります。サーバー側のwg0.confを修正します。
sudo nano /etc/wireguard/wg0.conf
引用元:githubの例
[Interface]
Address = 192.168.99.1/24
ListenPort = 51820
PrivateKey =
replace eth0 with the interface open to the internet (e.g might be wlan0 if wifi)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE
[Peer]
Client1
PublicKey =
AllowedIPs = 192.168.99.2/32
この中のInterfaceセクションにPostUp〜2行の記述が最初は存在していないと思いますので追記します。
追記する2行(有線LANケーブル接続の場合)
#replace eth0 with the interface open to the internet (e.g might be wlan0 if wifi)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o eth0 -j MASQUERADE; iptables -t nat -D POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
追記する2行(無線LAN接続の場合)
#replace eth0 with the interface open to the internet (e.g might be wlan0 if wifi)
PostUp = iptables -A FORWARD -i %i -j ACCEPT; iptables -A FORWARD -o %i -j ACCEPT; iptables -t nat -A POSTROUTING -o wlan0 -j MASQUERADE; iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
PostDown = iptables -D FORWARD -i %i -j ACCEPT; iptables -D FORWARD -o %i -j ACCEPT; iptables -t nat -D POSTROUTING -o wlan0 -j MASQUERADE; iptables -t nat -D POSTROUTING -s 10.0.0.0/24 -j MASQUERADE
注釈にもあるように、PiVPNを入れたRaspberry PiがルーターにWi-Fiでしか繋がっていないなら、eth0をwlan0に書き換えて追記します。
10.0.0.0/24の箇所は、バーチャルIPアドレスで指定したアドレスです。(デフォルトのバーチャルIPである10.6.0.0/24でも試しました。OKです)
IPアドレスレンジである10.0.0.0/24(10.6.0.0/24)、Raspberry Piを有線か無線か、どちらで接続しているかによってeth0(wlan0)は注意が必要です。
適用するため、wg0インターフェイスをdown、upさせます。
sudo wg-quick down wg0
sudo wg-quick up wg0
サービスをリスタートさせてもOKです。こちらの方がスムーズかな。
sudo systemctl restart wg-quick@wg0
もしくはRaspberry Piを再起動してもOKです。
クライアント側のconfファイルに追記する
接続するクライアント側のconfファイルにあるAllowedIPs =にも自宅のLAN環境を追加しておかないと自宅LAN内の他にまで届きません。
AllowedIPs = 10.6.0.0/32, 192.168.0.0/24
例として、192.168.0.0/24が自宅内LANのレンジです。(IPアドレスは環境によって置き換えてください)
自分のIPアドレスが、仮に192.168.11.20などであれば、レンジは192.168.11.0/24です。
クライアントがiPhoneなどのスマホであれば、スマホのWireGuardアプリの編集から、手動でAllowedIPsに自宅IPアドレスの範囲を追記してもOKです。
先にQRコードから読み込んでしまい、あとから/home/configs/○○.confに追記した場合は、改めてQRコードを発行して読み込ませないとなりません。

このiPhonのIPアドレス割り当てはバーチャルの2番です。1番がバーチャルのルーターです。
Allowed IPsは、デフォルトだと、0.0.0.0/0, ::0/0だったので、全部になっていました。これだと意味がありません。そのため自宅LANのIPアドレスのレンジに変更しました。
10.6.0.0/24は、サーバーの設定から自動的に決まっています。その後にカンマで192.168.0.0/24は追記しました。ファイルは/home/configs/○○.confです。○○は自分で付けたクライアント名です。
アプリで手動なら、右上の編集から書き換えできます。
PCやmacなど他のクライアントソフトウェアでは、クライアントソフトを入れたマシンにあるwg0.confです。
サーバーとクライアントの双方で異なった設定をしないとなりません。気をつけましょう。
個人用として運用
VPNサーバーの構築自体は、ラズパイにインストールするだけでほぼ完了です。あとは、このVPNサーバーを経由して自宅内の他のサーバーや機器にどう連携させるかだけです。
例として、私は自宅に音楽サーバーやファイルサーバーを稼働させています。それを外出先からでもアクセスできるようになりました。


名前解決できなかったから、音楽サーバーなどにはIPアドレスでアクセスしてね。
昔は法人用で個人では高かったVPN接続も、今ではRaspberry Piだけで構築できてしまいます。
現在ではVPN機能が付いたルーターも2万円程度で販売されています。
ファイルサーバーもそうですが、専用製品には敵わなくても、ラズパイで自分用VPNサーバー構築にトライしてみてください。
PiVPNでVPNサーバーの構築方法でした。
一応、動作し接続完了しました。もしも情報が足りないようでしたら、コメントください。
追記:/etc/sysctl.conf
にあるnet.ipv4.ip_forward=1
は、セットアップウィザードを完了しただけで有効になっていました。もしも無効ならば、コメント#を外して有効にしてください。
追記:ipv6の記述はしていません。ここではipv4だけです。
参考