Move to scanner+uploader logic

This commit is contained in:
Jonathan Flueren 2023-08-17 21:46:32 +02:00
parent 6d6d242346
commit 7a373a3b85
5 changed files with 59 additions and 190 deletions

View file

@ -1,29 +1,29 @@
# CZI presence detector # CZI presence detector
Tool to detect the presence of defined devices by their WiFi MAC addresses. Tool to detect and publish the presence of defined devices by their WiFi MAC addresses.
## How scanning works ## How scanning works
Sets the wifi adapter into monitor mode, then listens to surrounding packets listing all detected devices into `wifi_map.yaml`. Sets the wifi adapter into monitor mode, then listens to surrounding packets listing all detected devices into `wifi_map.yaml`.
Then, periodically filters the results by the mac addresses that opted in on the website from `identities.json` and sends all matched identities to the website via a signed webhook. This website stores the presence information locally and displays it with `website/index.php` with a timestamp of the last update. Then, periodically filters the results by the mac addresses that opted in on the website from `identities.json` and sends all matched identities to the website via a signed webhook. This website stores the presence information locally and displays it with `website/index.php` with a timestamp of the last update.
## What the website is capable of ## What the website is capable of
Shows the last update of the `upload.py` routine. It also allows to add identities by their name and mac and to delete identities by their mac. The mac addresses are hashed server-side and then stored into the world-accessible `identities.json`. Shows the last update of the `uploader.py` routine. It also allows to add identities by their name and mac and to delete identities by their mac. The mac addresses are hashed server-side and then stored into the world-accessible `identities.json`.
## Set-up ## Set-up
Dependencies: Dependencies:
- Scanner: Python3, trackerjacker (pip3) - Scanner/Uploader: Python3, trackerjacker (pip3)
- Website: php - Website: php
Configs to change: Configs to change:
- `scanner/live-scanner.sh`: - `scanner/scanner.sh`:
- WiFi adapter name - WiFi adapter name
- Possibly some more system-specific changes - Possibly some more system-specific changes
- `scanner/upload.py`: - `scanner/uploader.py`:
- URLs for webhook and identities - base URL for webhook and identities
- webhook secret - webhook secret
- `public/update.php`: - `public/update.php`:
- webhook secret - webhook secret
Put `scanner` onto the scanning device (e.g. Raspberry Pi). Let `live-scanner.sh` and `live-uploader.sh` running in the background, e.g. by the Systemd services below. Put `scanner` onto the scanning device (e.g. Raspberry Pi). Let `scanner.sh` and `uploader.pu` running in the background, e.g. by the Systemd services below.
Put `website` onto a php-capable webserver and point your domain to it. Put `website` onto a php-capable webserver and point your domain to it.
## Systemd services ## Systemd services
@ -38,7 +38,7 @@ User=root
Group=root Group=root
Restart=always Restart=always
WorkingDirectory=/path/to/scanner WorkingDirectory=/path/to/scanner
ExecStart=/path/to/scanner/live-scanner.sh ExecStart=scanner.sh
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target
@ -54,7 +54,7 @@ User=pi
Group=pi Group=pi
Restart=always Restart=always
WorkingDirectory=/path/to/scanner WorkingDirectory=/path/to/scanner
ExecStart=/path/to/scanner/live-uploader.sh ExecStart=uploader.py
[Install] [Install]
WantedBy=multi-user.target WantedBy=multi-user.target

View file

@ -1,56 +0,0 @@
#!/bin/bash
adapter=wlan0
conn_test_url=http://www.google.com
restart_network() {
systemctl restart wpa_supplicant
}
# Check for root privileges
if [ "$(id -u)" != "0" ]
then
>&2 echo "Quitting, this script has to be run as root!"
exit 1
fi
# Activate Monitor mode
#trackerjacker --monitor-mode-on -i $adapter
#ip link set $adapter down
#iw dev $adapter set monitor control
#ip link set $adapter up
# Run scan
timeout 30 trackerjacker -i $adapter --map
# Deactivate Monitor mode
#trackerjacker --monitor-mode-off -i $adapter
#ip link set $adapter down
#iw dev $adapter set type managed
#ip link set $adapter up
# Test network & try to restart if it fails
for i in 1 2 3 4 5
do
sleep 10
wget -q --spider $conn_test_url && break
# no internet connection
echo "No internet - restarting network"
restart_network
done
# Network restarted up to 5 times, last test for connectivity
wget -q --spider $conn_test_url
if [ $? -eq 0 ]; then
# Filter & upload results
python upload.py
else
echo "ERROR: no network connection"
fi
# Remove old scan results
rm wifi_map.yaml

20
scanner/scanner.sh Normal file
View file

@ -0,0 +1,20 @@
#!/bin/bash
adapter=wlan1
# Check for root privileges
if [ "$(id -u)" != "0" ]
then
>&2 echo "Quitting, this script has to be run as root!"
exit 1
fi
# Activate Monitor mode
#trackerjacker --monitor-mode-on -i $adapter
#ip link set $adapter down
#iw dev $adapter set monitor control
#ip link set $adapter up
# Run scan
trackerjacker -i $adapter --remove-unseen-devices --map > /dev/null 2>&1

View file

@ -1,20 +1,26 @@
# credits: https://gist.github.com/calebmadrigal/fdb8855a6d05c87bbb0254a1424ee582 #!/usr/bin/python
# some credits: https://gist.github.com/calebmadrigal/fdb8855a6d05c87bbb0254a1424ee582
import sys
import yaml import yaml
import requests import requests
import json import json
import hmac import hmac
import hashlib import hashlib
import time
BASE_URL = "http://localhost:8080/" BASE_URL = "http://localhost:8080/"
WEBHOOK_SECRET = "CHANGE-THIS" WEBHOOK_SECRET = "CHANGE-THIS"
WIFI_MAP_PATH = "wifi_map.yaml" WIFI_MAP_PATH = "wifi_map.yaml"
UPLOAD_INTERVAL = 30
def get_identities(): def get_identities():
identities_url = BASE_URL.rstrip('/') + '/identities.json' identities_url = BASE_URL.rstrip('/') + '/identities.json'
resp = requests.get(identities_url) resp = requests.get(identities_url)
return resp.json() if resp.status_code == 200:
return resp.json()
else:
return []
def parse_wifi_map(map_path): def parse_wifi_map(map_path):
@ -25,9 +31,9 @@ def parse_wifi_map(map_path):
# read known identities # read known identities
identities = get_identities() identities = get_identities()
print("Known identities:") #print("Known identities:")
for identity in identities: #for identity in identities:
print('mac hash = {}, name = {}'.format(identity['mac_hash'],identity['name'])) # print('mac hash = {}, name = {}'.format(identity['mac_hash'],identity['name']))
filtered_identities = set() filtered_identities = set()
@ -43,16 +49,13 @@ def parse_wifi_map(map_path):
if identity['mac_hash'] == mac_hash: if identity['mac_hash'] == mac_hash:
filtered_identities |= {identity['name']} filtered_identities |= {identity['name']}
print('\nFiltered identities:') #print('\nFiltered identities:',filtered_identities)
print(filtered_identities)
return filtered_identities return filtered_identities
if __name__ == '__main__': def upload_identities(identities):
filtered_identities = parse_wifi_map(WIFI_MAP_PATH)
# build request # build request
json_payload = json.dumps(list(filtered_identities)).encode("utf-8") json_payload = json.dumps(list(identities)).encode("utf-8")
signature = hmac.new( signature = hmac.new(
key=bytes(WEBHOOK_SECRET, "utf-8"), key=bytes(WEBHOOK_SECRET, "utf-8"),
@ -69,6 +72,16 @@ if __name__ == '__main__':
# send request # send request
r = requests.post(url=webhook_url, data=json_payload, headers=req_headers) r = requests.post(url=webhook_url, data=json_payload, headers=req_headers)
#print("Upload response:", r.status_code)
if __name__ == '__main__':
while(1):
filtered_identities = parse_wifi_map(WIFI_MAP_PATH)
upload_identities(filtered_identities)
time.sleep(UPLOAD_INTERVAL)
print("Upload response:")
print(r.status_code)

View file

@ -16,111 +16,3 @@ TEST_SSID:
signal: -86 signal: -86
ssid: TEST_SSID ssid: TEST_SSID
vendor: Broadcom vendor: Broadcom
eduroam:
90:48:9a:e3:58:25:
bssid: 90:48:9a:e3:58:25
bytes: 5073
channels:
- 1
devices:
01:00:5e:96:e1:89:
bytes: 476
signal: -62
vendor: ''
30:8c:fb:66:23:91:
bytes: 278
signal: -46
vendor: Dropcam
34:23:ba:1c:ba:e7:
bytes: 548
signal: 4
vendor: SAMSUNG ELECTRO-MECHANICS(THAILAND)
signal: -80
ssid: eduroam
vendor: TU Dortmundddd
hacker_network:
80:2a:a8:e5:de:92:
bssid: 80:2a:a8:e5:de:92
bytes: 5895
channels:
- 11
devices:
80:1f:02:e6:44:96:
bytes: 960
signal: -46
vendor: Edimax Technology Co. Ltd.
80:2a:a8:8a:ec:c8:
bytes: 472
signal: 4
vendor: Ubiquiti Networks Inc.
80:2a:a8:be:09:a9:
bytes: 5199
signal: 4
vendor: Ubiquiti Networks Inc.
d8:49:2f:7a:f0:8f:
bytes: 548
signal: 4
vendor: CANON INC.
signal: -46
ssid: hacker
vendor: Ubiquiti Networks Inc.
80:2a:a8:61:aa:2f:
bssid: 80:2a:a8:61:aa:2f
bytes: 5629
channels:
- 44
- 48
devices:
78:88:6d:4e:e2:c9:
bytes: 948
signal: -52
vendor: ''
e4:8b:7f:d4:cb:25:
bytes: 986
signal: -48
vendor: Apple, Inc.
signal: -48
ssid: null
vendor: Ubiquiti Networks Inc.
82:2a:a8:51:32:25:
bssid: 82:2a:a8:51:32:25
bytes: 3902
channels:
- 48
devices:
b8:e8:56:f5:a0:70:
bytes: 1188
signal: -34
vendor: Apple, Inc.
signal: -14
ssid: hacker
vendor: ''
82:2a:a8:fc:33:b6:
bssid: 82:2a:a8:fc:33:b6
bytes: 7805
channels:
- 10
- 11
- 12
devices:
78:31:c1:7f:25:43:
bytes: 4632
signal: -52
vendor: Apple, Inc.
7c:dd:90:fe:b4:87:
bytes: 423223
signal: 4
vendor: Shenzhen Ogemray Technology Co., Ltd.
ff:ff:ff:ff:ff:ff:
bytes: 2323
signal: 2
vendor: none
80:2a:a8:be:09:a9:
bytes: 5199
signal: 4
vendor: Ubiquiti Networks Inc.
signal: -62
ssid: null
vendor: ''