Raspberry Pi의 Node-RED에서 DHCP 패킷 캡처

실험실 등의 사용자 수를 조사하는데, 동일한 네트워크 내에 있는 디바이스가 알려졌다고 생각했습니다. 정기적으로 Ping을 해도 좋지만, 네트워크에 부하를 걸어 버리고, 스마트 폰 등이라고 잠을 때 Wifi를 끊어 버리는 것 같고, 타이밍이 나쁘면 응답을 돌려주지 않거나 합니다.

그래서 Wifi에 연결했을 때 DHCP의 패킷을 포착하면 네트워크에 연결된 순간을 알 수 있을까 생각했습니다. DHCP의 패킷은 UDP의 브로드캐스트로 날아오므로 포착할 수 있다고 생각했습니다.

이번에는 Node-RED를 사용합니다. Node-RED에는 표준 UDP 노드가 있습니다.

DHCP 패킷



h tp // w w. 피 c 훈. 코m/ㄱ09아. 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의 패킷을 포착할 수 있다고 생각합니다.

좋은 웹페이지 즐겨찾기