Raspberry PiのNode-REDでDHCPパケットを捕捉する
ラボなどの利用者数を調べるのに、同一ネットワーク内にいるデバイスが知れたらと思いました。定期的にPingをしても良いのですが、ネットワークに負荷をかけてしまうし、スマホなどだとスリープするときにWifiを切断してしまうようで、タイミングが悪いと応答を返してくれなかったりします。
そこで、Wifiにつないだ時のDHCPのパケットを捕捉すれば、ネットワークにつないだ瞬間がわかるのではないかと思いました。DHCPのパケットはUDPのブロードキャストで飛んでくるので、捕捉できると考えました。
今回はNode-REDを使います。Node-REDには標準でUDPのノードがあります。
DHCPのパケット
http://www.picfun.com/lan09a.html あたりを見ると、DHCPのパケット構成がわかります。
DHCPサーバーはポートUDPポート67、DHCPクライアントはUDPポート68を使うようです。
フローの作成
WindowsのNode-RED DesktoでUDPノードを使ってこんなフローを作ってみました。
[{"id":"8bfbec67.2f728","type":"udp in","z":"4e3881be.18f2e","name":"","iface":"","port":"67","ipv":"udp4","multicast":"false","group":"255.255.255.255","datatype":"buffer","x":630,"y":500,"wires":[["97287e61.cb0a8"]]},{"id":"97287e61.cb0a8","type":"debug","z":"4e3881be.18f2e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":770,"y":500,"wires":[]},{"id":"94c4df6f.98dd1","type":"udp in","z":"4e3881be.18f2e","name":"","iface":"","port":"68","ipv":"udp4","multicast":"false","group":"255.255.255.255","datatype":"buffer","x":630,"y":540,"wires":[["2c62d86f.117228"]]},{"id":"2c62d86f.117228","type":"debug","z":"4e3881be.18f2e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":770,"y":540,"wires":[]}]
手元のスマホをWifiのOFF→ONにすると、パケットが捕捉できました。
28バイト目から6バイトがクライアントのMACアドレスになります。9c:5c:f9はSony Mobile CommunicationのOUI(Organizationally Unique Identifier:メーカーID)です。XPeriaなので正しいですね。これでMACアドレスを知ることができたので、Wifiに接続したデバイスを知ることができました。
Raspberry Pi での実行
上記のフローをそのままRaspberry PiのNode-REDにもっていったのですが、うまくいきませんでした。
デプロイするとこんなエラーが出ます。
どうやらUnix系OSでは1024未満のポートにアクセスするためには管理者権限が必要のようです。Node-REDは一般ユーザーの権限で起動しているので、管理者権限はありません。sudo node-red
とかやれば管理者権限で起動できるのでしょうが、いろいろ調べたところセキュリティ上リスクがあるようなのでやりたくありません。
ポートフォワーディングをする
調べたところによると、1024以下のポートに来たデータを、ユーザー権限でもアクセスできるポートに転送(ポートフォワーディング)することで1024以下のポートに来たパケットを捕捉することができるようです。
今回はUDPの67を10067に、68を10068に転送してみます。
ufwの使用
Raspberry Piにもとから入っているiptablesというのを使えばポートフォワーディングできるらしいですが、ufwを使ったほうが簡単という情報を得たのでufwを使ってみることにしました。
まずufwをインストールします。
$ sudo apt install ufw
ufwをインストールすると、ファイヤーウォール機能が働いてしまい、すべてのポートが遮断されてしまっているので、ひとまずすべてのポートを開放します。(そもそもufwが入っていなかったときはすべてのポートが開放されていたので…。気になる人は必要なポートだけ開放してください。)
$ sudo ufw default ALLOW
次にポートフォワーディングの設定をします。/etc/ufw/after.rules
が設定ファイルです。(before.rulesも設定ファイルなのですが、after.rulesの方に書く理由はよくわかりませんでした)
$ sudo nano /etc/ufw/after.rules
以下を追加します。
*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p udp --dport 67 -j REDIRECT --to-port 10067
-A PREROUTING -p udp --dport 68 -j REDIRECT --to-port 10068
COMMIT
保存したら、ufwを有効化します。
$ sudo ufw enable
フローの修正
ポート67でなく10067を、ポート68でなく10068を受信するようにフローを修正します。
[{"id":"c5639bc.2283768","type":"udp in","z":"4e3881be.18f2e","name":"","iface":"","port":"10068","ipv":"udp4","multicast":"false","group":"255.255.255.255","datatype":"buffer","x":120,"y":380,"wires":[["3f9dd1de.322f9e"]]},{"id":"3f9dd1de.322f9e","type":"debug","z":"4e3881be.18f2e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":270,"y":380,"wires":[]},{"id":"4601ef74.d89b7","type":"udp in","z":"4e3881be.18f2e","name":"","iface":"","port":"10067","ipv":"udp4","multicast":"false","group":"255.255.255.255","datatype":"buffer","x":120,"y":340,"wires":[["9995f01d.0e956"]]},{"id":"9995f01d.0e956","type":"debug","z":"4e3881be.18f2e","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":270,"y":340,"wires":[]}]
これをデプロイし、手元のスマホのwifiをOFF/ONしてみるとDHCPのパケットが捕捉できると思います。
Author And Source
この問題について(Raspberry PiのNode-REDでDHCPパケットを捕捉する), 我々は、より多くの情報をここで見つけました https://qiita.com/ktetsuo/items/cce8b6f65102640ee381著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .