防犯カメラシステムの自作③~VPNを用いたリアルタイム映像視聴の環境構築~

 本投稿は,「防犯カメラシステム with Raspberry Pi」(←開発がすべて完了したら「開発物」にページを作成する予定)に関する投稿です.Tipsでの投稿は,内容ごとに分け,下記の通り分割して投稿してゆきます.

Reolink社製カメラ「RLC-1212A」の挙動確認
Raspberry PiへのPoE HATのセットアップ
③VPNを用いたリアルタイム映像視聴の環境構築(本投稿)
クラウドストレージへの動画ファイルの自動アップロード
クラウドストレージへの動画ファイルの自動アップロード+α
ウォルボックス内環境に対する温湿度センサとファン制御の実装
⑦人物など動体検知時におけるスマホへのプッシュ通知機能の実装(予定)

 本投稿では,「防犯カメラシステム with Raspberry Pi」に向けて,スマホなど外部ネットワークから,VPNを介してRaspberry Piにアクセスし,Raspberry Piと有線で接続された防犯カメラのリアルタイム映像を取得する方法を説明します.
 使用したRaspberry Piは,Pi 4 Model B 8GBです.OSは,Raspberry Pi OS(64bit)において執筆時点で最新バージョン(Debian 13 Trixieがベース.Release Date: 18 Jun 2026)を用いています.

目次

  1. 本投稿で使用するもの
  2. ネットワーク構成とコンセプト
  3. ネットワークの構築
    • Raspberry Piで扱う各ネットワークのローカルIPアドレスの設定
    • Raspberry PiのIPフォワードを有効化
    • WireGuardを用いたVPNの設定(サーバ:Raspberry Pi)
    • WireGuardを用いたVPNの設定(クライアント:スマホ)
      • IPv4のグロバルIPアドレスを用いる場合
      • IPv6のグロバルIPアドレスを用いる場合
    • Androidアプリ版WireGuard設定後の処理
  4. クライアントを新たに追加する場合

1. 本投稿で使用するもの

 筆者が自作しようとしている防犯カメラシステム全体ではなく,本投稿で扱った機材のみを,以下にあげる.

  • 防犯カメラ:Reolink社製 RLC-1212A
  • Raspberry Pi 4 Model B 8GB(Tips②[1]より,下記がセットアップ済み)
    • Waveshare社製 PoE HAT(B)
    • Raspberry Pi 4 Model B用のヒートシンク
  • micro SDカード×2枚
    • 防犯カメラに使用 (256GB,class10,UHS-1/U3,最大読込100MB/s)
    • Raspberry Piに使用(64GB,class10,UHS-1/U3,最大読込100MB/s)
  • PoEスイッチングハブ:TPLINK社製 TL-SG1005
  • LANケーブル×2本
    • ハブ―Raspberry Pi間の接続
    • ハブ―防犯カメラ間の接続
  • Reolink社のアプリ
    • PC用クライアントソフトのバージョン:v8.21.4
    • スマホアプリ(Android)のバージョン:v4.60.1.6.20260612
  • PC(Windows,家庭LANに接続した状態)
  • スマホ(Android)
  • WireGuard
    • VPN環境を構築するために,Raspberry Piおよび,アプリ版をスマホで使用
    • スマホアプリのバージョン:v1.0.20260315
  • スマホアプリ「Ping」
    • スマホから各ネットワークへの接続可否の状況確認に使用
    • スマホアプリのバージョン:v2.0.11
  • 家庭LANを構築しているルータ
    • VPNの設定をする際に,ポート開放またはIPv6フィルターの設定で扱う

2. ネットワーク構成とコンセプト

 自作した防犯カメラシステムにおけるネットワーク構成の概要を,図1に示す.

図1 自作する「防犯カメラシステム」のネットワーク構成

 図1に示したネットワークにおける通信の流れを説明する.

  1. スマホ(4G/5G)から,WireGuard(VPN)を用いてIPv6経由でルータのグローバルIPアドレス宛に,UDP/51820で送信する
  2. ルータは,IPv6フィルタ設定により,受信したUDP/51820パケットをRaspberry Piのwlan0(192.168.10.x)へ転送する
  3. Raspberry Pi(wlan0: 192.168.10.x)が受信し,その暗号化パケットを復号して,VPNが作る仮想ネットワークwg0(10.100.0.1)へと受け渡す.またここで,Rapberry Pi上の仮想ネットワークwg0とスマホ(仮想IPアドレス)との間にVPNトンネルが構築される
  4. Linuxカーネルが,IPフォワーディングとルーティングを行い,Raspberry Piのwg0: 10.100.0.1からeth0: 192.168.20.1へ,パケット転送を行う
  5. PoEスイッチングハブを介し,防犯カメラ(192.168.20.2)へとパケットが到達し,スマホはVPN経由で防犯カメラ映像を取得する

 自作する防犯カメラシステムにおいて,図1のようなネットワーク構成にした理由として,下記2つのコンセプトがある.

  • 頑健性:
    メーカーサーバに依存しないことで,その第三者のシステム障害/サービス終了があっても,連動して己のシステムまで停止しないようにする
  • 堅牢性:
    防犯カメラそのものは直接インターネットに接続せず,独立したLANに収容することで,防犯カメラ自体にバックドアが仕込まれていたり脆弱性があったりしても,セキュリティを保つ

 防犯カメラのリアルタイム映像の視聴には,ReoLink社製のスマホアプリ/PC用クライアントソフトを使用する.しかし筆者の運用では,図1に示した通り,通信にReolink社のP2Pサーバは利用しておらず,防犯カメラそのものはインターネット接続すらしていない.
 防犯カメラRLC-1212Aの物体検知は,クラウドAIによるものではなく,カメラ本体の処理によるエッジAIによるものである.そのため,防犯カメラRLC-1212A自体がインターネットに接続されていなくとも物体検知が可能である.Raspberry Piに,演算リソースの消費や発熱をさせて物体検知をさせることなく,物体検知が実現できる.

 VPNの構築には,WireGuardを用いた.
 他のツールとして,Tailscaleもあった.Tailscaleは環境構築が比較的に簡単であり,暗号化方式そのものはWireGuardである.しかし,クライアント(スマホ等)とRaspberry Piとの初回接続時の認証等には,Tailscaleサーバに依存することになる.コンセプトの1つである頑健性の観点と,そしてベンダーロックインを避ける思想から,TailscaleではなくWireGuardを用いた.

 自宅に居る際,スマホからのインターネットへのアクセスも,防犯カメラ映像の視聴も,スマホのWireGuard(VPN)をONと家庭LANへのWi-Fi接続をしたままで良い.つまりは,インターネットへアクセスする際は家庭LANにWi-Fi接続し,防犯カメラ映像の視聴時にはWi-Fiを切断しWireGuard(VPN)をONにするという切り替えを,いちいちしなくて良い.これはスプリットトンネルというものであり,特定の通信(192.168.20.2への通信)だけをVPN経由にし,その他の通信は直接インターネットに接続するようになっているためである.

3. ネットワークの構築

 1台のRaspberry Piにおける,無線LANと有線LANとの,それぞれの接続先と役割を説明する.
 無線LAN(Wi-Fi)は,家庭LANと接続する(例:192.168.10.xのネットワーク).そして有線LANは,家庭LANとは異なる,PoEハブを介して繋がる別のネットワークを構築する(例:192.168.20.xのネットワーク).
 そしてこのPoEスイッチングハブを介した別のネットワークにおいて,本投稿では,Raspberry PiのローカルIPアドレスに192.168.20.1を,防犯カメラに192.168.20.2を割り振る.

 PoEスイッチングハブを介したネットワークにおいて,Raspberry Piはの下記役割を担う.

  • VPNサーバ:
    スマホからのVPN通信を受け取り,PoEスイッチングハブのネットワークへ転送
  • ルータ:
    wlan0(192.168.10.x)とeth0(192.168.20.x)という異なるネットワーク間を接続する
  • ファイアウォール:
    nftablesまたはiptablesによる通信制御を設定すれば,ファイアウォールの役割も担わせることが可能.ただし本投稿を執筆した時点では,筆者はファイアウォールを実装していない

 この第3章では,下記の順で説明する.

  • 第3.1節:Raspberry Piで扱う,各ネットワークのローカルIPアドレスの設定
  • 第3.2節:ルータの役割を担わせるための,IPフォワードを有効化
  • 第3.3節:VPNサーバの役割を担わせるための,VPN設定
  • 第3.4節:クライアント(スマホ)のVPN設定を行う

 Raspberry Piのターミナルで,下記コマンドを打つ.これにより,家庭LANと無線LANでつながるwlan0と,PoEスイッチングハブと有線LANでつながるeth0の,接続名を確認する(図2).

nmcli connection show
図2 接続名の確認結果

 上記コマンドの結果において,TYPE欄にてethernetであるもののNAME欄が,有線LANの接続名である.例えば筆者の場合は, ”netplan-eth0” が有線LANの接続名となる(図2).
 この接続名を以て,PoEスイッチングハブのネットワークに向けたローカルIPアドレスを,eth0に設定する.

sudo nmcli connection modify "<your_network_name>" \
ipv4.method manual \
ipv4.addresses 192.168.20.1/24

 次に,eth0に対し,デフォルトゲートウェイの設定を削除する.
 この防犯カメラシステムでは,eth0は防犯カメラ専用の閉じたネットワークとして使用し,インターネットへの出口ではない.そのため,通信経路を明確化すると共に,誤ったルーティングが不要な外部通信を防止する目的で,意図的にeth0のデフォルトゲートウェイの設定を削除しておく.
 eth0のデフォルトゲートウェイの設定を削除するコマンドは,下記の通りである.

sudo nmcli connection modify "<your_network_name>" \
ipv4.gateway ""

 この防犯カメラシステムのeth0では名前解決を行う必要がなく,DNSも不要である.そのため,不要なDNS問い合わせや設定ミスによる通信を防止することと,インターフェース役割を最小限にすることを目的として,DNSの設定を削除する.
 eth0のDNSの設定を削除するコマンドは,下記の通りである.

sudo nmcli connection modify "<your_network_name>" \
ipv4.dns ""

 eth0の,ローカルIPアドレスの設定,デフォルトゲートウェイおよびDNSの設定を削除したら,下記コマンドでeth0を再起動する.

sudo nmcli connection down "<your_network_name>"
sudo nmcli connection up "<your_network_name>"

 設定が意図したとおり反映されているかの確認として,下記コマンドを実行する.inet 192.168.20.1/24と表示されれば成功である.

ip addr show eth0

 ここからは,防犯カメラのローカルIPアドレスの設定を行う.
 まずは設定を行い始める前に,防犯カメラが,正しいローカルIPアドレスを指定すれば通信できる状態にあるかを確認する.今はまだ家庭LANに接続され,ローカルIPアドレスが192.168.10.xの状態である防犯カメラに対し,PINGが通るかを確認する.PINGの確認は,Windows PCであれば,コマンドプロンプトにて下記のように防犯カメラのローカルIPアドレスを指定したコマンドを打てば,確認できる.

ping 192.168.10.x 

 Windows PCから,防犯カメラへ通信が通っていることをが確認できたら,PC用クライアントソフトから防犯カメラのローカルIPアドレスを静的に割り振る.PC用クライアントソフトから,カメラのネットワーク設定から,各項目を下記のように設定する.

  • 接続タイプ:静的
  • IPアドレス:192.168.20.2
    • PoEスイッチングハブを介したネットワークでのアドレス
  • サブネットマスク:255.255.255.0
  • ゲートウェイ:192.168.20.1
    • Raspberry Piのこと
  • DNS:静的DNS
  • 優先DNS:192.168.20.1

これら192.168.20.xのネットワーク(PoEスイッチングハブを介したネットワーク)としての防犯カメラの設定が完了したら,同じネットワークに接続されているRaspberry Piから,192.168.20.xのネットワークとしてPINGが実際に通るか確認を行う.
 Raspberry Pinターミナルから,下記のように,先ほど新たに設定した防犯カメラのローカルIPアドレスを指定したコマンドを打てば,確認できる.

ping 192.168.20.2

 Raspberry PiがIPフォワードの有効化を行う.下記に示したコマンドは,Raspberry Piが起動する度に,IPフォワード化を実行する処理を記述した.confファイルを,起動時に読み込まれる位置に作成している.
 ファイル名は任意で良い.筆者は,第3.2節で後述するVPN通信に関わるルーティングの設定であることから,ファイル名をwireguard.confとした.

sudo nano /etc/sysctl.d/wireguard.conf

 そして,作成した.confファイルの中に,以下のように記述し保存する.

net.ipv4.ip_forward=1

 ここで,Raspberry Pi起動時に自動的に.confファイルを読み込ませる処理において注意がある.
 Raspberry Pi OSのベースとなっているDebianにおいて,Debian 13 Trixieからは,/etc/sysctl.confのディレクトリは読み込まれなくなった[2].そのため,Debian 12 Bookworm以前のように,コマンド sudo nano /etc/sysctl.conf でファイル作成とディレクトリに格納しても,Debian 13 Trixieでは起動時に実行されず意図した挙動・通信がなされないトラブルを招く.

 上記でwireguard.confに書き込んだ内容をカーネルに反映させるべく,下記コマンドを実行する.
これらにより,Raspberry Piを再起動した後も,IPフォワードの有効化がなされる.

sudo sysctl --system

 実際に,Raspberry Piを再起動した後もIPフォワードの有効化がなされているかの確認は,再起動後に下記コマンドを実行すれば良い.実行結果が “1” であったなら,成功である.

sysctl net.ipv4.ip_forward

 VPNサーバの役割をRaspberry Piに担わせるべく,WireGuardのインストールおよび設定について説明する.Raspberry PiにWireGuardをインストールする前に,下記コマンドで最新パッケージの一覧を取得する.

sudo apt update

 次にWiredGuardのインストールを行う.

sudo apt install wireguard wireguard-tools

 WireGuardのバージョンを確認したい場合は,下記コマンドで確認できる.

wg --version

 ここからは,Raspberry Piの秘密鍵と公開鍵を作成する.まずは下記コマンドを使用し,ターミナル上で操作するディレクトリを,鍵の保存先のディレクトリへと移動する.

sudo su
cd /etc/wireguard

 秘密鍵を生成する.1行目のコマンドで秘密鍵を生成し,2行目のコマンドで権限の変更を行っている.権限の変更は,秘密鍵であるため,所有者のみが読み書き可能にしている.

wg genkey | sudo tee server_private.key
sudo chmod 600 server_private.key

 公開鍵を生成する.下記コマンドで,公開鍵を秘密鍵から生成する.

sudo cat server_private.key | wg pubkey | sudo tee server_public.key

 秘密鍵および公開鍵の中身を確認する方法は,それぞれ下記のコマンドで確認できる.

sudo cat server_private.key
cat server_public.key

 次に,WireGuardの設定ファイルである.confファイルの作成と設定を行う.ここではファイル名をwg0.confとした場合のコマンドを,以下に記載する.

sudo nano /etc/wireguard/wg0.conf

 作成したwg0.confファイルには,下記の通り記述する.スマホの公開鍵は,後述するスマホのWireGuardの設定にて作成される.

[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = <Piの秘密鍵>

[Peer]
PublicKey = <スマホの公開鍵>
AllowedIPs = 10.100.0.2/32
PersistentKeepalive = 25

 クライアントとしてスマホを扱い,スマホに対するWireGuardのインストールと設定について説明する.Androidアプリ版WireGuardにおいて,「空の状態から作成」をすると,図3の画面になる.

図3 Androidアプリ版WireGuardにおける「空の状態から作成」

 図3の各項目に対し,まずインターフェースの項目について説明する.下記に示した以外の項目は,空欄で良い.

  • 名前:<任意の名称>
    • アプリ上でこのネットワーク・接続を管理するための任意の名称
  • 秘密鍵:<スマホの秘密鍵>
    • 欄内の,円形の矢印アイコンをタップすると自動生成される
  • 公開鍵:<スマホの公開鍵>
    • スマホの公開鍵.秘密鍵と同時に自動生成される
    • 第3.3節で説明した,Raspberry Pi上のWireGuardにおける<スマホの公開鍵>には,この公開鍵を入力する
  • アドレス:10.100.0.2/32
    • VPNによるwg0のネットワークにおける,このスマホのアドレス.筆者は,10.100.0.2/32とした
    • 10.100.0.1は,サーバであるRaspberry Piのアドレスであり,クライアントの1台目からは10.100.0.xに,2以降を割り当ててゆけばよい

 次に,ピアの項目について説明する.

  • 公開鍵:<Piの公開鍵>
    • Raspberry Piの公開鍵を入力する
  • 持続的キープアライブ:10
    • Raspbeery Pi上のWireGuardにおけるPersistentKeepaliveと同義
    • 筆者は当初25[秒]に設定していた.しかしReolink社のスマホアプリから防犯カメラにアクセスした際に,映像データに圧迫されて生存確認パケットが遅延するのか,速度低下とカメラデバイスとの切断が頻発した
    • PCとPCクライアント用ソフトにおいては,25[秒]の設定でも,速度低下と切断は生じなかった
  • エンドポイント:
    • グローバルIPアドレス.ただし,IPv4とIPv6とで,この欄への記述の仕方や,家庭LANを構築しているルータに対する処理が異なる.詳細は後述する
  • Allowed IPs:10.100.0.0/24, 192.168.20.0/24

 エンドポイントにおけるグローバルIPについて説明する.
 IPv4グローバルアドレスを扱う場合は,家庭LANを構築しているルータにてポート開放する必要がある.これに対して,IPv6のグローバルアドレスを扱う場合は,同ルータにてポート開放ではなくIPv6フィルターの設定を行う必要がある.
 例えば筆者の場合は,使用しているインターネット回線がtansix方式であり.この場合,Raspberry PiやPCでコマンドを扱いIPv4のグローバルIPアドレスを確認しても,固定のIPv4のグローバルアドレスは割り振られていない.そのため,特定のIPv4のグローバルIPアドレスの指定とポート開放によるVPN接続はできず,IPv6のグローバルアドレスを用いる手法でVPNの設定を行った.
 IPv4とIPv6のそれぞれの場合での,エンドポイントの設定方法を,以下に記載する.

 前述の第3.4節で説明した,Androidアプリ版WireGuardにおけるエンドポイントの項目を,下記のように入力する.

  • エンドポイント:<wlan0のIPv4のグローバルIPアドレス>:51820
    • 例えばRaspberry Piのターミナルにて,curl -4 https://api.ipify.org と入力すると,IPv4のグローバルIPアドレスを確認できる

 家庭LANを構築しているルータにおける,ポート変換の一例を図4に示す.これは,使用しているルータによってUIや項目名等が異なる.図4における「LAN側IPアドレス」の項目に,Raspberry Piのwlan0のIPアドレス192.168.10.xを入力する.

図4 IPv4グローバルアドレスを用いる場合におけるポート変換の設定画面例

 前述の第3.4節で説明した,Androidアプリ版WireGuardにおけるエンドポイントの項目を,下記のように入力する.

  • エンドポイント:[<wlan0のIPv6のグローバルIPアドレス>]:51820
    • 例えばRaspberry Piのターミナルにて,curl -6 https://api.ipify.org と入力すると,IPv6のグローバルIPアドレスを確認できる
    • Androidアプリ版WireGuardでは,エンドポイント欄に [<wlan0のIPv6のグローバルIPアドレス>]:51820 の形式で入力すると,「エンドポイントの内容を解読できません」と表示され,編集内容を保存できなかった.そのため筆者は,別途PCのテキストエディタなどで.confファイルを作成し(.txtファイルで作成し,拡張子を書き換えれば良い),下記内容を入力した.confファイルを,Androidアプリ版WireGuardへインポートする方法で解決した
[Interface]
Address = 10.100.0.2/24
PrivateKey = <スマホの秘密鍵>

[Peer]
AllowedIPs = 10.100.0.0/24, 192.168.20.0/24
Endpoint = [<IPv6グローバルIPアドレス>]:51820
PersistentKeepalive = 25
PublicKey = <Piの公開鍵>

 家庭LANを構築しているルータにおける,IPv6フィルターの一例を図5に示す.これは,使用しているルータによってUIや項目名等が異なる.図5における「IPアドレス>宛先」の項目に,IPv6のグローバルアドレスを入力する.

図5 IPv6グローバルアドレスを用いる場合におけるIPv6フィルターの設定画面例

 第3.4.1項または3.4.2項の設定を完了したら,第3.3節で作成したRaspberry Pi上のwg0.confに対し,スマホの公開鍵を記入し保存する.そしてこのwg.confが,Raspberry Piの起動と共に実行されるよう,ターミナルにて下記コマンドを実行する.

systemctl enable wg-quick@wg0
systemctl start wg-quick@wg0
systemctl status wg-quick@wg0

 上記の3行のコマンドはそれぞれ順に,systemdへの登録,今すぐsystemd経由でWireGuardの起動,起動の確認を命令している.

 これらを完了することで,スマホからReoLinkアプリを用いて,直接はインターネット接続されていない防犯カメラの映像を視聴できるようになる.

4. クライアントを新たに追加する場合

 この第4章では,クライアントを追加する場合の,Raspberry Piでの操作を説明する.追加するクライアント側のWireGuardの設定は,第3.4節を参照されたし.

 Raspberry Piのターミナルにて,sudo nano /etc/wireguard/wg0.conf のコマンドを実行し,wg0.comfに追加クライアントをPeerとして加筆する.以下に示す例では,本投稿で説明したスマホ(Phone)に対し,新たにPCと家族のスマホを追加する場合である.

[Interface]
Address = 10.100.0.1/24
ListenPort = 51820
PrivateKey = <Piの秘密鍵>

[Peer]
# Phone
PublicKey = <スマホの公開鍵>
AllowedIPs = 10.100.0.2/32
PersistentKeepalive = 25

[Peer]
# PC
PublicKey = <PCの公開鍵>
AllowedIPs = 10.100.0.3/32
PersistentKeepalive = 25

[Peer]
# Family's Phone
PublicKey = <家族のスマホの公開鍵>
AllowedIPs = 10.100.0.4/32
PersistentKeepalive = 25

 変更したwg0.confの内容を反映させるために,ターミナルで下記コマンドを実行する.

sudo wg-quick down wg0
sudo wg-quick up wg0

 そして下記コマンドで,wg0.confの変更内容が反映されているかを確認する.加筆されたPeerの内容も表示されれば成功である.

sudo wg show

参考文献

  1. 防犯カメラシステムの自作②~Raspberry PiへのPoE HATのセットアップ~, word in the world, https://word-in-the-world.com/2026/08/02/securitycamera-02/, (参照2026-8-5).
  2. Issues to be aware of for trixie — release-notes documentationi, Debian Documentation Team, https://www.debian.org/releases/trixie/release-notes/issues.html#etc-sysctl-conf-is-no-longer-honored, (参照2026-8-5).