RaspberryPi4でLAN内のトラフィックを監視する
LAN内のトラフィックを監視する方法としては、SNMPやZabbixなどのOSSのツールを利用する方法が挙げられます。
各種いろいろググって検討しましたが、SNMPに対応しているスイッチやルーターを買い揃えないといけなかったり、OSSを使うにしても学習コストが高そうなことと、イマイチ私が監視したい内容だけを表示することが微妙に出来なさそうでした。
そして最終的にたどり着いた方法がこちら。といっても参考にしたのはネットワーク構成だけですが。
qiita.com
出来るだけお金を掛けずに実装しようとした結果、ほぼ自前でトラフィックを監視することになりました。
具体的にはスイッチに接続されている全てのポートのトラフィックをポートミラーリングでラズパイに集約し、tsharkでキャプチャすることでLAN内のトラフィックを監視します。
目標
- 機器ごとの一日あたりの通信量の合計を知りたい(1ヶ月、累計なども)
- 時間別の通信量のグラフ(見てて面白そう)
ネットワーク図
使用機器
ルーター:ソフトバンク 光BBユニット(J18V150.00)
私はソフトバンク光を契約しているのと、IPv4 over IPv6を利用するために光BBユニットを選択します。
スイッチ:TL-SG108E
TP-Linkあたりがコスパ良いですね。

TP-Link 8ポート 10/100/1000Mbps ギガビット イージー スマート スイッチ TL-SG108E
- 発売日: 2016/06/25
- メディア: Personal Computers
AP:Aterm WF800HP
我が家の間取りは1Kなのでこれぐらいのスペックでも、家の中ならどこでもフルHDの動画が止まらずに見れるぐらいの速度は出ます。
RaspberryPi4 メモリ4GB
ラズパイを買うときは電源やSDカードなどのラズパイに必要なものが全部セットになっているやつを選んでいます。
同じものを全て別々に買うとセット価格よりも全然高くなりそう。
外付けHDD:WDBBKG0040HBK-JESN
ラズパイに挿しているSDカードにデータを保存しまくるのはあまり気が進まないので、データ類は全て外付けHDDに保存するようにします。
選択肢は山程ありますが、なんとなく信頼できそうな内側も外側もWDのやつを買ってみました。

WD デスクトップHDD 4TB USB3.0 WD Elements Desktop 外付けハードディスク / WDBBKG0040HBK-JESN 2年保証
- 発売日: 2018/05/23
- メディア: Personal Computers
下準備
無線LANルーターをブリッジで接続
Wi-fiで接続している機器のトラフィックも監視するためには、WANに接続している無線LANルーターではなくスイッチに接続している無線LANルーターに接続させなければなりません。
その際はスイッチにブリッジモードで接続させます。
二重ルーターになってしまうので。
スイッチでポートミラーの設定
SG108EのIPアドレスはデフォルトだと192.168.0.1になっています。
User Name: admin
Password: admin
192.168.0.1がデフォルトになっている機器が重複して思うようにアクセス出来ないことがあるので、まずはスイッチとクライアントPCだけを接続してスイッチのIPアドレスを変更します。
ルーターがDHCPで割り当てる値の範囲外にしておくのが良いかもしれません。
ひとまず192.168.0.100とかに設定。
続いて左側のメニューからポートミラーの設定ページを開きます。
Monitoring > Port Mirror
Port Mirrorを「Enable」にして、Mirroring Portはラズパイを接続するポート番号に。
設定したあとに「Apply」ボタンを押して設定を有効にします。
次にポートミラーの対象を設定します。
このとき、ルーターを接続しているポートも選択することを忘れてはいけません。
ダウンロードのトラフィックをキャプチャできなくなります。
そのため、基本はMirrored Portでラズパイ以外の全てのポートを選択し、Ingressを「Enable」にします。
そしてまた「Apply」ボタンを押して設定を有効化。
これでスイッチの設定は終了です。
外付けHDDをマウント
ラズパイ4はUSB3.0が搭載されているので、そちらに接続します。
まずはfdiskでHDDを認識しているか確認。
pi@raspberrypi:~ $ sudo fdisk -l | grep /dev/sda -- Disk /dev/sda: 3.7 TiB, 4000752599040 bytes, 7813969920 sectors /dev/sda1 2048 7813967871 7813965824 3.7T Microsoft basic data
blkidでHDDのUUIDとファイルシステムを調べます。
pi@raspberrypi:~ $ sudo blkid /dev/sda1 -- /dev/sda1: LABEL="Elements" UUID="E63EBD053EBCD033" TYPE="ntfs" PTTYPE="atari" PARTLABEL="Elements" PARTUUID="f7475307-9179-4866-9d7f-dc632b4d2d17"
/mnt/hdd にHDDを自動マウントするように記述します。
pi@raspberrypi:~ $ sudo mkdir /mnt/hdd pi@raspberrypi:~ $ sudo vim /etc/fstab -- (略) UUID="E63EBD053EBCD033" /mnt/hdd ntfs defaults,nofail 0 0
追記したらラズパイを再起動して認識されていればOKです。
pi@raspberrypi:~ $ df -h | grep /dev/sda -- /dev/sda1 3.7T 24G 3.7T 1% /mnt/hdd
ラズパイのセットアップ
pi@raspberrypi:~ $ sudo apt update pi@raspberrypi:~ $ sudo apt upgrade pi@raspberrypi:~ $ sudo apt install tshark
トラフィック監視
LAN内の機器のIPアドレスとMACアドレスを特定
パケットをキャプチャしてもそこで見える情報はIPアドレスやMACアドレスだけなので、パッと見でどの機器がどれだけ通信しているのかが分かりません。
そこでIPアドレスとMACアドレス、そして機器名の一覧表を予め作っておくことで、IPアドレスに紐付いている機器名でデータを表示できるようにします。
方法としてはarpやnmapなどが考えられますが、どれも絶妙にLAN内の機器全てを表示してはくれないんですよね...
単純に1つ1つ手作業で調べて登録していくのが確実なような気がします。
IPアドレスが固定できるようなら固定してしまったほうがあとあと楽です。大した手間でもないので。
最後にブラウザで表示させるときにラクするために、機器名・IPアドレス・MACアドレスはデータベースに登録しておくことにします。
tsharkで10分ごとにパケットキャプチャ
テキトーなファイルに10分間だけパケットをキャプチャするコマンドを書いておきます。
pi@raspberrypi:~/ $ sudo vim startCapture.sh -- tshark -i eth0 -a duration:600 -w /mnt/hdd/trafficData/`date "+%Y%m%d%H%M"`.pcap
このスクリプトを10分間隔で実行するためにcrontabに記述しますが、イーサネットをキャプチャするにはroot権限である必要があります。
そのためrootのcrontabに記述します。
pi@raspberrypi:~/RoomManager $ sudo crontab -e -- */10 * * * * bash /home/pi/startCapture.sh
これで10分間eth0をキャプチャしたpcapファイルがHDDに保存されていきます。
データベースに機器ごとの通信量を挿入
scapyなどを使ってパケット解析する方法もありますが、面倒だったのでtsharkでTCPのconversationログを表示させ、IPアドレスごとのアップロードとダウンロードの値を機器名でデータベースに挿入していきます。
なお、tsharkのコマンドは以下の通り。
tshark -r hoge.pcap -z conv,tcp -q
pythonでtsharkのコマンドを実行し、良い感じにデータベースに突っ込みます。
このプログラムをpcapファイルが保存されたあとに実行されるようにcrontabに記述します。
pi@raspberrypi:~/RoomManager $ sudo crontab -e -- */10 * * * * bash /home/pi/startCapture.sh 1,11,21,31,41,51 * * * * /usr/bin/python3 /home/pi/traffic.py
ブラウザで機器ごとの通信量を表示
LAN内のどこからでも見れるようにするために、ラズパイにwebサーバを立てます。
ひとまず見れればいいやということで結構雑ではありますが、PHPでサクっと書きます。
わりとそれっぽい見た目になりました。
どうでもいいですがcssはbootstrapのUmiテーマを使っています。
ysakasin.github.io
まとめ
GWに5日くらいかけて作りましたが、案外それっぽく出来るものですね。
グラフは日時を指定して表示内容を変えたり出来るようにしてもいいかもしれません。
ソースコードはgithubに上げてます。
https://github.com/fulutori/trafficMonitoring