Dispositivi
Una persona, un telefono, un filtro — i dispositivi sono il modo in cui Warden sa a chi ha appena risposto.
Cos’è
Un dispositivo è un singolo endpoint sulla LAN — telefono, laptop, console, smart TV, lampadina IoT — fissato in Warden tramite il suo indirizzo IP, il suo MAC, o entrambi. Ogni dispositivo può avere il suo profilo, sovrascrivere una singola regola sopra il profilo del gruppo, o appoggiarsi al default della subnet.
Questa pagina copre quando aggiungere una voce dispositivo, ogni campo di identificazione e classificazione, e le superfici CLI / TUI / API che li leggono e li scrivono. Per il quadro d’insieme della risoluzione delle query, vedi processo di filtraggio. Per i vincoli per campo, vedi il riferimento TOML.
Quando ti serve
Aggiungi una voce [[devices]] quando ti serve una di queste cose:
- Un profilo che segue una persona specifica anche quando il MAC viene randomizzato (telefoni dei bambini, laptop dei ragazzi).
- Un’eccezione per un singolo dispositivo sopra un profilo — per esempio, il profilo “kids” blocca YouTube ma l’iPad della figlia maggiore lo usa per la scuola.
- Un nome leggibile nella TUI / nel query log al posto di
192.168.1.107. - Un bersaglio per le scorciatoie
block/quiet(“metti l’iPad in punizione fino alle 21:00”).
Non serve una voce per ogni host. Gli host non mappati ricadono sulla subnet ([[subnets]]) o sul default_profile globale, ed è esattamente il comportamento giusto per una VLAN ospiti o una serie di lampadine IoT identiche.
Schema
Una voce [[devices]] ha tre strati: identità (come Warden abbina il dispositivo), classificazione (come compare in TUI e CLI), e overlay (eccezioni per dispositivo sopra il profilo risolto).
Dimensioni di identità
Warden abbina un dispositivo confrontando l’IP sorgente di una query DNS con queste firme. Una sola firma è sufficiente — IP e MAC si combinano in OR, non in AND, quindi configurarli entrambi permette di raggiungere il dispositivo anche dopo un rinnovo DHCP o una randomizzazione del MAC.
| Firma | Campo TOML | Formato | Note |
|---|---|---|---|
| IP statico | ip | IPv4 (10.10.1.50) o IPv6 (fe80::1); valore singolo | Il dispositivo perde l’identità se il lease viene riassegnato. Fissa il lease sul router, o abbina un mac. |
| MAC primario | mac | AA:BB:CC:DD:EE:FF | Risolto tramite la tabella ARP viva. Le voci stantie vengono saltate. iOS Private Wi-Fi e Android randomizzano per rete — usa mac_aliases in quei casi. |
| Alias MAC | mac_aliases | Lista di AA:BB:CC:DD:EE:FF | Basta una corrispondenza per identificare il dispositivo. Utile per i telefoni che ruotano il MAC; cattura ogni nuovo MAC dalla lista unmapped della TUI. |
Se [server].enforce_client_mac = true (il default) e la tabella ARP mostra un MAC che non corrisponde né a mac né a un mac_aliases, il dispositivo viene declassato fuori dal suo profilo diretto e trattato come non mappato — si applica la subnet o il default_profile. Il declassamento è ergonomico, non crittografico: un attaccante deciso con accesso fisico può falsificare qualsiasi MAC, ma basta a impedire a un adolescente curioso di cambiarsi l’IP statico per sfuggire al profilo “kids”.
Riferimento dei campi
| Campo | Tipo | Obbligatorio | Default | Scopo |
|---|---|---|---|---|
id | stringa, [a-z0-9_-], ≤64 byte | sì | — | Chiave stabile usata da gruppi, schedule, IPC, statistiche. |
display_name | stringa | sì | — | Nome leggibile mostrato in TUI, query log, audit. |
ip | IPv4 o IPv6 | uno tra ip/mac | — | Pin statico. Almeno uno tra ip o mac deve essere impostato. |
mac | XX:XX:XX:XX:XX:XX | uno tra ip/mac | — | MAC primario. Verificato contro ARP. |
mac_aliases | lista di MAC | no | [] | MAC aggiuntivi per telefoni che randomizzano. Una corrispondenza qualsiasi identifica il dispositivo. |
profile | id di profilo | no | non impostato | Assegnazione diretta. Vince su gruppi, subnet, default. |
groups | lista di id di gruppo | no | [] | Appartenenze. Vince il profilo del gruppo a priorità più alta se profile non è impostato. |
owner | stringa, ≤64 byte | no | non impostato | Chi possiede il dispositivo (es. "Edoardo"). Asse di raggruppamento nella TUI. |
device_type | stringa, ≤64 byte | no | non impostato | Etichetta libera ("iPhone personale", "Smart TV"). L’alias legacy device viene ancora caricato. |
department | stringa, ≤64 byte | no | non impostato | Raggruppamento logico ("famiglia", "ufficio"). Asse di raggruppamento nella TUI. |
tags | lista di stringhe, [a-z0-9_-], ≤32 char | no | [] | Etichette libere per filtrare. Massimo 16 tag. Nessun effetto sulla risoluzione. |
notes | stringa, ≤256 byte | no | non impostato | Annotazione locale. Non viene mai inviata via IPC. |
allow_rules | lista di id di admin rule | no | [] | Overlay di allow per dispositivo — domini lasciati passare solo per questo dispositivo. |
deny_rules | lista di id di admin rule | no | [] | Overlay di deny per dispositivo — blocchi aggiuntivi sopra il profilo. |
override_profile_deny | bool | no | false | Se true, una voce di allow_rules può sovrascrivere un deny a livello di profilo sullo stesso dominio. Visibile nella tab Resolver della TUI. |
Il tetto combinato allow_rules + deny_rules è di 64 voci (soft, warning del validator) / 128 (hard, rifiutato). Fonte: src/config/schema/device.rs.
Esempi
Voce minima — fissa un host, puntalo a un profilo:
[[devices]]
id = "kids-tablet"
display_name = "iPad dei bambini"
ip = "10.10.1.50"
mac = "11:22:33:44:55:66"
profile = "kids"Un dispositivo che segue una ragazzina anche con MAC randomizzato, classificato per la TUI, con un’unica regola di allow sopra il profilo “kids” per la scuola:
[[devices]]
id = "anna-iphone"
display_name = "iPhone di Anna"
ip = "10.10.1.107"
mac = "AA:BB:CC:DD:EE:FF"
mac_aliases = [
"22:33:44:55:66:77",
"33:44:55:66:77:88",
]
profile = "kids"
owner = "Anna"
device_type = "iPhone"
department = "famiglia"
tags = ["mobile", "scuola"]
allow_rules = ["anna-allow-classroom"]
override_profile_deny = falseUn dispositivo senza profilo diretto — il profilo arriva dal gruppo a priorità più alta a cui appartiene:
[[devices]]
id = "kitchen-bulb"
display_name = "Lampadina cucina"
mac = "FF:EE:DD:CC:BB:AA"
groups = ["iot-lite"]
device_type = "Smart bulb"
department = "iot"devices.d/*.toml (uno per persona, stanza, o VLAN). Il config.toml master li include tramite includes. I diff restano leggibili e warden device add instrada automaticamente le nuove voci nel file giusto.CLI
Ogni sottocomando di scrittura attiva un hot reload del daemon (swap atomico della config, niente restart). I sottocomandi di sola lettura (list, show) funzionano anche senza il daemon.
| Comando | Cosa fa |
|---|---|
warden device list | Stampa i dispositivi configurati dalla config su disco. |
warden device list --live | Statistiche live per dispositivo dal daemon (query, % bloccate, ultimo visto, profilo risolto). |
warden device show <id> | Renderizza una voce dispositivo come coppie chiave/valore. |
warden device add <id> --ip <ip> [--mac <m>] [--profile <p>] [--owner <o>] [--device-type <t>] [--department <d>] [--tags a,b] [--display-name <n>] [--into <file>] | Crea un nuovo dispositivo. È richiesto almeno uno tra --ip / --mac. |
warden device set <id> <campo> <valore> | Modifica un singolo campo. Supportati: ip, mac, profile, display_name, owner, device, department, notes, tags, groups. Usa none per azzerare un campo nullable. |
warden device remove <id> | Cancella un dispositivo. Rifiutato se uno schedule lo referenzia ancora. |
warden device block <id> | Imposta il profilo del dispositivo su blocked (creato in automatico se manca). |
warden device unblock <id> [--profile <p>] | Rimette il dispositivo su un profilo (default default). |
warden device quiet <id> --for 30m | Blocco temporaneo one-shot tramite uno schedule a scadenza. Accetta --for 1h30m o --until <RFC 3339>. |
warden device allow <device-id> <dominio> | Aggiunge un allow per dispositivo su un dominio. Rifiutato con RULE_REFUSED_OVERRIDE se il profilo del dispositivo nega lo stesso dominio e override_profile_deny = false. |
warden device deny <device-id> <dominio> | Aggiunge un deny per dispositivo su un dominio. |
warden device rules <device-id> prune | Rimuove le voci pendenti di allow_rules / deny_rules che non puntano più a un admin rule reale (LIST_PRUNE_WARN). |
Pattern comuni:
# fissa un nuovo tablet
sudo warden device add kids-tablet \
--ip 10.10.1.50 --mac 11:22:33:44:55:66 \
--profile kids --owner Daisy --device-type iPad
# coprifuoco
sudo warden device quiet kids-tablet --for 12h
# eccezione per un singolo dispositivo
sudo warden device allow anna-iphone classroom.example.com
# attività live
warden device list --liveFonte: src/cli/commands/devices.rs, src/cli/mod.rs:474.
TUI
Premi 3 (o g d) nella TUI per saltare alla tab Dispositivi. La vista è master/detail: dispositivi configurati e host non mappati osservati live in un’unica lista, con una scheda di dettaglio sulla destra che mostra vendor, statistiche di cache, alias MAC, e profilo effettivo.
Combinazioni di tasti nella tab Dispositivi:
a— apre il modal Aggiungi (i campi rispecchianowarden device add).e— Modifica il dispositivo configurato selezionato.d— Cancella con conferma s/n. Rifiutato se uno schedule lo referenzia ancora.Entersu una riga non mappata — promuovi la riga: il modal Aggiungi si apre già pre-compilato con IP + MAC osservati; tu fornisciidedisplay_name.G— cicla l’asse di raggruppamento: nessuno →owner→department→profile.↑/↓(oj/k) — naviga; le righe header dei gruppi vengono saltate.
La lista interroga il daemon ogni 5 s tramite il comando IPC DeviceStats. Fonte: src/tui/tabs/devices.rs.
API REST
Le statistiche live dei dispositivi sono esposte dalle API locali.
GET /api/devices — autenticato con Bearer token. Restituisce un array JSON, una voce per ogni dispositivo che ha colpito il daemon dall’ultimo snapshot:
[
{
"name": "kids-tablet",
"ip": "10.10.1.50",
"queries": 4321,
"blocked": 187,
"blocked_pct": 4.3,
"cache_hits": 2890,
"profile": "kids",
"last_seen": 1714820400
}
]Il path legacy /api/clients è deprecato; le risposte trasportano gli header Deprecation e Sunset che puntano a /api/devices.
IPC
Sul socket Unix: IpcCommand::DeviceStats { token: None } restituisce IpcResponse::DeviceList { clients: Vec<DeviceStatEntry> }. Stessi campi della REST. Sola lettura, nessun token richiesto. Fonte: src/api/handlers.rs, src/ipc/protocol.rs.
Ordine di precedenza
Quando arriva una query, Warden percorre cinque livelli in quest’ordine. Vince la prima corrispondenza.
- Profilo diretto del dispositivo. L’IP sorgente corrisponde a
ip(o il MAC corrisponde via ARP), e il dispositivo impostaprofile = "...". - Schedule attivo. Una voce
[[schedules]]con una finestra temporale che copre adesso riguarda questo dispositivo o uno dei suoi gruppi. - Profilo di gruppo. Il dispositivo non ha
profilediretto ma appartiene a uno o più[[groups]]. Vince il gruppo a priorità più alta; i conflitti a parità di priorità sono errori del validator. - Subnet, longest-prefix match. L’IP sorgente non è in
[[devices]]ma cade in un CIDR di[[subnets]]. Vince il prefisso più lungo. - Fallback globale.
[server].default_profile. Se non impostato, le query non mappate ricevono REFUSED.
override_profile_deny, allow_rules e deny_rules agiscono dentro il profilo risolto — sono un overlay, non un livello a parte.
Se enforce_client_mac = true e ARP mostra un MAC diverso, il dispositivo viene declassato al livello 4 (subnet) per quella query. Schedule, gruppo e profilo diretto vengono saltati. Fonte: src/profiles/resolver.rs.
Note di sicurezza
- Gli indirizzi MAC sono in chiaro in
config.tomledevices.d/*.toml. Non vengono hashati. - Il query log registra
client_ipeclient_name(l’iddel dispositivo). Non registra il MAC. - L’audit log registra le operazioni CRUD sui dispositivi — add, remove, modifica di campi, overlay allow/deny — con uid del chiamante, azione, target id, e se è stato usato
override_profile_deny. Non registra i MAC. - L’enforcement del MAC è ergonomico, non crittografico. Ferma il cambio IP casuale, non un attaccante deciso con accesso fisico. Per la garanzia precisa, vedi modello delle minacce.
- Le note (
notes = "...") restano locali. Non vengono mai serializzate via IPC o REST.
Risoluzione problemi
Viene applicato il profilo sbagliato. Chiedi direttamente al resolver:
warden resolve 10.10.1.50
# Level 1: device 'kids-tablet' → profile 'kids'Se il livello mostrato non è quello che ti aspettavi, risali la catena — il MAC è stato randomizzato? il lease si è spostato? enforce_client_mac sta declassando il dispositivo?
Un telefono che ieri funzionava oggi finisce sulla subnet. Quasi sempre randomizzazione del MAC. Controlla nella tab Dispositivi della TUI la riga non mappata che condivide lo stesso IP — mostra il nuovo MAC. Promuovila (Enter) o aggiungila a mac_aliases:
sudo warden device set anna-iphone mac_aliases "[AA:BB:CC:DD:EE:FF,22:33:44:55:66:77]"Un dispositivo fissato solo per IP perde il profilo dopo un riavvio del router. Il DHCP ha riassegnato il lease. Fissa il lease sul router, oppure aggiungi un mac alla voce così l’identità segue l’hardware.
warden device allow è rifiutato con RULE_REFUSED_OVERRIDE. Il profilo del dispositivo nega già quel dominio e override_profile_deny è false. Alza il flag e riprova, oppure aggiungi la regola di allow a livello di profilo:
sudo warden device set anna-iphone override_profile_deny true
sudo warden device allow anna-iphone classroom.example.comUn host dual-stack riceve il profilo sbagliato su IPv6. Lo schema attuale memorizza un solo ip per dispositivo. Se l’host ha indirizzi v4 e v6 separati, fissa l’IPv6 con una voce [[subnets]] che copra il suo CIDR IPv6, oppure affidati al mac (che funziona indipendentemente dalla famiglia di indirizzi, finché il dispositivo è sullo stesso segmento L2 di Warden).
Per altro, vedi risoluzione problemi.
Vedi anche
- Profili — cosa contiene un profilo (liste di blocco, regole, risposta di blocco).
- Gruppi — assegna un solo profilo a molti dispositivi.
- Subnet — fallback per host non mappati.
- Pianificazioni — scambi di profilo basati sull’orario.
- Regole admin — le regole referenziate da
allow_rules/deny_rules. - Riferimento TOML — ogni campo, ogni vincolo.
- Riferimento CLI — la superficie completa di
warden device ….