Trusting the tool
Every line is readable
LAN Fence is open source under the MIT License. There is no closed-source component, no obfuscation and no compiled blob — the code you run is the code in the repository.
Observation only, by design
It sends nothing beyond a standard ARP "who-has" request. It never joins, deauthenticates, spoofs, blocks or throttles another device. Contributions that add offensive capability are refused.
No telemetry, no auto-update
LAN Fence never phones home. The only network destinations it ever contacts are ones you configure: your own syslog daemon, your own SMTP relay, or your own webhook URL.
Small, named dependencies
Four core Python libraries plus one optional, GPL-licensed one
(scapy, needed only for the actual packet send/receive)
— each listed with its licence. No third-party source is vendored
into the project.
Untrusted input is sanitised
DHCP hostnames, mDNS names and vendor strings all come straight off the wire from devices you don't control. Control characters are stripped and every field is length-bounded before it reaches a report, the database or your terminal.
Tested with the network mocked
Active/passive scanning itself needs root and a real interface, so
most of the test suite exercises the scanning and detection logic
with the network layer mocked — scanner.py is
deliberately the one thin module that talks to raw sockets.
What LAN Fence touches on your machine
The default behaviour reads and writes only what it needs to do its
job: it sends ARP requests and listens for ARP replies/traffic on the
interface you point it at, looks up each responding MAC in an offline
vendor table, checks it against the bundled rogue-device signatures,
and writes to three places you control — the SQLite device database
(db_path), the allowlist YAML
(allowlist_file), and, if you enable them, alerts to your
own syslog, SMTP or webhook destination.
The device database and allowlist are created 0600
(owner-readable only, where the platform supports it) and written
atomically — a fresh temp file, then
os.replace() into place — so a symlink planted at a
predictable path can't redirect a privileged write onto another
file, and there's no window where a partially-written file could be
read.
Running as root safely
Active/passive ARP scanning needs raw-socket access, so
scan/monitor typically run under
sudo, and lanfence link symlinks the launcher
onto root's PATH. Before doing anything as root, both
resolve the launcher through realpath and
refuse to run or link it if the launcher file or its
containing directory is group- or world-writable — a poisoned
PATH entry can't ride the escalation. lanfence
link re-execs itself under sudo only when writing
to the target directory actually needs root, and prompts for your
password rather than assuming it.
The honest limit
LAN Fence cannot prove that a device is malicious, or that a MAC address is genuine. MAC vendor prefixes and hostnames are trivially spoofed by anyone deliberately trying to blend in. A finding is a lead worth checking by hand, not a verdict. A tool that claimed otherwise would be the one not to trust. Use LAN Fence as one input to your own judgement.
Trusting this website
lanfence.com is a static-feeling PHP site whose only job is to document the project and point you at the real artifacts.
- No third-party requests. No analytics, no tag managers, no tracking pixels, no A/B tools, no web fonts and no CDN. Every asset — CSS, JavaScript, images — is served from lanfence.com itself. The only JavaScript is a small menu toggle and the terminal replay on the home page.
- No cookies, no accounts, no forms. The site sets no cookies and collects nothing from you. There is nothing to log in to and nothing to submit.
- Locked-down headers. A strict
Content-Security-Policybuilt ondefault-src 'self'withobject-src 'none'andframe-ancestors 'none', plusX-Content-Type-Options: nosniff,X-Frame-Options: DENY, a tightReferrer-Policy, aPermissions-Policythat denies camera, microphone and geolocation, and HTTP Strict Transport Security. HTTPS is forced and all plain-HTTP requests are redirected. - The site is open source too. It lives in its own repository under the same MIT licence, so you can read or diff exactly what is serving these pages.
- This site is documentation, not the source of truth. Every install instruction points at PyPI or GitHub. If this domain ever disappeared, nothing about LAN Fence would change.
Standard web-server access logs (IP, timestamp, requested path, user agent) may be retained for a short period for abuse and reliability purposes. That is the extent of it.
Verifying your download
Install LAN Fence only from these sources:
| Source | Canonical location |
|---|---|
| PyPI package | lanfence — https://pypi.org/project/lanfence/ |
| Source & releases | github.com/rosscooney/lanfence |
Before you install or upgrade:
- Pin the version and read the release notes and the diff for that tag on GitHub.
- Inspect the package if you want to — it is pure
Python:
pip download lanfence --no-deps --no-binary :all:and read the sdist. - Check release artifacts against the checksums (and, where published, build attestations) attached to the GitHub release.
# Pin an exact version rather than floating
pipx install "lanfence[scan]"==0.3.0
# Confirm what you got, offline
lanfence --version
lanfence check
A note on scapy
scapy is licensed GPL-2.0-only. LAN Fence's own code is
MIT and calls scapy as an ordinary, unmodified, independently-installed
library dependency (an import, not vendored source) — the
same relationship any Python tool has with a GPL library it depends on
via PyPI. It's kept an optional extra (lanfence[scan])
deliberately: the config, allowlist, device database and reporting
layers have no GPL dependency at all — only the actual ARP send/receive
code path needs it. If your organisation's licence policy treats
"depends on a GPL library at runtime" differently from "redistributes
GPL source", get your own legal read before shipping a downstream
product built on LAN Fence.
Running it well
LAN Fence's usefulness depends on it actually running, on the right interface, continuously:
- Run
lanfence checkafter installing to confirm permissions, the scanning interface/subnet and database writability. - For always-on coverage, run
lanfence monitorunder systemd (a sample unit is included) rather than a terminal session that will eventually close. - Run with
sudo, or grantCAP_NET_RAWto the interpreter for a non-root service user — without it, active/passive scanning cannot send or receive ARP packets. - Allowlist your own infrastructure early
(
lanfence allow) so real findings aren't buried in noise from devices you already trust. - Treat every finding as a lead to verify, never as confirmation on its own — see the honest limit above.
See the usage documentation for the full command reference.
Reporting a vulnerability
If you believe you have found a security vulnerability in LAN Fence, please report it responsibly.
- GitHub issue — open an issue on the
repository marked
security. - Email — [email protected], for anything you'd rather not put in a public issue first.
Please include:
- a description of the issue and its impact,
- steps to reproduce or a proof of concept,
- affected version(s) or commit hash,
- any suggested remediation.
In scope, for example: code that could let a device on the network influence LAN Fence beyond being observed and reported on, unsafe handling of report or database data, or command/log injection via crafted device metadata (hostname, vendor string). Not in scope: “LAN Fence failed to flag a device it should have” is not by itself a vulnerability — though improvements to detection coverage are very welcome as normal issues or pull requests.
What to expect from us
- Acknowledgement of your report as soon as reasonably possible.
- An assessment of the issue and, where accepted, a fix or mitigation.
- Credit in the release notes if you would like it.
LAN Fence is built and maintained by Stable State Consulting Ltd (www.stablestate.co.uk).