NAC - CyberMind-FR/secubox-deb GitHub Wiki
EN | FR | 🟠 AUTH | who is on the network, in which zone, and why
What it is for. The NAC (Client Guardian, package
secubox-nac) keeps an inventory of every device on the local network, places each one in a zone enforced by nftables, deduces its operating system from evidence, and isolates in quarantine whatever should not be trusted. An unknown device lands in quarantine by default.
- Package:
secubox-nac· panel/nac/· API/api/v1/nac/· config/etc/secubox/nac.toml - It absorbs the former
mac-guard,device-intelandiot-guardmodules: their old addresses redirect to/nac/(301) and their old APIs answer 410.
Each device belongs to one zone, backed by an nftables set. The chains run at
priority filter - 5: a drop is final, a mistake never opens anything.
| Zone | Set | Effect |
|---|---|---|
lan |
lan_allowed |
no restriction |
lxc |
lxc_zone |
no restriction (containers on br-lxc land here automatically) |
iot |
iot_zone |
internet yes; LAN and containers (RFC 1918) no |
guest |
guest_zone |
internet yes; LAN and containers no |
quarantine |
quarantine_zone |
nothing through the box; towards the box only DHCP and DNS |
| banned | blocked |
nothing in or out, neither to the box nor through it |
An operator move always wins; the interface-based classification (br-lxc →
lxc, extensible with interface_zones in the [nac] config) only fills the
gap for devices not placed explicitly.
The API runs unprivileged and never calls nft.
- Blocking, quarantining or changing zone writes the desired state to
/var/lib/secubox/nac/nft-desired.json(atomic, locked). -
secubox-nac-apply.pathnotices the change and startssecubox-nac-apply(root, narrow:CAP_NET_ADMINonly). It validates every MAC and set name, then loads the rules and elements in one transaction. - At nftables start (and every restart) the table is rebuilt from that state.
The real status is in nft-applied.json and surfaced by /status; GET /sync_zones asks for a new application.
The collector fills four fields per device, shown in the panel and in
GET /clients and GET /client/{mac}:
| Field | Meaning |
|---|---|
os |
deduced system (iOS 17, Android 13, Windows, OpenWrt (Linux)…) or empty |
os_source |
the proof, mandatory as soon as os is set: dhcp-vendor-class:…, user-agent:…, dns:<domain>, hostname:<name>, empreinte-nac:openwrt
|
device_subtype |
fine type: smartphone, tablet, television, printer, streaming, connected object… |
mac_random |
1 when the MAC "locally administered" bit is set (iOS/Android/Windows privacy addresses) |
Rules:
- No inference without proof: an OS without a source is refused.
- The manufacturer (OUI) alone never gives an OS; a random MAC is not typed by its vendor.
- Stronger evidence wins: DHCP vendor class > User-Agent > DNS domains > device name > NAC fingerprint. mDNS services are also understood.
- A conclusion whose proof has disappeared is withdrawn at the next cycle.
Evidence actually wired today: the device name, the connectivity DNS domains (read-only, from the ad-guard database, never any other domain), the OpenWrt/SecuBox fingerprint and, since 3.9.0, the Bonjour/mDNS service types (see below). DHCP vendor class and User-Agent are understood by the detector but not yet fed: when the DHCP server is the internet box, the NAC does not see option 60, and no per-device User-Agent is reported yet.
LXC containers carry a conteneur flag; ?exclure_conteneurs=true hides them.
Since secubox-nac 3.9.0, a cached avahi-browse pass (120 s) fills in what the
DHCP leases do not say:
- the name of a device that has no lease (a lease always wins) and the announced name (for example a living-room TV);
-
service badges (printing, AirPlay, Chromecast, sharing…), returned as
servicesbyGET /clientsand searchable from the page; - the service types also feed the detection of the fine device type.
If Bonjour is absent or fails, discovery goes on without it. Since 3.9.1 the call
uses avahi-browse -k; without it the service types were translated into text and
no service was recognised.
The containers of our own modules are known by name even without DNS or lease.
A narrow root service, secubox-nac-lxc-names (5-minute timer), writes an
inventory conteneurs.json (address → name) because the container folders are
closed to the NAC account; the NAC uses it for devices that have no name. A
missing or unreadable file means no name, never an error.
| Case | How |
|---|---|
| Unknown device | default zone is quarantine (default_zone in the policy) |
| Manual |
Quarantine in the panel, or POST /quarantine_client
|
| Release |
Release moves the device to lan (POST /unquarantine) |
| Ban |
POST /ban_client (set blocked), POST /unban_client returns it to quarantine |
| Automatic | when the actor-intelligence engine publishes the QUARANTINE measure for a LAN device (risk ≥ 75, confidence ≥ 80, at least two distinct sensors) |
Automatic quarantine uses the same quarantine zone. There is no automatic release: an administrator recognises and validates the device. One measure isolates only once.
[nac] setting (/etc/secubox/secubox.conf) |
Default | Role |
|---|---|---|
quarantaine_auto |
auto |
auto isolates, propose only records the candidate, off disables; any other value means off
|
quarantaine_protegees |
[] |
MAC addresses never isolated |
Never isolated: the box itself, a router, an OpenWrt/SecuBox device, a protected
MAC, or a device absent for more than 3 h. GET /quarantaine/auto returns the
mode and the candidates; each isolation leaves a quarantine_auto line in the
device history and a client_quarantined_auto event.
Appareils du réseau — who is connected, since when, on which OS, and what the NAC decided.
| Block | Content |
|---|---|
| Tiles | devices, connected, unknown, quarantined, allowed, share of identified OS (each tile has its definition in a tooltip). Since 3.6.1 the tiles are filter buttons (Connected, Unknown, Quarantined, Allowed, Identified OS; Devices resets everything) and the active tile follows the drop-down lists |
| Device cards | search (name, IP, vendor, OS, service), filters (state, OS, connected or not), sort (last seen, name, IP); each card shows the device's web filter (content-filtering profile, requests blocked and classified over 7 days, or "managed by ad-guard", read-only) |
| Real clients | since 3.7.0, the NAC device, its Toolbox identities and its DPI activity are joined on evidence (device key = hash of the MAC; otherwise the same announced tunnel address, flagged as deduced; otherwise the identity alone): global usage pie, histogram of active clients by usage type, one sheet per client |
| LXC containers | the containers on the br-lxc bridge have their own panel and no longer appear in the device list, the tiles, the splits or the new devices; the quarantine action stays reserved to devices |
| Charts | split by OS (with the evidence), split by state, zones, new devices in 24 h |
| Zone behaviour | the real behaviour of each zone, drawn from the actual nft rules (see below) |
| Read-only | admission policy, recent history |
Actions: assign a device to a zone (LAN, IoT, Guests, Quarantine), Allow, Block, Quarantine and Release, each with an in-page confirmation. The API exposes the NAC zone, not a VLAN number, and the page says so.
GET /zone_behaviors (administrator) returns what each zone really does:
isolation of the LAN, the box's own DNS and DHCP, quarantine, blocked. Nothing is
declared that is not applied: each line repeats a rule of the shipped nft file
(a test checks it). What the NAC does not do (DNS sinkhole for quarantine,
parking page, fallback zone, Tor or VPN per zone) is listed apart and marked
unavailable. Tor and VPN do exist, but as a per-client Toolbox choice (levels R0
to R3, WireGuard tunnel), not as a property of a NAC zone; the analysis (DPI,
DNS, Actor Intelligence) observes the traffic whatever the zone. Add
?demo=1 for a demonstration view (a banner says so, actions are inert) and
?embed=1 to embed the page in another one.
Guards: require_jwt (administrator) to act, read access for the status.
| Method | Path | Purpose |
|---|---|---|
| GET |
/status, /summary, /stats
|
module state and counters |
| GET |
/clients, /client/{mac}
|
inventory, detail (OS, source, subtype) |
| GET | /zones |
zones and members |
| POST |
/add_to_zone, /remove_from_zone
|
move a device |
| POST |
/approve_client, /ban_client, /unban_client
|
decide |
| POST |
/quarantine_client, /unquarantine
|
quarantine and release |
| GET/POST | /policy |
admission policy |
| GET |
/history, /alerts
|
events |
| GET | /quarantaine/auto |
automatic quarantine mode and candidates |
| POST | /scan |
active scan of a subnet (validated) |
- ToolBox — the digital phone booth (quarantine of an exposed device)
- DNS-Filtrage — ad-guard, whose DNS evidence feeds OS detection
- Device-Categories — device taxonomy
- Admin-Panels-Gallery — the common Aurora panel style
- Webfilter — the content filter whose profile each device card shows
- Architecture — the six-module stack