🐙

Raspberry Pi に PiVPN をインストールして外から自宅環境へアクセス

2024/04/10に公開

Raspberry Pi にPiVPNをインストールし、外出先でも自宅ネットワークへアクセスできる環境を構築します。

PiVPNとは

PiVPNとは、Raspberry PiでOpenVPNやWireGuardのVPNサーバーをインストールスクリプトです。

普通にパッケージからWireGuardをインストールして設定する場合はそれなりの前提知識が必要ですが、PiVPNを用いれば簡単にセットアップできます。

前提条件

インストール

下記のコマンドを実行して、質問に答えるだけです。

curl -L https://install.pivpn.io | bash

インストールの設定メモを一部抜粋

  • VPN種類 : Wireguard
  • ポート : 51820
  • 固定IP or DNS Entry : DNS Entry

ドメイン設定

私の自宅のは固定IPではないため、DDNSサービスを利用します。
CloudflareでDDNSサービスを設定する場合は以下のスクリプトをCronで定期的に動かすようにします。

#!/bin/bash

# Forked by benkulbertis/cloudflare-update-record.sh
# CHANGE THESE
auth_email="youemail@com"            # The email used to login 'https://dash.cloudflare.com'
auth_key="xxxxxxxxx"   # Top right corner, "My profile" > "Global API Key"
zone_identifier="xxxxxx" # Can be found in the "Overview" tab of your domain
record_name=$1                                     # Which record you want to be synced

# DO NOT CHANGE LINES BELOW
ip4=$(curl -s -4 https://ipv4.icanhazip.com/)
ip6=$(curl -s -6 https://ipv6.icanhazip.com/)

# SCRIPT START
echo "[Cloudflare DDNS] $record_name, Check Initiated"

# Seek for the record
record4=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name&type=A" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json")
record6=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records?name=$record_name&type=AAAA" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json")

# Can't do anything without both record
count4=$(echo "$record4" | grep -Po '(?<="count":)[0-9]*' | head -1)
count6=$(echo "$record6" | grep -Po '(?<="count":)[0-9]*' | head -1)

if [[ $count4 == 0 || $count6 == 0 ]]; then
  >&2 echo -e "[Cloudflare DDNS] $record_name, Dual stack records do not exist, perhaps create them first?"
  exit 1
fi

# Set existing IP address from the fetched record
old_ip4=$(echo "$record4" | grep -Po '(?<="content":")[^"]*' | head -1)
old_ip6=$(echo "$record6" | grep -Po '(?<="content":")[^"]*' | head -1)

# Compare either one is the same
# NOTE: The script will update even one IP remains the same.
if [[ $ip4 == $old_ip4 && $ip6 == $old_ip6 ]]; then
  echo "[Cloudflare DDNS] $record_name, IPs have not changed."
  exit 0
fi

# Set the record identifier from result
record4_identifier=$(echo "$record4" | grep -Po '(?<="id":")[^"]*' | head -1)
record6_identifier=$(echo "$record6" | grep -Po '(?<="id":")[^"]*' | head -1)

# The execution of update
update4=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record4_identifier" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" --data "{\"id\":\"$zone_identifier\",\"type\":\"A\",\"proxied\":false,\"name\":\"$record_name\",\"content\":\"$ip4\",\"ttl\":1}")
update6=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$zone_identifier/dns_records/$record6_identifier" -H "X-Auth-Email: $auth_email" -H "X-Auth-Key: $auth_key" -H "Content-Type: application/json" --data "{\"id\":\"$zone_identifier\",\"type\":\"AAAA\",\"proxied\":false,\"name\":\"$record_name\",\"content\":\"$ip6\",\"ttl\":1}")

# The moment of truth
success4=$(echo "$update4" | grep -Po '(?<="success":)[^,]*' | head -1)
success6=$(echo "$update6" | grep -Po '(?<="success":)[^,]*' | head -1)

if [[ $success4 == "true" && $success6 == "true" ]]; then
  echo "[Cloudflare DDNS] $record_name, IPv4 address '$ip4' and IPv6 address '$ip6' has been synced to Cloudflare."
else
  >&2 echo -e "[Cloudflare DDNS] $record_name, Update failed. DUMPING RESULTS:\n$update4\n$update6"
  exit 1
fi

cronでの動かし方

4 5 * * MON sudo ./cloudflare-dns.sh your.domain.com 2>&1 >/home/pi/cloudflare-dns.log

ルーターのポート開け

自宅のルーターにて Raspberry Pi に対するポート転送を設定します。

クライアントプロファイル設定

VPNサーバー側の設定が完了したところで、クライアント用のプロファイルを作成します。PiVPNのコマンドを叩けば、簡単にプロファイルを作成できます。

pivpn add

プロファイルを作成できたら、そのプロファイルをスマートフォンに読み込ませます。Wireguardのアプリをインストールし、以下のコマンドでQRコード表示し、プロフィールを追加します。

pivpn -qr home

Written-By-Human-Not-By-AI-Badge-white

Discussion