lanfence 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. lanfence-0.1.0/CHANGELOG.md +67 -0
  2. lanfence-0.1.0/CONTRIBUTING.md +75 -0
  3. lanfence-0.1.0/DISTRIBUTING.md +62 -0
  4. lanfence-0.1.0/LICENSE +21 -0
  5. lanfence-0.1.0/MANIFEST.in +4 -0
  6. lanfence-0.1.0/PKG-INFO +272 -0
  7. lanfence-0.1.0/README.md +239 -0
  8. lanfence-0.1.0/lanfence/__init__.py +6 -0
  9. lanfence-0.1.0/lanfence/alerts.py +134 -0
  10. lanfence-0.1.0/lanfence/allowlist.py +101 -0
  11. lanfence-0.1.0/lanfence/cli.py +394 -0
  12. lanfence-0.1.0/lanfence/config.py +130 -0
  13. lanfence-0.1.0/lanfence/data/oui_vendors.txt +148 -0
  14. lanfence-0.1.0/lanfence/data/rogue_signatures.yaml +106 -0
  15. lanfence-0.1.0/lanfence/db.py +182 -0
  16. lanfence-0.1.0/lanfence/engine.py +202 -0
  17. lanfence-0.1.0/lanfence/fingerprint.py +164 -0
  18. lanfence-0.1.0/lanfence/fsutil.py +45 -0
  19. lanfence-0.1.0/lanfence/logging_config.py +48 -0
  20. lanfence-0.1.0/lanfence/models.py +128 -0
  21. lanfence-0.1.0/lanfence/netutil.py +49 -0
  22. lanfence-0.1.0/lanfence/report.py +189 -0
  23. lanfence-0.1.0/lanfence/sanitize.py +48 -0
  24. lanfence-0.1.0/lanfence/scanner.py +243 -0
  25. lanfence-0.1.0/lanfence/vendor.py +52 -0
  26. lanfence-0.1.0/lanfence.egg-info/PKG-INFO +272 -0
  27. lanfence-0.1.0/lanfence.egg-info/SOURCES.txt +41 -0
  28. lanfence-0.1.0/lanfence.egg-info/dependency_links.txt +1 -0
  29. lanfence-0.1.0/lanfence.egg-info/entry_points.txt +2 -0
  30. lanfence-0.1.0/lanfence.egg-info/requires.txt +10 -0
  31. lanfence-0.1.0/lanfence.egg-info/top_level.txt +1 -0
  32. lanfence-0.1.0/pyproject.toml +63 -0
  33. lanfence-0.1.0/setup.cfg +4 -0
  34. lanfence-0.1.0/tests/test_allowlist.py +77 -0
  35. lanfence-0.1.0/tests/test_cli.py +91 -0
  36. lanfence-0.1.0/tests/test_config.py +72 -0
  37. lanfence-0.1.0/tests/test_db.py +100 -0
  38. lanfence-0.1.0/tests/test_engine.py +114 -0
  39. lanfence-0.1.0/tests/test_fingerprint.py +80 -0
  40. lanfence-0.1.0/tests/test_netutil.py +39 -0
  41. lanfence-0.1.0/tests/test_report.py +53 -0
  42. lanfence-0.1.0/tests/test_scanner.py +61 -0
  43. lanfence-0.1.0/tests/test_vendor.py +33 -0
@@ -0,0 +1,67 @@
1
+ <!--
2
+ Copyright (c) 2026-present Stable State Consulting Ltd
3
+ SPDX-License-Identifier: MIT
4
+ -->
5
+
6
+ # Changelog
7
+
8
+ All notable changes to LAN Fence are recorded here.
9
+
10
+ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
11
+ and this project aims to follow [Semantic Versioning](https://semver.org/).
12
+ Each release is also published to
13
+ [PyPI](https://pypi.org/project/lanfence/) and tagged on
14
+ [GitHub](https://github.com/rosscooney/lanfence/releases).
15
+
16
+ ## [Unreleased]
17
+
18
+ ## [0.1.0] - 2026-09-11
19
+
20
+ Initial release. MVP scope: ARP scanning (active + passive), MAC tracking, an
21
+ allowlist, basic device fingerprinting, CLI + JSON output, and syslog/email/
22
+ webhook alerting.
23
+
24
+ ### Added
25
+
26
+ - `lanfence scan` - one-time active ARP sweep of the local subnet (auto-
27
+ detected, or `--interface`/`--subnet`); records every device to a
28
+ persistent SQLite database and prints a device table plus any findings.
29
+ - `lanfence monitor` - continuous watch: repeats an active ARP sweep on an
30
+ interval (`scan.scan_interval_seconds`) and, in parallel, passively sniffs
31
+ ARP traffic between sweeps for lower-latency detection of a device that
32
+ joins mid-interval. Runs until interrupted (Ctrl+C).
33
+ - `lanfence allow <mac>` / `--list` / `--remove` - manage a YAML allowlist of
34
+ devices you trust; findings about an allowlisted device are downgraded to
35
+ `info` instead of alerting every time it reconnects.
36
+ - `lanfence report --since <30m|24h|7d>` - summarizes connect/disconnect/
37
+ reappear events and findings recorded in the database over a time window,
38
+ for scheduled (cron/systemd-timer) daily or weekly reports.
39
+ - `lanfence check` - verifies the host can run LAN Fence: root/raw-socket
40
+ access, whether `scapy` is installed, interface/subnet auto-detection, and
41
+ that the database path is writable.
42
+ - Device lifecycle tracking (`new_device` / `reappeared` / `disconnected`)
43
+ persisted to SQLite, keyed by MAC address.
44
+ - Built-in device fingerprinting: a curated offline OUI → vendor table
45
+ (`lanfence/data/oui_vendors.txt`) plus a rogue-device signature set
46
+ (`lanfence/data/rogue_signatures.yaml`) covering Espressif (ESP32/ESP8266 -
47
+ common in DIY hidden cameras and Wi-Fi implants), Raspberry Pi hardware,
48
+ USB-Ethernet gadget chipsets, and hostname signatures for Pwnagotchi, Hak5
49
+ Bash Bunny/LAN Turtle/WiFi Pineapple, Flipper Zero and O.MG Cable. Both
50
+ files are extensible via `vendor_file:` / `rogue_signatures_file:` in
51
+ config. A locally-administered (randomized/spoofed) MAC is flagged on its
52
+ own as a low-grade signal.
53
+ - Plain-language findings with `high` / `medium` / `info` severity, a
54
+ rationale, a recommendation, and supporting evidence lines.
55
+ - Alert dispatch to syslog, email (SMTP) and/or a webhook (JSON POST), gated
56
+ by `alerts.min_severity`; `--alert` on `scan`/`monitor` triggers dispatch.
57
+ - JSON export (`--format json`) on `scan` and `report`, and
58
+ `--fail-on-findings` exit codes (`0`/`10`/`20` for info/medium/high) for CI
59
+ use.
60
+ - YAML configuration (`--config`) for scan settings, alert channels, database
61
+ path, allowlist path, and extra vendor/signature files.
62
+ - No telemetry and no calls to any third-party service; every network
63
+ destination (syslog target, SMTP host, webhook URL) is one the operator
64
+ configures themselves.
65
+
66
+ [Unreleased]: https://github.com/rosscooney/lanfence/compare/v0.1.0...HEAD
67
+ [0.1.0]: https://github.com/rosscooney/lanfence/releases/tag/v0.1.0
@@ -0,0 +1,75 @@
1
+ # Contributing to LAN Fence
2
+
3
+ Thanks for your interest in improving LAN Fence. Contributions are welcome via
4
+ pull requests at <https://github.com/rosscooney/lanfence>.
5
+
6
+ ## Licensing of contributions
7
+
8
+ - LAN Fence is distributed under the [MIT License](LICENSE).
9
+ - Contributions submitted to the project are expected to be distributed under
10
+ the MIT License as part of LAN Fence.
11
+ - Contributors retain copyright in their own contributions unless separately
12
+ agreed in writing.
13
+ - By submitting a pull request, you confirm that you have the right to submit
14
+ the code under the MIT License, and that you are licensing your contribution
15
+ under the MIT License.
16
+
17
+ There is **no** Contributor Licence Agreement or copyright assignment to sign.
18
+
19
+ ## What not to submit
20
+
21
+ - Proprietary or confidential code.
22
+ - Code copied from third-party projects under licences incompatible with MIT
23
+ distribution (for example GPL/AGPL/SSPL source code copied into LAN Fence).
24
+ - Significant new dependencies whose licences are incompatible with the
25
+ project's MIT distribution model. If a change adds a new runtime dependency,
26
+ note its licence in the pull request description.
27
+ - A full copy of the IEEE OUI registry or similarly large generated data files.
28
+ `lanfence/data/oui_vendors.txt` is a small curated subset on purpose (see
29
+ the comment at the top of that file) - keep additions targeted.
30
+
31
+ ## Scope and non-goals
32
+
33
+ LAN Fence is an **observation-only, defensive** tool. It scans, records and
34
+ reports; it never sends anything beyond a standard ARP request, never joins,
35
+ deauthenticates, spoofs, blocks, or otherwise touches another device on the
36
+ network. Please do not propose features that add active exploitation, packet
37
+ injection/deauth, DHCP/ARP spoofing, network blocking or throttling, or any
38
+ other offensive capability against devices LAN Fence discovers - such pull
39
+ requests will be closed.
40
+
41
+ LAN Fence cannot prove a device is malicious or that a MAC address is genuine
42
+ - vendor OUIs and hostnames are trivially spoofed. It surfaces evidence and
43
+ heuristics for a human to judge. Keep documentation and finding wording
44
+ consistent with that (a "finding" is a lead, not a verdict).
45
+
46
+ ## Development setup
47
+
48
+ ```bash
49
+ python3 -m venv .venv && . .venv/bin/activate
50
+ pip install -e ".[dev,scan]"
51
+ pytest
52
+ ```
53
+
54
+ Active/passive scanning itself needs root (or `CAP_NET_RAW`) and a real
55
+ network interface, so most of the test suite exercises the scanning code with
56
+ the network layer mocked - `lanfence/scanner.py` is intentionally the one
57
+ thin module that talks to raw sockets.
58
+
59
+ ## Before opening a pull request
60
+
61
+ - Add or update tests for behaviour changes.
62
+ - Run the test suite: `pytest`.
63
+ - Keep changes focused; describe the motivation in the PR description.
64
+ - Add the source-file header to any **new** original source files:
65
+
66
+ ```python
67
+ # Copyright (c) 2026-present Stable State Consulting Ltd
68
+ # SPDX-License-Identifier: MIT
69
+ ```
70
+
71
+ ## Reporting bugs and security issues
72
+
73
+ - Normal bugs: open a GitHub issue.
74
+ - Security vulnerabilities in LAN Fence itself: open a GitHub issue marked
75
+ `security`, or email contributors@lanfence.dev.
@@ -0,0 +1,62 @@
1
+ <!--
2
+ Copyright (c) 2026-present Stable State Consulting Ltd
3
+ SPDX-License-Identifier: MIT
4
+ -->
5
+
6
+ # Distributing LAN Fence
7
+
8
+ LAN Fence is MIT-licensed. The distribution model is deliberately
9
+ **low-friction**: this project ships **only its own MIT code**, plus a small
10
+ curated OUI vendor table and a handful of rogue-device fingerprint signatures
11
+ (both plain-text/YAML data files, not compiled artifacts), and never
12
+ redistributes a prebuilt operating-system image. Users install onto their own
13
+ stock Raspberry Pi OS / Debian, so the GPL/LGPL parts of the OS come straight
14
+ from Raspberry Pi Ltd and Debian - this project is not in that supply chain.
15
+
16
+ > Not legal advice. If you redistribute at scale, have a solicitor review your
17
+ > final artifact and its notices.
18
+
19
+ ## Supported ways to install
20
+
21
+ ### 1. pipx (recommended)
22
+
23
+ ```bash
24
+ pipx install lanfence
25
+ ```
26
+
27
+ Isolated from system Python, and puts the `lanfence` launcher on your `PATH`.
28
+
29
+ ### 2. pip / venv (any Debian/Ubuntu/RPi OS host)
30
+
31
+ ```bash
32
+ python3 -m venv ~/.venvs/lanfence
33
+ ~/.venvs/lanfence/bin/pip install 'lanfence[scan]'
34
+ ```
35
+
36
+ `scapy` (its own licence, GPL-2.0 - see below) is an optional extra
37
+ (`lanfence[scan]`) because it is only needed for the actual ARP scanning code
38
+ path; everything else (config, allowlist, database, reporting) has no GPL
39
+ dependency.
40
+
41
+ ## A note on `scapy`
42
+
43
+ `scapy` is licensed GPL-2.0-only. LAN Fence's own code is MIT and calls scapy
44
+ as an ordinary, unmodified, independently-installed library dependency (an
45
+ `import`, not vendored source) - this is the same relationship any Python tool
46
+ has with a GPL library it depends on via PyPI. If your organisation's
47
+ licence policy treats "depends on a GPL library at runtime" differently from
48
+ "redistributes GPL source", get your own legal read before shipping a
49
+ downstream product built on LAN Fence; LAN Fence's own source and the code it
50
+ directly redistributes (`lanfence/data/*`) remain MIT regardless.
51
+
52
+ ## Publishing checklist (maintainers)
53
+
54
+ See [RELEASING.md](RELEASING.md) for the full step-by-step. In short:
55
+
56
+ - [ ] `python -m build` → `twine check dist/*` passes
57
+ - [ ] `pip install dist/*.whl` in a clean venv; `lanfence --version` works
58
+ - [ ] `CHANGELOG.md` has a dated section for this version
59
+ - [ ] tag `vX.Y.Z`; publish to PyPI as `lanfence`
60
+ - [ ] `LICENSE`, `CONTRIBUTING.md`, `CHANGELOG.md`, `DISTRIBUTING.md` present in
61
+ the sdist (`LICENSE` via `license-files` in `pyproject.toml`; the rest
62
+ via [`MANIFEST.in`](MANIFEST.in)) - check with `tar tzf dist/*.tar.gz`
lanfence-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026-present Stable State Consulting Ltd
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ # Copyright (c) 2026-present Stable State Consulting Ltd
2
+ # SPDX-License-Identifier: MIT
3
+
4
+ include CONTRIBUTING.md CHANGELOG.md DISTRIBUTING.md
@@ -0,0 +1,272 @@
1
+ Metadata-Version: 2.4
2
+ Name: lanfence
3
+ Version: 0.1.0
4
+ Summary: Defensive LAN device monitor - detect and alert on unauthorized devices joining your network
5
+ Author-email: Stable State Consulting Ltd <contributors@lanfence.dev>
6
+ Maintainer-email: Stable State Consulting Ltd <contributors@lanfence.dev>
7
+ License-Expression: MIT
8
+ Project-URL: Homepage, https://github.com/rosscooney/lanfence
9
+ Project-URL: Source, https://github.com/rosscooney/lanfence
10
+ Project-URL: Issues, https://github.com/rosscooney/lanfence/issues
11
+ Keywords: network,security,defensive,arp,raspberry-pi,monitoring
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Information Technology
14
+ Classifier: Intended Audience :: System Administrators
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Topic :: Security
20
+ Classifier: Topic :: System :: Networking :: Monitoring
21
+ Requires-Python: >=3.11
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Requires-Dist: typer>=0.12
25
+ Requires-Dist: pydantic>=2.6
26
+ Requires-Dist: PyYAML>=6.0
27
+ Requires-Dist: rich>=13.0
28
+ Provides-Extra: dev
29
+ Requires-Dist: pytest>=8.0; extra == "dev"
30
+ Provides-Extra: scan
31
+ Requires-Dist: scapy>=2.5; extra == "scan"
32
+ Dynamic: license-file
33
+
34
+ # LAN Fence
35
+
36
+ **LAN Fence is an open-source defensive network device monitor for Linux**
37
+ (developed and tested on Raspberry Pi OS / Debian, and reasonably portable to
38
+ other Debian/Ubuntu systems).
39
+
40
+ - Source & downloads: <https://github.com/rosscooney/lanfence>
41
+ ([releases](https://github.com/rosscooney/lanfence/releases))
42
+ - Package: [`lanfence` on PyPI](https://pypi.org/project/lanfence/)
43
+
44
+ LAN Fence runs on a small Linux box (a Raspberry Pi is the common case) sitting
45
+ on your network. It continuously scans for connected devices via ARP,
46
+ maintains an allowlist of devices you already trust, and alerts in
47
+ plain language when something unknown joins - a rogue device, unauthorized
48
+ hardware, or a supply-chain implant on your LAN.
49
+
50
+ LAN Fence **only observes**. It sends nothing beyond a standard ARP "who-has"
51
+ request (the same thing every device on your LAN does routinely) and never
52
+ touches, blocks, deauthenticates or spoofs anything.
53
+
54
+ > ⚠️ LAN Fence **cannot prove a device is malicious, or that a MAC address is
55
+ > genuine.** MAC vendor prefixes and hostnames are trivially spoofed by anyone
56
+ > deliberately trying to blend in. A finding is a lead worth checking by hand,
57
+ > not a verdict - use it as one input to your own judgement.
58
+
59
+ ## How it works
60
+
61
+ 1. **Active scanning** - LAN Fence periodically ARP-sweeps your subnet
62
+ (`lanfence scan` for one sweep, or on an interval inside `lanfence
63
+ monitor`), collecting every MAC/IP that answers.
64
+ 2. **Passive monitoring** - between active sweeps, `lanfence monitor` also
65
+ listens for ARP traffic on the wire, so a device that joins mid-interval is
66
+ caught sooner rather than waiting for the next sweep.
67
+ 3. Every sighting is folded into a persistent **SQLite database** keyed by MAC
68
+ address, which tracks each device's lifecycle: `new_device` the first time
69
+ it's ever seen, `reappeared` if it had gone offline and came back, and
70
+ `disconnected` when an active sweep no longer sees it.
71
+ 4. Each device is **fingerprinted**: an offline OUI → vendor lookup, a set of
72
+ built-in rogue-device signatures (see below), and a check of whether its
73
+ MAC is locally administered (randomized/spoofed rather than
74
+ vendor-assigned).
75
+ 5. Each device is checked against your **allowlist**
76
+ (`lanfence allow <mac>`). A brand-new or reappearing device not on the
77
+ allowlist produces a plain-language **finding** with a severity
78
+ (`high`/`medium`/`info`), a rationale, and a recommendation; an allowlisted
79
+ device is downgraded to `info` so your own hardware stops shouting every
80
+ time it reconnects.
81
+ 6. Findings can be dispatched to **syslog, email, or a webhook**, and
82
+ everything is available as a CLI table or JSON for automation.
83
+
84
+ ## Built-in rogue-device signatures
85
+
86
+ Heuristics, not proof - a match is a lead to check by hand:
87
+
88
+ | Signal | Category | Why it matters |
89
+ |---|---|---|
90
+ | Vendor: Espressif | `esp32_esp8266` | ESP32/ESP8266 - the chipset behind most cheap DIY hidden cameras, rogue APs, and ESP32-based Wi-Fi implants (as well as plenty of legitimate IoT). |
91
+ | Vendor: Raspberry Pi | `raspberry_pi` | Legitimate everywhere, but also the common hardware basis for rogue network-tap / implant projects (P4wnP1, home-built taps). |
92
+ | Vendor: ASIX Electronics | `usb_ethernet_gadget` | USB-Ethernet chipset used both by ordinary dongles and by BadUSB tools (Bash Bunny, LAN Turtle, O.MG cable) presenting as a network adapter. |
93
+ | Hostname contains `pwnagotchi` | `pwnagotchi` | Pwnagotchi's distinctive default hostname. |
94
+ | Hostname contains `bashbunny` / `lanturtle` / `pineapple` / `omg-cable` | Hak5/O.MG tooling | Default hostnames of common commercial implant/pentest hardware. |
95
+ | Hostname contains `flipper` | `flipper_zero` | Flipper Zero (via its Wi-Fi dev board). |
96
+ | Locally administered MAC | `locally_administered_mac` | No vendor OUI - common for privacy MAC-randomization on phones/laptops, but also for spoofed or gadget hardware. |
97
+
98
+ Extend or override these with your own `rogue_signatures_file:` (same YAML
99
+ shape as `lanfence/data/rogue_signatures.yaml`) and `vendor_file:` (same
100
+ tab-separated shape as `lanfence/data/oui_vendors.txt`) in config.
101
+
102
+ ## Install
103
+
104
+ ```bash
105
+ pipx install lanfence # isolated, recommended
106
+ # active/passive scanning needs the `scan` extra (scapy):
107
+ pipx inject lanfence 'lanfence[scan]'
108
+ ```
109
+
110
+ or
111
+
112
+ ```bash
113
+ python3 -m venv ~/.venvs/lanfence
114
+ ~/.venvs/lanfence/bin/pip install 'lanfence[scan]'
115
+ ```
116
+
117
+ Scanning needs raw-socket access, so `scan`/`monitor` typically need `sudo`
118
+ (or `CAP_NET_RAW` on the interpreter). `allow`, `report` and `check` do not.
119
+
120
+ ## Commands
121
+
122
+ ```text
123
+ lanfence scan # one-time active ARP scan; table + findings
124
+ lanfence scan --format json # same, machine-readable
125
+ lanfence monitor # continuous: active sweeps + passive sniffing
126
+ lanfence allow <MAC> --name X # trust a device; its findings become info
127
+ lanfence allow --list # show the allowlist
128
+ lanfence allow --remove <MAC> # untrust a device
129
+ lanfence report --since 24h # summarize events/findings from the database
130
+ lanfence check # verify permissions, scapy, interface, storage
131
+ ```
132
+
133
+ ### Example: an unknown device joins
134
+
135
+ ```text
136
+ $ sudo lanfence scan
137
+
138
+ Devices seen (4)
139
+ ┌───────────────────┬──────────────┬──────────────┬────────────────────┬────────┬─────────┐
140
+ │ MAC │ IP │ Hostname │ Vendor │ Status │ Trusted │
141
+ ├───────────────────┼──────────────┼──────────────┼────────────────────┼────────┼─────────┤
142
+ │ b8:27:eb:12:34:56 │ 192.168.1.10 │ nas.local │ Raspberry Pi │ online │ yes (NAS)│
143
+ │ 52:8a:1c:99:f4:2d │ 192.168.1.47 │ [unknown] │ [unknown] │ online │ no │
144
+ └───────────────────┴──────────────┴──────────────┴────────────────────┴────────┴─────────┘
145
+
146
+ Findings (1)
147
+
148
+ MEDIUM Unknown device connected
149
+ MAC: 52:8a:1c:99:f4:2d
150
+ The vendor bit pattern indicates a locally administered address rather
151
+ than one assigned by a hardware vendor. Common causes: MAC-randomization
152
+ privacy features on modern phones/laptops, virtual machines/containers,
153
+ or a device deliberately spoofing its address.
154
+ Recommendation: Verify this device belongs on your network. If it's
155
+ yours, run `lanfence allow 52:8a:1c:99:f4:2d` to stop future alerts.
156
+ • MAC: 52:8a:1c:99:f4:2d
157
+ • IP: 192.168.1.47
158
+ • Hostname: [unknown]
159
+ • Vendor: [unknown]
160
+ • mac = 52:8a:1c:99:f4:2d (U/L bit set, no vendor OUI match)
161
+
162
+ Overall: 1 finding(s), highest severity: medium
163
+ ```
164
+
165
+ ## Running unattended
166
+
167
+ LAN Fence does not ship its own scheduler; use `systemd` (recommended on a
168
+ Pi) or `cron`.
169
+
170
+ **Continuous monitoring** - `/etc/systemd/system/lanfence.service`:
171
+
172
+ ```ini
173
+ [Unit]
174
+ Description=LAN Fence continuous monitoring
175
+ After=network-online.target
176
+ Wants=network-online.target
177
+
178
+ [Service]
179
+ ExecStart=/usr/local/bin/lanfence monitor --config /etc/lanfence/config.yaml
180
+ Restart=on-failure
181
+ User=root
182
+
183
+ [Install]
184
+ WantedBy=multi-user.target
185
+ ```
186
+
187
+ ```bash
188
+ sudo systemctl enable --now lanfence
189
+ ```
190
+
191
+ **Daily report** - a cron entry (`sudo crontab -e`):
192
+
193
+ ```cron
194
+ 0 7 * * * /usr/local/bin/lanfence report --since 24h --format json > /var/log/lanfence/daily.json
195
+ ```
196
+
197
+ ## Configuration
198
+
199
+ All settings are optional; everything has a sensible default. Pass
200
+ `--config path/to/config.yaml` to any command.
201
+
202
+ ```yaml
203
+ scan:
204
+ interface: null # null = auto-detect
205
+ subnet: null # null = derive from the interface's own address
206
+ scan_interval_seconds: 60 # how often `monitor` repeats an active sweep
207
+ active_scan_timeout_seconds: 3
208
+ passive: true # also sniff ARP traffic between sweeps
209
+ resolve_hostnames: true # try reverse DNS for each device
210
+ dns_timeout_seconds: 1
211
+
212
+ alerts:
213
+ min_severity: medium # info | medium | high - dispatch threshold
214
+ syslog:
215
+ enabled: false
216
+ address: /dev/log
217
+ facility: user
218
+ email:
219
+ enabled: false
220
+ smtp_host: localhost
221
+ smtp_port: 587
222
+ use_tls: true
223
+ username: null
224
+ password: null
225
+ from_addr: null
226
+ to_addrs: []
227
+ webhook:
228
+ enabled: false
229
+ url: null
230
+ timeout_seconds: 5
231
+
232
+ db_path: ~/.local/share/lanfence/lanfence.db
233
+ allowlist_file: ~/.config/lanfence/allowlist.yaml
234
+ vendor_file: null # extra OUI table, merged with the packaged one
235
+ rogue_signatures_file: null # extra signatures, merged with the packaged ones
236
+ ```
237
+
238
+ ## Exit codes (`--fail-on-findings`)
239
+
240
+ `scan` and `report` accept `--fail-on-findings` for CI/scripting use:
241
+
242
+ | Highest severity in the result | Exit code |
243
+ |---|---|
244
+ | none / info | 0 |
245
+ | medium | 10 |
246
+ | high | 20 |
247
+
248
+ ## Privacy and security
249
+
250
+ - **No telemetry, no external calls.** LAN Fence never phones home. The only
251
+ network destinations it ever contacts are ones *you* configure: your own
252
+ syslog daemon, your own SMTP relay, or your own webhook URL.
253
+ - The vendor and signature databases are bundled, offline, and static -
254
+ nothing is fetched to "keep them fresh".
255
+ - The device database and allowlist are written atomically and are
256
+ owner-readable only where the platform supports it.
257
+
258
+ ## Development
259
+
260
+ ```bash
261
+ python3 -m venv .venv && . .venv/bin/activate
262
+ pip install -e ".[dev,scan]"
263
+ pytest
264
+ ```
265
+
266
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for scope and pull-request guidelines,
267
+ and [DISTRIBUTING.md](DISTRIBUTING.md) for licensing notes on the optional
268
+ `scapy` (GPL-2.0) dependency.
269
+
270
+ ## License
271
+
272
+ MIT - see [LICENSE](LICENSE).