diff --git a/front/plugins/nmap_dev_scan/nmap_dev.py b/front/plugins/nmap_dev_scan/nmap_dev.py index 5b269ef1..9a9d1bf0 100755 --- a/front/plugins/nmap_dev_scan/nmap_dev.py +++ b/front/plugins/nmap_dev_scan/nmap_dev.py @@ -5,7 +5,6 @@ import os import subprocess import sys -import hashlib import re import nmap @@ -17,6 +16,7 @@ from plugin_helper import Plugin_Objects # noqa: E402 [flake8 lint suppression] from logger import mylog, Logger # noqa: E402 [flake8 lint suppression] from helper import get_setting_value # noqa: E402 [flake8 lint suppression] from const import logPath # noqa: E402 [flake8 lint suppression] +from utils.crypto_utils import string_to_mac_hash # noqa: E402 [flake8 lint suppression] import conf # noqa: E402 [flake8 lint suppression] from pytz import timezone # noqa: E402 [flake8 lint suppression] @@ -177,16 +177,6 @@ def parse_nmap_xml(xml_output, interface, fakeMac): return devices_list -def string_to_mac_hash(input_string): - # Calculate a hash using SHA-256 - sha256_hash = hashlib.sha256(input_string.encode()).hexdigest() - - # Take the first 12 characters of the hash and format as a MAC address - mac_hash = ':'.join(sha256_hash[i:i + 2] for i in range(0, 12, 2)) - - return mac_hash - - # =============================================================================== # BEGIN # =============================================================================== diff --git a/front/plugins/pihole_api_scan/README.md b/front/plugins/pihole_api_scan/README.md index e38750df..9fddea26 100644 --- a/front/plugins/pihole_api_scan/README.md +++ b/front/plugins/pihole_api_scan/README.md @@ -13,9 +13,6 @@ The plugin connects to your Pi-hole’s API and retrieves: NetAlertX then uses this information to match or create devices in your system. -> [!TIP] -> Some tip. - ### Quick setup guide * You are running **Pi-hole v6** or newer. @@ -30,17 +27,18 @@ No additional Pi-hole configuration is required. | Setting Key | Description | | ---------------------------- | -------------------------------------------------------------------------------- | -| **PIHOLEAPI_URL** | Your Pi-hole base URL. | +| **PIHOLEAPI_URL** | Your Pi-hole base URL. | | **PIHOLEAPI_PASSWORD** | The Web UI base64 encoded (en-/decoding handled by the app) admin password. | | **PIHOLEAPI_SSL_VERIFY** | Whether to verify HTTPS certificates. Disable only for self-signed certificates. | | **PIHOLEAPI_RUN_TIMEOUT** | Request timeout in seconds. | | **PIHOLEAPI_API_MAXCLIENTS** | Maximum number of devices to request from Pi-hole. Defaults are usually fine. | +| **PIHOLEAPI_FAKE_MAC** | Generate FAKE AMC from IP. | -### Example Configuration +### Example Configuration | Setting Key | Sample Value | | ---------------------------- | -------------------------------------------------- | -| **PIHOLEAPI_URL** | `http://pi.hole/` | +| **PIHOLEAPI_URL** | `http://pi.hole/` | | **PIHOLEAPI_PASSWORD** | `passw0rd` | | **PIHOLEAPI_SSL_VERIFY** | `true` | | **PIHOLEAPI_RUN_TIMEOUT** | `30` | @@ -110,6 +108,32 @@ Then re-run the plugin. --- +#### ❌ Some devices are missing + +Check: + +* Pi-hole shows devices under **Settings → Network** +* NetAlertX logs contain: + +``` +[PIHOLEAPI] Skipping invalid MAC (see PIHOLEAPI_FAKE_MAC setting) ... +``` + +If devices are missing: + +* The app skipps devices with invalid MACs +* Enable PIHOLEAPI_FAKE_MAC if you want to import these devices with a fake mac and you are not concerned with data inconsistencies later on + +Try enabling PIHOLEAPI_FAKE_MAC: + +``` +PIHOLEAPI_FAKE_MAC = 1 +``` + +Then re-run the plugin. + +--- + #### ❌ Wrong or missing hostnames Pi-hole only reports names it knows from: @@ -122,7 +146,7 @@ If names are missing, confirm they appear in Pi-hole’s own UI first. ### Notes -- Additional notes, limitations, Author info. +- Additional notes, limitations, Author info. - Version: 1.0.0 - Author: `jokob-sk`, `leiweibau` diff --git a/front/plugins/pihole_api_scan/config.json b/front/plugins/pihole_api_scan/config.json index cac9235c..d23bba0e 100644 --- a/front/plugins/pihole_api_scan/config.json +++ b/front/plugins/pihole_api_scan/config.json @@ -279,6 +279,41 @@ "string": "Maximum time in seconds to wait for the script to finish. If this time is exceeded the script is aborted." } ] + }, + { + "function": "FAKE_MAC", + "type": { + "dataType": "boolean", + "elements": [ + { + "elementType": "input", + "elementOptions": [ + { + "type": "checkbox" + } + ], + "transformers": [] + } + ] + }, + "default_value": false, + "options": [], + "localized": [ + "name", + "description" + ], + "name": [ + { + "language_code": "en_us", + "string": "Fake MAC if empty" + } + ], + "description": [ + { + "language_code": "en_us", + "string": "Some PiHole devices don't have a MAC assigned. Enabling the FAKE_MAC setting generates a fake MAC address from the IP address to track devices, but it may cause inconsistencies if IPs change or devices are re-discovered with a different MAC. Static IPs are recommended. Device type and icon might not be detected correctly and some plugins might fail if they depend on a valid MAC address. When unchecked, devices with empty MAC addresses are skipped." + } + ] } ], "database_column_definitions": [ diff --git a/front/plugins/pihole_api_scan/pihole_api_scan.py b/front/plugins/pihole_api_scan/pihole_api_scan.py index 09ff5f69..70a33018 100644 --- a/front/plugins/pihole_api_scan/pihole_api_scan.py +++ b/front/plugins/pihole_api_scan/pihole_api_scan.py @@ -23,6 +23,7 @@ from helper import get_setting_value # noqa: E402 [flake8 lint suppression] from const import logPath # noqa: E402 [flake8 lint suppression] import conf # noqa: E402 [flake8 lint suppression] from pytz import timezone # noqa: E402 [flake8 lint suppression] +from utils.crypto_utils import string_to_mac_hash # noqa: E402 [flake8 lint suppression] # Setup timezone & logger using standard NAX helpers conf.tz = timezone(get_setting_value('TIMEZONE')) @@ -42,6 +43,7 @@ PIHOLEAPI_SES_CSRF = None PIHOLEAPI_API_MAXCLIENTS = None PIHOLEAPI_VERIFY_SSL = True PIHOLEAPI_RUN_TIMEOUT = 10 +PIHOLEAPI_FAKE_MAC = get_setting_value('PIHOLEAPI_FAKE_MAC') VERSION_DATE = "NAX-PIHOLEAPI-1.0" @@ -222,8 +224,14 @@ def gather_device_entries(): if ip in iplist: lastQuery = str(now_ts) + tmpMac = hwaddr.lower() + + # ensure fake mac if enabled + if PIHOLEAPI_FAKE_MAC and is_mac(tmpMac) is False: + tmpMac = string_to_mac_hash(ip) + entries.append({ - 'mac': hwaddr.lower(), + 'mac': tmpMac, 'ip': ip, 'name': name, 'macVendor': macVendor, @@ -281,7 +289,7 @@ def main(): foreignKey=str(entry['mac']) ) else: - mylog('verbose', [f"[{pluginName}] Skipping invalid MAC: {entry['name']}|{entry['mac']}|{entry['ip']}"]) + mylog('verbose', [f"[{pluginName}] Skipping invalid MAC (see PIHOLEAPI_FAKE_MAC setting): {entry['name']}|{entry['mac']}|{entry['ip']}"]) # Write result file for NetAlertX to ingest plugin_objects.write_result_file() diff --git a/server/utils/crypto_utils.py b/server/utils/crypto_utils.py index d88612f4..ba38b334 100644 --- a/server/utils/crypto_utils.py +++ b/server/utils/crypto_utils.py @@ -70,3 +70,13 @@ def generate_deterministic_guid(plugin, primary_id, secondary_id): """Generates a deterministic GUID based on plugin, primary ID, and secondary ID.""" data = f"{plugin}-{primary_id}-{secondary_id}".encode("utf-8") return str(uuid.UUID(hashlib.md5(data).hexdigest())) + + +def string_to_mac_hash(input_string): + # Calculate a hash using SHA-256 + sha256_hash = hashlib.sha256(input_string.encode()).hexdigest() + + # Take the first 12 characters of the hash and format as a MAC address + mac_hash = ':'.join(sha256_hash[i:i + 2] for i in range(0, 12, 2)) + + return mac_hash