アオカケスの鳥かご

日々の出来事を綴っていきたい

RaspberryPi4でLAN内のトラフィックを監視する

LAN内のトラフィックを監視する方法としては、SNMPやZabbixなどのOSSのツールを利用する方法が挙げられます。


各種いろいろググって検討しましたが、SNMPに対応しているスイッチやルーターを買い揃えないといけなかったり、OSSを使うにしても学習コストが高そうなことと、イマイチ私が監視したい内容だけを表示することが微妙に出来なさそうでした。


そして最終的にたどり着いた方法がこちら。といっても参考にしたのはネットワーク構成だけですが。
qiita.com


出来るだけお金を掛けずに実装しようとした結果、ほぼ自前でトラフィックを監視することになりました。

具体的にはスイッチに接続されている全てのポートのトラフィックをポートミラーリングでラズパイに集約し、tsharkでキャプチャすることでLAN内のトラフィックを監視します。

目標

  • 機器ごとの一日あたりの通信量の合計を知りたい(1ヶ月、累計なども)
  • 時間別の通信量のグラフ(見てて面白そう)

ネットワーク図

f:id:aokakes:20200509171305p:plain
ネットワーク図

使用機器

ルーターソフトバンク 光BBユニット(J18V150.00)

f:id:aokakes:20200509174012j:plain
光BBユニット
ルーターは何でもOKです。

私はソフトバンク光を契約しているのと、IPv4 over IPv6を利用するために光BBユニットを選択します。


スイッチ:TL-SG108E

f:id:aokakes:20200509174054j:plain
TL-SG108E
スイッチングハブはポートミラーリングに対応している必要があります。

TP-Linkあたりがコスパ良いですね。


AP:Aterm WF800HP

f:id:aokakes:20200509174124j:plain
WF800HP
大学時代のインターンシップのときにその場凌ぎとして3000円ぐらいで購入したWF800HP。
我が家の間取りは1Kなのでこれぐらいのスペックでも、家の中ならどこでもフルHDの動画が止まらずに見れるぐらいの速度は出ます。


RaspberryPi4 メモリ4GB

f:id:aokakes:20200509174851j:plain
RaspberryPi4
気付けば技適が認証されていたので奮発してメモリ4GBの一番良いやつを買いました。

ラズパイを買うときは電源やSDカードなどのラズパイに必要なものが全部セットになっているやつを選んでいます。
同じものを全て別々に買うとセット価格よりも全然高くなりそう。


外付けHDD:WDBBKG0040HBK-JESN
ラズパイに挿しているSDカードにデータを保存しまくるのはあまり気が進まないので、データ類は全て外付けHDDに保存するようにします。

選択肢は山程ありますが、なんとなく信頼できそうな内側も外側もWDのやつを買ってみました。

下準備

無線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はラズパイを接続するポート番号に。
f:id:aokakes:20200509180239p:plain

設定したあとに「Apply」ボタンを押して設定を有効にします。


次にポートミラーの対象を設定します。

このとき、ルーターを接続しているポートも選択することを忘れてはいけません。
ダウンロードのトラフィックをキャプチャできなくなります。

そのため、基本はMirrored Portでラズパイ以外の全てのポートを選択し、Ingressを「Enable」にします。
f:id:aokakes:20200509180612p:plain

そしてまた「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でサクっと書きます。


わりとそれっぽい見た目になりました。
f:id:aokakes:20200509191215p:plain


どうでもいいですがcssはbootstrapのUmiテーマを使っています。
ysakasin.github.io

まとめ

GWに5日くらいかけて作りましたが、案外それっぽく出来るものですね。

グラフは日時を指定して表示内容を変えたり出来るようにしてもいいかもしれません。


ソースコードgithubに上げてます。
https://github.com/fulutori/trafficMonitoring