Skip to content

Releases: rosscooney/LanFence

Allow graceful exit from monitor screen

Choose a tag to compare

@rosscooney rosscooney released this 12 Sep 11:00
  • Press q (without Enter) to exit the live monitor through its normal
    cleanup and session summary. A visible border hint explains the shortcut;
    Ctrl+C remains available and redirected input is never consumed.

v0.3.12

Choose a tag to compare

@rosscooney rosscooney released this 12 Sep 10:44

Added

  • Expanded lanfence channels setup into a numbered application setup menu
    with a shared unsaved draft for communications, scanning, offline detection,
    DHCP approvals, passive service discovery, digests, storage paths, and alert
    delivery. Review redacted changes, reset individual settings to defaults,
    save atomically, or discard; direct channel setup remains available.
    DHCP approvals can be selected explicitly from read-only observed inventory.

Fixed

  • Channel configuration validation and test failures no longer include raw
    Pydantic input or transport exception text that could expose credentials.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.11

Choose a tag to compare

@rosscooney rosscooney released this 12 Sep 10:27

Added

  • Live bordered dashboard for lanfence monitor. A continuously-
    updating terminal display (Rich Live, alternate screen) with a compact
    header (interface, network, elapsed time, active discovery mechanisms,
    last sweep), a scrolling recent-activity feed, and an always-visible
    statistics footer (Known/Seen/Online/New/Review/Scan
    countdown, plus finding/sweep/passive-listener status at wider
    terminals). Seen/New are exact session counters derived from real
    scanning results (deduplicated across active/passive sources and
    addresses, never inferred or double-counted from indirect evidence like
    a DHCP-offered address or an mDNS service target); Known/Online/
    Review come from efficient aggregate database queries refreshed after
    each sweep and on a periodic cadence, not a per-frame full scan. A
    finding is shown once (in the activity feed, not also via the old
    console renderer); repeated identical operational errors are coalesced
    with a count. Small terminals shorten labels and drop optional
    statistics, falling back to a minimal one-line display below a usable
    size; presentation state and rendering are unit-tested independently of
    any terminal or network. --live/--no-live control it explicitly
    (default: auto-detect an interactive terminal); an explicit --live on
    unsupported output (a pipe, a log file, TERM=dumb) falls back to plain
    append-only output with one clear message instead of emitting raw
    control sequences. Ctrl+C exits the alternate screen cleanly before
    printing a short session summary with real counters. Plain/append-only
    mode's existing output is unchanged.

  • lanfence channels - interactive communication-channel setup.
    Configure Slack/Discord/Teams/ntfy/email/webhook/Twilio/syslog without
    hand-editing YAML: lanfence channels shows a status table (enabled/
    configured/safe destination summary/digest selection - never a password,
    token, full webhook URL, or credential-bearing path); channels setup [channel] walks through each channel's real config fields with local
    validation, existing-value defaults, a sanitized preview, and an optional
    post-save test message (defaults to no; Twilio warns about SMS charges);
    channels enable/disable <channel> toggle delivery noninteractively
    without touching stored credentials; channels test <channel> sends one
    clearly-labeled message via the real transport and reports its actual
    success/failure (bypassing alerts.min_severity, creating no device/
    finding/lifecycle event/cooldown entry). A secret is never echoed - only
    "already configured," with an explicit keep/replace/clear. Saves are
    atomic, refuse to overwrite malformed YAML or a concurrent edit, preserve
    every unrelated setting and disabled channel's own secrets, and restrict
    the file to owner-only permissions. Uses a new conventional default
    config path (~/.config/lanfence/config.yaml) when --config isn't
    given, since no other command has a default writable config file to
    reuse - monitor needs a restart to pick up a change made this way.

Fixed

  • Commit passive service-discovery retention cleanup together with each
    observation. Previously cleanup left an open SQLite write transaction,
    allowing an idle monitor to block reset or another monitor with
    database is locked, even when cleanup removed no rows.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.10

Choose a tag to compare

@rosscooney rosscooney released this 12 Sep 09:01

Added

  • Multiple device addresses and historical names, with provenance.
    LAN Fence now retains every address and name a device has presented,
    not just the latest - each tagged with its source (arp, ipv6_nd,
    dhcp_ack, or legacy_snapshot for pre-upgrade data; names additionally
    dhcp_option_12/reverse_dns), the interface it was seen on, and when
    it was first/most recently observed. Device.ip/Device.hostname (and
    lanfence devices/device) now show a preferred value computed from
    this evidence - directly-observed addresses always outrank a DHCP-
    reported lease or imported legacy data regardless of recency, and a
    DHCP-reported name always outranks reverse-DNS - rather than simply
    whatever was written most recently. A dual-stack device correctly
    retains both its IPv4 and IPv6 addresses (previously, sighting it via
    both mechanisms in the same sweep silently discarded one). A DHCP
    client's own request/offer is deliberately never trusted as address
    evidence (only a confirmed server ACK, or a direct ARP/ND observation,
    is) - it still counts as the device being alive on the network. lanfence device <MAC> shows the full retained history in new Addresses/Names
    sections (and --format json in new addresses/names arrays); an
    existing database's ip/hostname are imported once as
    legacy_snapshot evidence, timestamped as of the import (not backdated),
    the first time it's opened after upgrading.

  • User-managed device inventory metadata. lanfence device <MAC> now
    accepts --owner/--purpose/--group/--location (and matching
    --clear-* flags) to attach your own notes to a device - who owns it,
    what it's for, its group, and where it lives. Entirely separate from
    observed hostname/vendor and from trust/review/presence; edits never
    scan, alert, or create a lifecycle event. lanfence devices gained
    matching --owner/--group/--location filters (exact,
    case-insensitive) and an opt-in --details flag adding metadata columns
    to the table; JSON output always includes metadata. The interactive
    lanfence review queue offers an optional "Add device details?" step
    after trusting a device. Owner/group appear as brief context in
    lanfence digest device rows (purpose/location are left out to keep
    rows terse). lanfence reset clears metadata along with the rest of a
    device's history.

  • Passive advertised-service discovery (mDNS/DNS-SD, SSDP/UPnP).
    Enriches inventory with services a device advertises about itself
    (printing, AirPlay, remote audio, cast, generic web service, and any
    other valid service type retained with its raw name) - opt-in via
    discovery.mdns/discovery.ssdp, narrowly extending the existing
    passive capture filter (UDP 5353/1900); needs scan.passive too, and
    monitor warns if enabled without it. Strictly passive: no mDNS query,
    SSDP M-SEARCH, or other discovery traffic is ever sent, and an SSDP
    LOCATION URL is never fetched. Attribution to a device is deliberately
    conservative - a service's target address (or, for SSDP, its packet
    source) is matched only against directly-observed (ARP/IPv6 ND)
    address evidence, never the transmitting frame's own Ethernet/IP source
    (an mDNS proxy/reflector can advertise on behalf of other hosts) and
    never an ambiguous or merely historical IP association; unmatched
    services are shown as unassociated rather than guessed. TTL/ssdp:byebye/
    goodbye semantics are honored per-record, independently, with a small
    documented allowlist for mDNS TXT attributes (bounded count/size, never a
    raw TXT blob) - all advertised claims, never verified capabilities.
    lanfence device <MAC> shows a new "Advertised services" section (and
    --format json a new services array); a new lanfence services
    command lists everything observed (--protocol, --unassociated,
    --include-expired). New-device digest rows get a terse services
    summary; no new findings/alerts are raised by this feature.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.9

Choose a tag to compare

@rosscooney rosscooney released this 12 Sep 07:12

Added

  • Per-device presence policies. lanfence device <MAC> --presence unspecified|intermittent|always-on (plus --offline-after/--clear-offline-after) lets you tell LAN Fence what "normal" presence looks like for a device, separate from trust. Intermittent devices suppress only the routine "it came back" lifecycle finding (first discoveries and real security findings are never suppressed); always-on devices get a medium-severity absence finding once gone past an effective delay, plus one info recovery finding on return, persisted per-episode. lanfence devices --presence ... filters, and interactive review asks about it after trusting a device.
  • lanfence digest. A concise, side-effect-free summary of recent activity - new devices, review/investigation queues, missing always-on devices - as an alternative to per-event notifications. Rolling window (default 24h), preview by default, --send delivers via digest.channels (email/webhook/Slack/Discord/Teams/ntfy), independent of the immediate-alert pipeline.
  • Unexpected DHCP server detection. Passively detects a DHCPOFFER/ACK/NAK reply from a server not on dhcp_servers.approved for the interface it answered on. Scoped by interface (VLAN sub-interfaces like eth0.20 supported natively), independent of device trust. lanfence dhcp-servers lists observed servers; Finding.mac is now optional for this non-device finding type.
  • lanfence reset permanently wipes scanned device history (and, optionally, the allowlist).
  • LAN Fence now identifies and trusts itself on the interface it's using, so its own traffic is never treated as an unknown device.

Fixed

  • lanfence monitor could crash on a real DHCP hostname delivered as raw bytes by some scapy versions/platforms.
  • lanfence link falsely refused a normal pipx install under sudo - it now resolves the real invoking user via SUDO_UID.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.8

Choose a tag to compare

@rosscooney rosscooney released this 11 Sep 21:30

Fixed

  • lanfence monitor could crash on a real DHCP hostname. On at least some scapy versions/platforms, the DHCP "hostname" option comes back as raw bytes rather than an already-decoded str, crashing fingerprint matching (TypeError: a bytes-like object is required, not 'str') the moment a real device's hostname was compared against a rogue-device signature. DHCP-sourced hostnames are now decoded defensively before use.

Added

  • LAN Fence now identifies and trusts itself. Its own MAC on the interface it's using is detected automatically and trusted the same way an allow-ed device is, so its own ARP/passive traffic is never treated as an unknown device. Never written to the allowlist file.
  • lanfence reset permanently deletes all previously scanned devices - history, events, alert cooldowns, review/snooze state - and, unless --keep-allowlist is given, the allowlist too. Asks for confirmation unless --yes is passed.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.7

Choose a tag to compare

@rosscooney rosscooney released this 11 Sep 17:05

Added

  • Configurable offline grace periods. A device is no longer marked offline the instant one active sweep misses it. New scan.offline_grace_seconds (default 180) and scan.offline_after_missed_scans (default 3) require BOTH a consecutive-miss threshold and an elapsed-time grace period before a disconnected event fires. Only a completed active sweep ever evaluates an offline transition, and only a sweep that actually covered a device's known discovery path (interface, address family, IPv4 subnet) counts as an eligible miss - a failed, skipped, or out-of-scope sweep never does. Any positive sighting (active or passive) resets the miss counter. Set offline_grace_seconds: 0 and offline_after_missed_scans: 1 to restore the previous immediate-disconnect behavior.
  • Device inventory and review. New lanfence devices, lanfence device <MAC>, and lanfence review commands work the database without touching the network - list observed devices, inspect one device's history, and trust/snooze/investigate/clear devices needing attention (interactively or noninteractively).
  • DHCP snooping. lanfence monitor now also parses DHCP traffic for a device's self-reported hostname, often available sooner and more reliably than reverse-DNS.
  • lanfence run is a new exact alias for lanfence scan.

Fixed

  • lanfence link falsely refused a normal pipx install under sudo, comparing the launcher's group against "root" instead of the original invoking user. Now resolves the real invoking user via SUDO_UID.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.6

Choose a tag to compare

@rosscooney rosscooney released this 11 Sep 15:53

Changed

  • Alert dispatch is now rate-limited by default. New alerts.rate_limit_seconds (default 900 - 15 minutes) is a per-MAC cooldown on external alert channels: once a device has triggered a dispatch, further alerts about it are suppressed until the cooldown elapses, unless a new finding's severity is higher than what was last alerted. This is a behavior change for anyone upgrading - previously every qualifying finding was dispatched every time. Only the external channels are throttled - the CLI table, JSON output, and the database's event history remain complete. Set rate_limit_seconds: 0 to restore the old "alert every time" behavior.

Added

  • Five new alert channels: Slack, Discord, Microsoft Teams, ntfy, and Twilio SMS (authenticated via HTTP Basic Auth, one message per recipient, body capped at ~480 characters since SMS is billed per segment). All disabled by default, gated by alerts.min_severity.

Internal

  • Added a CI workflow running pytest on every push/PR across Python 3.11/3.12/3.13.
  • Fixed a test flake and stale vendor-table documentation.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.5

Choose a tag to compare

@rosscooney rosscooney released this 11 Sep 15:09

Added

  • IPv6 neighbor discovery. scan/monitor (--ipv6/--no-ipv6, on by default) now discover devices over IPv6 as well as ARP: an active sweep pings the link-local all-nodes multicast address (ff02::1), and passive monitoring additionally parses Neighbor Solicitation/Advertisement traffic. This closes a real gap - a device that is IPv6-only, or deliberately configured off IPv4 to evade an ARP-only monitor, was previously invisible. lanfence check reports IPv6 availability on the interface.
  • New rogue-device vendor signatures backed by real, confirmed vendor strings: hisilicon_camera_soc, allwinner_sbc_or_camera, orange_pi, and an ai-thinker match folded into esp32_esp8266.
  • lanfence vendor-refresh and a full ~40,000-entry IEEE OUI vendor table (see prior release notes).

Changed

  • Corrected/downgraded several hostname-based rogue-device signatures (bunny/turtle replacing unverified bashbunny/lanturtle, pineapple downgraded) after verification found weaker support than originally assumed; removed omg-cable and flipper outright as unverifiable.

Fixed

  • run_active_sweep no longer marks every known device "disconnected" when a scan sweep fails entirely (e.g. no root) - it now only marks devices offline when at least one scan mechanism actually completed.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md

v0.3.4

Choose a tag to compare

@rosscooney rosscooney released this 11 Sep 14:00

Changed

  • lanfence check now creates an empty allowlist file (allow: []) if none exists yet, instead of just reporting "not created yet" - matching what it already does for the device database.

Fixed

  • lanfence link no longer refuses a normal pipx install on Debian / Raspberry Pi OS. Those default new users to umask 002, so a fresh pipx venv is group-writable by the user's own primary group - a group nobody else belongs to on a typical single-user Pi, not a real tampering risk. _trusted_to_run_as_root() now only rejects group-writability when the group actually has another member; world-writable is unaffected and still rejected outright.

Full changelog: https://github.com/rosscooney/LanFence/blob/main/CHANGELOG.md