Commit Graph
6780 Commits
Author SHA1 Message Date
Jokob @NetAlertX d838376e9e Merge pull request #1809 from mauricio-camayo/add-wificanary-plugin
Add WIFICANARY plugin - passive WiFi rogue-AP detection
2026-09-25 14:19:37 +10:00
Mauricio CamayoandClaude Sonnet 5 41efcbc971 Address jokob-sk review: dedupe rogue detections, add iw to remaining Dockerfiles
check_trusted_aps() evaluated a rogue AP once per trusted_aps entry sharing
its SSID, so the documented main-AP+extender pattern (same SSID, two
entries) produced duplicate (bssid, motor) rows for a real clone - a
problem once next_release's per-plugin identity-hash dedup guard lands in
main, since it drops a plugin's entire batch on any internal duplicate.
Fixed by deduping once in main() after collecting from all check_*
functions. Also added iw + its setcap to Dockerfile.debian and
.devcontainer/Dockerfile, which the original PR missed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011meLPKCzVpdZyAUfv5U6mm
2026-09-24 20:10:12 -05:00
Jokob @NetAlertX eea3ac88c0 Merge pull request #1807 from netalertx/next_release
Next release
2026-09-25 08:46:22 +10:00
jokob-sk 087241274a Merge branch 'next_release' of github.com:netalertx/NetAlertX into next_release 2026-09-25 08:32:18 +10:00
jokob-sk f30d27db13 BE: plugin input improvements 2026-09-25 08:32:03 +10:00
Mauricio CamayoandClaude Sonnet 5 f7a0c5861e Address CodeRabbit review: extender false-positive + stale README section
- check_trusted_aps() was evaluating every AP sharing a protected SSID
  against every trusted entry for that SSID, not just its own. A main AP
  requiring a stricter accepted security set (e.g. wpa3-only) than a
  separately-trusted extender (e.g. wpa2) caused the extender to be
  flagged as evil_twin/absent_baseline_clone - it was being judged
  against the main AP's accepted set instead of its own. Fixed by
  excluding, from each trusted entry's evaluation, any BSSID that has its
  own separate trusted entry for the same SSID.
- README's "iw isn't in the published image yet" section was already
  stale within the same PR - this branch's own Dockerfile change adds
  iw + setcap, so the image ships it. Replaced with one sentence.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-24 15:01:16 -05:00
Jokob @NetAlertX 11e1227d7d Merge pull request #1808 from netalertx/main
sync
2026-09-24 10:43:22 +10:00
jokob-sk 33003a4c4d BE: plugin input improvements 2026-09-24 10:42:06 +10:00
jokob-sk d9ef76d942 BE: plugin input improvements 2026-09-24 10:26:24 +10:00
jokob-sk 6cc092f2ad BE: plugin input improvements 2026-09-24 10:01:52 +10:00
jokob-sk 1c410bf2be DOCS: skill updates 2026-09-24 09:00:08 +10:00
Jokob @NetAlertX 88cf790263 Merge pull request #1805 from netalertx/next_release
Next release
2026-09-24 07:50:23 +10:00
Mauricio CamayoandClaude Sonnet 5 d0a3a5416b Add WIFICANARY plugin - passive WiFi rogue-AP detection
Periodic iw-scan-based detection of the 6 heuristics that don't need
monitor-mode hardware (see issue #1789): pwnagotchi/Pineapple signatures,
evil-twin/open clones, baseline-AP-absent-with-clone, security downgrades,
and duplicate-SSID/different-vendor - all evaluated against a user-curated
trusted-AP baseline (WIFICANARY_trusted_aps). A detection creates a
flagged Devices entry even for BSSIDs that never associate, per the
addendum on the same issue.

- WIFICANARY_TRUSTED_SECURITY is multi-select: an observed encryption
  exactly matching any selected value is accepted; otherwise it's flagged
  if weaker than the strongest selected value (deliberate - comparing
  against the weakest would make multi-select pointless, since anything
  at/above the weakest would silently pass regardless of the rest of the
  selection).
- Added a "known device turned rogue" motor: escalate_known_devices()
  cross-references each detection's BSSID against the Devices table via
  the new DeviceInstance.getAllByMacs(). This covers the BSSID-identity
  half of the issue #1789 addendum's motor 10; the deauth/probe-source-MAC
  half still needs monitor-mode data this plugin doesn't have.
- Vendor is deliberately not looked up by this plugin - any device it
  creates gets devVendor filled in for free by core's own vendor_update
  plugin on its next pass.

43 wificanary unit tests + 10 DeviceInstance.getAllByMacs() tests, all
test_plugin_conventions.py checks pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011meLPKCzVpdZyAUfv5U6mm
2026-09-23 15:56:47 -05:00
jokob-sk 7aca7c17f3 BE: FREEBOX dual stack IP fix #1804 2026-09-23 08:17:23 +10:00
jokob-sk 24301cbdbc BE: FREEBOX dual stack IP fix #1804 2026-09-23 07:52:30 +10:00
jokob-sk a573eeb0e7 BE: FREEBOX dual stack IP fix #1804 2026-09-22 08:43:41 +10:00
jokob-sk 38866a64db BE: FREEBOX last scan fix #1804 2026-09-22 08:25:53 +10:00
jokob-sk d72aea21f5 BE: re-enable GRAPHQL_PORT #1803 2026-09-21 17:30:25 +10:00
Jokob @NetAlertX cd1d0ed11e Merge pull request #1800 from mauricio-camayo/dockerdisc-v2-import-on
DOCKERDISC v2: optional device creation for LAN-visible containers
2026-09-21 08:47:37 +10:00
Mauricio CamayoandClaude Sonnet 5 b175a3b65f Address jokob-sk review: shorten UI description, map scanSourcePlugin
Settings-UI description trimmed to one short line - implementation
detail (Socket Proxy, column mapping, CREATE_DEV behavior) already
lives in README, doesn't belong in the Settings page string.

scanSourcePlugin now maps to a static "DOCKERDISC" value (same
Dummy-column pattern arp_scan already uses), so a container device
created by this plugin gets devSourcePlugin set correctly instead of
NULL - every other CurrentScan-mapped plugin already does this.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011meLPKCzVpdZyAUfv5U6mm
2026-09-20 16:22:12 -05:00
Mauricio CamayoandClaude Sonnet 5 dea6a553fb Address CodeRabbit review: add DOCKERDISC_IMPORT_ON, docstrings
Declares DOCKERDISC_IMPORT_ON (default on) so an operator can fully opt
this plugin out of CurrentScan promotion. Needed because
DOCKERDISC_CREATE_DEV alone doesn't cover it: a macvlan/ipvlan
container's row always carries a real scanMac, so even with
CREATE_DEV off, an already-existing device for that MAC (found
independently by ARP/Nmap) still gets its presence/devLastIP/
devParentMAC updated by this plugin on every run - only IMPORT_ON can
turn that off. The two settings are independent, per jokob-sk's PR
feedback - IMPORT_ON gates promotion for the whole run, CREATE_DEV
gates device creation per row.

Also adds missing docstrings to process_host()/main() (CodeRabbit
docstring-coverage check), matching the style already used elsewhere
in this file.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011meLPKCzVpdZyAUfv5U6mm
2026-09-18 20:05:37 -05:00
jokob-sk 0fc6082c73 BE: IP ordering fixes #1797 2026-09-19 09:48:33 +10:00
Mauricio CamayoandClaude Sonnet 5 cfde00048a DOCKERDISC v2: optional device creation for LAN-visible containers
Maps DOCKERDISC to CurrentScan (scanMac/scanCreatesDevice/scanParentMAC/
scanLastIP) so a container on a macvlan/ipvlan network can opt into
creating or confirming its own device, parented to its Docker host.
Gated by a new DOCKERDISC_CREATE_DEV setting (default off). A container
without its own MAC (bridge/overlay/etc.) never creates a device either
way - the framework's blank-scanMac guard blocks the whole group
regardless of the setting.

Reuses the existing objectPrimaryId/extra column definitions (already
host MAC / container IP) to also feed scanParentMAC/scanLastIP, so every
promoted container is auto-parented to its host with no extra plugin
logic. Two new hidden columns (helpVal1/helpVal2) carry the per-container
scanMac/scanCreatesDevice values.

Tests: 33 -> 35, both DOCKERDISC_CREATE_DEV on/off paths asserted.
Live-verified end to end against a real built image (docker-socket-proxy
+ isolated macvlan/bridge test containers), since IMPORT_ON isn't in any
released NetAlertX image yet.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011meLPKCzVpdZyAUfv5U6mm
2026-09-18 17:14:10 -05:00
Safeguard b882962ffe Translated using Weblate (Russian)
Currently translated at 100.0% (838 of 838 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/ru/
2026-09-18 08:51:31 +02:00
Jokob @NetAlertX d03492db47 Merge pull request #1796 from netalertx/main
Sync
2026-09-18 08:55:43 +10:00
Jokob @NetAlertX b870601275 Merge pull request #1795 from netalertx/fix/notification-content-truncation
Fix/notification content truncation
2026-09-18 08:54:57 +10:00
jokob-sk 8dcd670d24 DOCS+BE: skill updates, write_notifications fix #1793 2026-09-18 08:42:42 +10:00
jokob-sk 3bf10f8378 DOCS+BE: skill updates, write_notifications fix #1793 2026-09-18 08:20:31 +10:00
jokob-sk 52d1698221 DOCS+BE: skill updates, write_notifications fix #1793 2026-09-18 08:09:22 +10:00
Jokob @NetAlertX 45e86b5646 Merge pull request #1792 from netalertx/main
sync
2026-09-16 08:14:44 +10:00
Jokob @NetAlertX 014b960159 Merge pull request #1791 from agueybanapr/patch-1
Refactor config import logic for legacy column references
2026-09-16 08:12:41 +10:00
Jokob @NetAlertX fce1c00e75 Merge pull request #1788 from mauricio-camayo/add-dockerdisc-plugin
Add DOCKERDISC plugin: enrich existing devices with their Docker containers
2026-09-16 07:54:35 +10:00
Sylvain Pichon 726ca7b402 Translated using Weblate (French)
Currently translated at 100.0% (838 of 838 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/fr/
2026-09-15 18:51:51 +00:00
Mauricio CamayoandClaude Sonnet 5 091e648e88 Fix DOCKERDISC_HOST_MAC docs and strengthen case-insensitivity test
resolve_host_mac() returns the manually configured MAC immediately,
with no Socket Proxy /info call at all - the config.json text still
described it as a fallback used only when auto-detection fails.
Reworded both the setting's own description and the parent "Docker
hosts" description to match actual behavior.

The case-insensitivity regression test for lookup_device_mac() stubbed
DeviceInstance.getByMac() to return a fixed row regardless of input,
so it passed even without exercising real collation - functionally a
duplicate of test_lookup_device_mac_found. Replaced it with a
delegation check, and added real SQLite-backed coverage for
DeviceInstance.getByMac()'s case-insensitivity in
test/backend/test_device_instance.py. That surfaced a gap in the
shared db_test_helpers.py fixture: its Devices.devMac column was
missing the COLLATE NOCASE that the real schema declares, so it could
not have exercised this behavior. Fixed the fixture to match.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011meLPKCzVpdZyAUfv5U6mm
2026-09-15 12:57:04 -05:00
Mauricio Camayo d512e5d84e Add regression test for lookup_device_mac() case handling
CodeRabbit flagged a possible case-sensitivity gap in getByMac() usage.
No functional change needed - Devices.devMac is COLLATE NOCASE at the
schema level, so getByMac()'s plain equality lookup is already
case-insensitive (that's exactly why getAllByName() has to apply it
explicitly and getByMac() doesn't - devName has no column collation).
This test guards that lookup_device_mac() doesn't do anything of its
own that would undo that.
2026-09-15 12:19:30 -05:00
Mauricio Camayo b0d1776221 Trim module docstring: drop design-history attribution and verification date
Per jokob-sk's review - unnecessary details belongs in the PR/commit
history, not the docstring (matches CLAUDE.md's own convention: a
docstring describes current behavior, not a changelog of why).
2026-09-15 12:06:04 -05:00
Mauricio Camayo 776b462001 Merge remote-tracking branch 'upstream/main' into add-dockerdisc-plugin 2026-09-15 11:58:18 -05:00
Mauricio Camayo 3b83d2403b Address jokob-sk review: DeviceInstance instead of raw SQL, drop HTML entity/partial translations/dead spec-file reference
- resolve_host_mac()/lookup_device_mac() now use the new
  DeviceInstance.getAllByName()/getByMac() core methods instead of
  querying Devices directly - no more direct SQL access from the plugin.
- config.json: removed the &rarr; HTML entity from a description (plain
  ASCII ->, matching e.g. pihole_monitor's convention), and dropped the
  partial es_es/de_de translations scattered through settings/columns
  (English only now, matching e.g. rest_import) instead of leaving some
  strings translated and others not.
- script.py: removed the two remaining references to
  PLUGIN_DOCKERDISC_SPEC.md, a file that was never included in this PR.
2026-09-15 11:58:10 -05:00
Pedro Berdasco fbc9fcee7e Refactor config import logic for legacy column references
Ensure legacy column references are renamed only if the config file has changed.  Fix unnecessary config scan in importConfigs, was causing the container to run at over 80% CPU.  

QA tested locally, all test passed!
2026-09-15 08:33:48 +00:00
Jokob @NetAlertX 0794bb8ae2 Merge pull request #1790 from netalertx/next_release
Next release
2026-09-15 09:00:34 +10:00
jokob-sk e237b92657 BE+FE: plugin view fixes, skills, new core method and tests 2026-09-15 08:46:44 +10:00
Mauricio Camayo 6a26804a5e Address CodeRabbit review: request timeout budget, shape validation, ambiguous devName, README fix
- DockerHost now takes a shared run deadline instead of a per-request
  timeout duration - every _get() call is capped by whatever's left of
  that budget (and REQUEST_TIMEOUT_DEFAULT as an upper bound), so one
  slow/hanging host can't burn the whole RUN_TIMEOUT and starve every
  other configured host. config.json's hosts param now also sets
  timeoutMultiplier, scaling the outer kill-timeout by host count.
- _get() validates the parsed response's shape (dict for /info, list for
  /containers/json and /networks) before returning it, rejecting a
  malformed/unexpected payload the same as a network failure instead of
  letting a caller crash on it further down.
- resolve_host_mac()'s hostname match now detects more than one device
  sharing that name and treats it as ambiguous (falls back to manual),
  instead of silently picking an arbitrary one via LIMIT 1.
- README: the Socket Proxy is only reachable at 127.0.0.1:2375 under the
  network_mode: host case described above it, not under normal compose
  networking - fixed the doc to not imply either URL works there.
2026-09-14 10:01:40 -05:00
Mauricio Camayo 94a5cd4968 Add DOCKERDISC plugin: enrich existing devices with their Docker containers
Read-only enrichment plugin, not an import/discovery plugin. For each
configured Docker host (via Docker Socket Proxy, never /var/run/docker.sock
directly), lists that host's containers under the host device's own
Device Details -> Plugins -> DOCKERDISC tab.

- Never creates a device, for either a host or a container - matches
  against hosts already discovered the normal way (ARP/Nmap).
- Every container is listed (bridge/overlay included), not only
  macvlan/ipvlan ones - a container only gets its own MAC/IP shown when
  it has a macvlan/ipvlan network.
- Host MAC auto-detected via the Socket Proxy's /info -> Devices.devName
  match, with a manual fallback.
2026-09-14 09:11:34 -05:00
jokob-sk 6ab220fd8c BE+FE: async event execution 2026-09-14 18:17:06 +10:00
Hosted Weblate d44e9d7803 Merge branch 'origin/main' into Weblate. 2026-09-14 07:28:04 +00:00
Massimo Pissarello c86d02a8d2 Translated using Weblate (Italian)
Currently translated at 100.0% (838 of 838 strings)

Translation: NetAlertX/core
Translate-URL: https://hosted.weblate.org/projects/pialert/core/it/
2026-09-14 07:28:03 +00:00
Jokob @NetAlertX 1b52017a42 Merge pull request #1787 from netalertx/next_release
LANG: sync
2026-09-14 17:27:49 +10:00
jokob-sk 05ac423f76 LANG: sync 2026-09-14 17:27:22 +10:00
Jokob @NetAlertX 994651926c Merge pull request #1786 from netalertx/next_release
Next release
2026-09-14 17:19:19 +10:00
jokob-sk 52ddd7f9d2 BE: review fixes 2026-09-14 16:59:49 +10:00