※当サイトはアフィリエイト広告を利用しています
※当サイトはアフィリエイト広告を利用しています

【DIY】インターネットから隔離した監視カメラシステムを構築しました

DIY

※セキュリティの観点から画像は非掲載ですが、以下の仕組みを完全自作した記録になります!
Tapoの通信を独自解析:外へのNTP/DNS要求の挙動と対策
5秒さかのぼり録画:Ubuntuの共有メモリを活用した録画漏れ対策
WebRTC超低遅延化::iPadから0.5秒で玄関先を確認するストリーム分岐
YoutubeLive配信:外出先からのリアル動画の参照

監視カメラの便利さと前機種の故障

インターフォンが鳴ったけど、モニターに誰も映っていない
ときどき駐車場にパンの袋などが散らばっていることがある

というようなことがあって、玄関脇にWEBカメラを付けて監視カメラにしています。

付けていたのは、アトムテックのATOM Cam 2。

  • 日本の企業が販売
  • 防水
  • WiFi接続
  • 動作検知
  • クラウド保存(無料)

しばらく安定して動作していたのですが、ときどき固まる(電源OFF/ONで復旧)こともあったりして、いつの間にかクラウド保存が有料になってしまいました。

そしてとうとう電源が入らない状態に。。。

次機種の選定:Tapo C520WS

カメラに要求する機能は以下。

  • 動体検知
  • 防水
  • WiFi接続
  • 解像度は2K程度
  • 映像をDIYで処理したい

結果、TP-Link社のTapo C520WSにしました。

DIYについて、国内での情報は少なかったのですが、まあなんとかなるでしょう。

不安要素と決意:100%完全鎖国計画

ネットワークカメラは、攻撃者の『踏み台』にされたり、バックドアを仕掛けられてローカルネットワークに侵入されたりというリスクがあります。

高市早苗総理も心配していますね。

そして、TP-Link社はルーター製品でセキュリティ面の不信感がありました。

Yahoo!知恵袋にも心配する相談が。

tapoの防犯カメラを使ってるのですがセキュリティは大丈夫なのでしょうか?アカウントのパスワードがカメラのパスワードという認識で問題ない… – Yahoo!知恵袋
tapoの防犯カメラを使ってるのですがセキュリティは大丈夫なのでしょうか?アカウントのパスワードがカメラのパスワードという認識で問題ないですか? セキュリティ系に詳しくなくて、初歩的な質問かもしれません。

解決策は『鎖国』

カメラがインターネットに接続しているから問題が起きるわけで、インターネットと100%隔離してしまえば問題は起きないと考えられます。

隔離した環境でカメラを動作させる!これしかない!

構成の検討

『鎖国したシステム』のDIYのためには、カメラからの映像を処理するサーバーが必要です。

ラズパイの購入も考えましたが、すでにあるLinux機(Ubuntuサーバー)を活用することにしました。

Ubuntuサーバーに、Dockerで数個のシステムを動作させます。

サポートの塩対応、そして自力解析

Tapoがインターネットを通じてどういう情報をやり取りしているのか、TP-Linkに問い合わせしてみることに。

Tapoをローカルネットワークに接続する予定です。セキュリティを考慮して、必要なポートだけを解放したいのですが、どのポートを開放すればいいか教えてください

Tapoはインターネット接続が必須です。ポートを制限したネットワークでは使わないでください

・・・(うーん。親切さがまったくない)

自分で調べるしかありませんね。

カメラの購入

ということで、まずカメラを入手して、どういう通信を行っているのか調べることにしました。

どうせカメラを制御するコマンド(ONVIF)のお作法も調べなくちゃいけないし、サポートが役に立たないなら、まず購入するしかない。

ついでに、屋外で電源ケーブルを取り回すためのパーツも購入しておきました。

ネットワーク接続

スマートフォンにTapoアプリをインストールし、カメラと接続します。

ONVIFで動体検知を受け取るので、カメラに接続するためのアカウントを作成します。
ユーザとパスワードを設定しておきます。

通信の観測:Tapoの生態

まず、tapoが、インターネットで、どういう通信をしているのかを確認します。

Ubuntuサーバで、Tapoの通信を観測しました。

時刻合わせ

  • プロトコルはNTP 
  • NTPサーバーは本体にハードコーディング
  • 複数のNTPサーバのリストを持っている
観測したNTPサーバーリストの一部
TP-LINK GLOBAL INC. ntp.tplinkcloud.com?
コロラド大学ボルダー校(アメリカ)のNTPサーバーNetnod(スウェーデン)が運用する標準時サーバスウェーデン・ストックホルムのNTPサーバー

リストにあるNTPサーバと通信できない場合、NIST(アメリカ国立標準技術研究所)のサーバーを順番に名前解決しようとしていました。

謎の通信

  • TPLINKのクラウド(Alibaba Cloud) aps1-device-cloudgateway.iot.i.tplinknbu.com
  • HTTPS(443)通信内容はしっかり暗号化されていますね

インターネットを遮断すると、動体検知の通知がスマホアプリに届かなくなったので、謎の通信に動体検知情報が含まれていると思われます。

どういう情報を送受信しているのかは暗号化されているのでわかりませんでした。

インターネット接続の対策

時刻同期の要求

Tapoからの時刻要求は、Ubuntuサーバで受けて回答するようにしました。

NTPを返していますね、成功です。

Hostname                      NTP   Drop Int IntL Last     Cmd   Drop Int  Last
192.168.100.xxx                 1      0   -   -   129       0      0   -     -

謎の通信

こちらは放置です。

Alibaba CloudやNTPサーバに接続できなくなってから、15秒おきにDNSサーバに問い合わせを実行するようになりました。

何回かリトライしてあきらめるかと思いましたが、ずっと実行し続けています。
今回の環境では、Tapoの通信は外に出ていないのでインターネットへの影響はありませんが、『爆撃』に近いですね。

Tapoカメラがエラーで停止するような問題は起きていません。

だいたいわかったのでカメラを設置

ボックスに延長コンセントを入れるのですが穴に入らない・・

ボックスの穴の横に切れ目を入れました。

外壁のコンセントから電源を取って、カメラのコンセントもボックスに収納してから取り付けます。

ボックスの穴は、エアコンの穴を埋めるパテで埋めてあります。

検知の設定

検知する対象の設定はスマホアプリから設定可能です。

動体検知をONにすると、雨粒を検知することがわかりました。
豪雨のときにONVIFに検知がたくさん流れてきます。

動体検知:OFF
人物検知:ON
車両検知:ON

で運用します。

動画保存

当初、Ubuntuサーバーでカメラからの通知を待って録画を開始し、10秒間、動画を保存するようにしていました。

これだと、通信を受けてから録画を始めるので、録画が遅れることがありました。

改善策は『さかのぼり録画』

Ubuntuサーバの共有メモリ上に5秒の録画ファイルを常に複数作っておき、通知を受けたときに1つ前の録画ファイルとそのあとの3つの録画ファイルを繋げてNASに保存するようにしました。

recorder-1  | 2026-04-03 06:10:17 | 🚗 VEHICLE DETECTED: Starting record…
recorder-1  | 2026-04-03 07:36:21 | 🚗 VEHICLE DETECTED: Starting record…
recorder-1  | 2026-04-03 09:07:47 | 🚗 VEHICLE DETECTED: Starting record…

これで録画対象を漏らさず残せるようになりました。

録画ファイルは30日間保持する設定にしています。

外部からの確認

リアル動画

Tapoは2つのストリームを持っています
stream1:2K/1080p(高画質)
stream2:360p(低画質)

サーバに録画する動画はstream1を使用しています。
スマホで外部からリアルの映像を確認するときはそれほどの画質は必要ないので、stream2を使いました。

UbuntuサーバでTapoからのrtsp(stream2)を受信して、ffmpegでRTMPに変換してYoutubeに送信しています。
映像はコピーでいいのでUbuntuサーバに負荷をかけずに送れます、音声形式はpcm_alawなのでaacに変換する必要があります。

検知録画

検知通知は、Ubuntuサーバからntfyでスマホに通知を送っています。

録画データはNASにあるので、TailscaleでUbuntuサーバに接続して映像を確認しています。

深夜の人物検知は特に気になります。。

内部からのリアル映像確認

インターフォンが鳴って、相手をモニターの死角で確認できない時に、iPadでTapoカメラの映像を確認したいのですが、Youtubeだと起動に時間がかかりすぎ。

rtspでもVLCアプリの起動が必要なので、これも時間がかかる。

ということで、stream2をiPadからWebRTCで参照することにしました。

ところが、stream2をiPadから接続しようとすると、接続できません。

stream1は検知録画で、stream2はYoutubeで使っています。

Tapo側で各streamに接続できるのは1つだけのようです。

解決策として、Ubuntuサーバ側で、stream2をYoutubeとWebRTCに分配するようにしました。
分配はgo2rtc を使っています。

体感0.5秒ほどでiPad(WebRTC)で玄関先が見えるようになりました。

カメラの設定

カメラの設定は、スマートフォンのアプリで行ないます。

スマートフォンがTapoと同じローカルネットワークに接続しているときは、アプリでTapoに接続できるので、設定はそのときだけ可能になります。

未解決の問題

カメラの初期位置がズレる

カメラの『追跡』をONにしているため、Tapoが人物検知と車両検知で対象を追従してくれるのですが、元に戻るときに、少し位置がズレます。
1回のズレは少しなのですが、数回繰り返すとズレが大きくなります。

アプリの『パン・チルト』機能を使って、手動で位置を戻すようにしています。

YouTubeライブが数日おきに停止する

システム起動直後は完璧に配信がスタートするのですが、数日から1週間ほど連続運用すると、いつの間にかYouTube側の配信が停止してしまいます。

【発生時の状況】

  • YouTube側のステータス: YouTube Studioで見ると、通信状態は「良好」や「非常に良い」の緑ランプがついたままなのに、実際の映像が配信されなくなります。
  • Docker側の状態: コンテナは落ちておらず(Up状態のまま)、go2rtc も ffmpeg もプロセスは生きている状態。
  • これまでの対策と一時的な復旧法:  go2rtc を再起動してyoutube-liveを完全に停止させ、数秒待ってからyoutube-live (ffmpeg)を再起動すると、映像が復活します。

現状の運用

  1. 関連するDockerを停止→起動するシェルを作成
  2. 上記シェルをサーバーで毎日深夜に実行するようcronを設定

Youtube側の制約でライブ配信が停止するケースにも対応できるのですが、深夜までライブが止まってしまいます。とりあえず、この運用でしのいでいます。

まとめ

安価な構成で、完全鎖国状態の監視用カメラシステムを構築することができました。

Tapoの通信やONVIFの中身を解析するのに時間がかかりました。
膨大なログを自分の目で見るのはほぼ困難で、生成AIにはかなり助けてもらいました。

こういうシステム寄りの記事はときどき掲載するようになると思います。文字ばっかりでつまらないかもしれませんが、お役に立てば幸いです。

コメント

タイトルとURLをコピーしました