IT

Liste di blocco

Work in progress — content may be incomplete.
Pagina superata — non seguirla

Tutto quello che segue descrive il modello di liste v1, ritirato: il campo category, la sezione [[categories]], [profiles.<id>].blocklists, [profiles.<id>].categories, i comandi warden category … e warden blocklist set-category. Nessuno di questi esiste più, e una configurazione che li usa viene rifiutata al caricamento con unknown field.

Oggi le liste si selezionano per intersezione di tag: una blocklist porta dei tag, un profilo chiede dei tag, e la lista si applica quando i due insiemi si sovrappongono. Il modello corretto è documentato in profili. Per convertire una configurazione pre-tag usa warden migrate.

La riscrittura di questa pagina è specificata e in corso.

Una lista di blocco è una sorgente di domini. I profili decidono quali far valere, e Warden decide cosa fare delle corrispondenze.

Cos’è

Una lista di blocco è una voce dichiarativa con nome, che dice a Warden dove scaricare un elenco di domini, come parsarli, ogni quanto aggiornarli, e in che modo devono partecipare al filtro — come sorgente di deny (default) o, con trust = "local", come sorgente di allow. Ogni riga [[blocklists]] ha un id, vive nella configurazione fusa, ed è referenziata da uno o più profili tramite [profiles.<id>].blocklists (sottoscrizione diretta) o [profiles.<id>].categories (indiretta, per categoria).

Questa pagina copre quando aggiungere una voce [[blocklists]], ogni dimensione che puoi regolare al suo interno, le superfici CLI / TUI / API che le leggono e le scrivono, come una lista partecipa alla catena del filtro, e come Warden isola le sorgenti esterne in modo che un feed ostile non possa forare i tuoi override. Per come un profilo sceglie le liste da far valere, vedi profili; per la controparte autorizzata dall’operatore che può esprimere allow, regex, e $important, vedi regole admin.

Quando ti serve

Aggiungi o sostituisci liste quando:

  • Stai installando. Un’installazione nuova è già sottoscritta a security/malicious, privacy/ads e privacy/tracking dal catalogo purge.cc. È il default sensato per un homelab. Esplora il resto con warden lists catalog.
  • Vuoi stringere un profilo. Sovrapponi feed mirati — content/adult per un profilo bambini, content/gambling per un piccolo ufficio, services/tiktok per un profilo focus.
  • Porti la tua lista. Una URL remota di cui ti fidi (https://big.oisd.nl/, una allowlist aziendale interna), oppure un file locale che hai scritto tu e importato con warden blocklist import-local.
  • Stai migrando da Pi-hole o AdGuard Home. I formati domains, hosts e adguard coprono praticamente ogni adlist in giro. I file esistenti si importano così come sono.

Non ti serve una voce [[blocklists]] quando vuoi:

  • Consentire o negare un singolo dominio per un dispositivo o un profilo — è un compito da regola admin referenziata da [profiles.<id>].admin_rules o da [[devices]].allow_rules / deny_rules.
  • Esprimere regole @@ di allow, $important, regex, o wildcard. Le liste esterne sono confinate fuori da quei poteri; solo le admin rule li onorano. Vedi note di sicurezza.
  • Regolare la risposta di blocco (forma del RCODE, TTL) — vive sul profilo, non sulla lista.

Schema

Una lista di blocco è una riga di array-of-tables[[blocklists]], ripetibile. Ogni riga richiede come minimo un id, un nome leggibile, e una URL.

[[blocklists]]
id           = "privacy-ads"
display_name = "Privacy: ads"
url          = "https://lists.purge.cc/privacy/ads.txt"
format       = "domains"
kind         = "block"
trust        = "remote-unsigned"
category     = "default"

Dimensioni

Una lista di blocco è un vettore lungo questi assi indipendenti. Combinabili — solo id, display_name e url sono obbligatori; tutto il resto ha un default sensato.

GruppoDimensioneCampo TOMLCosa regola
IdentitàididRiferimento incrociato stabile. I profili si sottoscrivono con questo id. Charset [a-z0-9-], ≤64 caratteri, niente - iniziali o finali.
Nome leggibiledisplay_nameEtichetta operatore mostrata in warden blocklist list, nella tab Lists della TUI, e nelle righe di audit. Non può essere vuoto.
SorgenteURLurlEndpoint HTTPS da cui scaricare. A runtime è ammesso solo https://; gli host loopback / RFC1918 / link-local / CGNAT / multicast / ULA sono rifiutati. Massimo 3 hop di redirect.
Token di autenticazione (opzionale)auth_token_refNomina una chiave in secrets.toml. Risolto al momento del fetch e inviato come Authorization: Bearer <valore>. Il segreto non compare mai nella configurazione fusa.
ParsingFormatoformatdomains (un host per riga), hosts (stile /etc/hosts con IP all’inizio), o adguard (regole `
Cap di vocimax_entriesSoglia di troncamento per lista. Oltre il cap il parser si ferma con un WARN. Default 5_000_000 (cap della CLI; il bitmask del motore supporta fino a 64 sorgenti di lista a livello di sistema).
Ciclo di vitaCadenza di refreshupdate_interval_hoursOgni quanto il daemon riscarica. Default 12. Il floor a runtime è 60 secondi. L’alias legacy refresh_interval_hours è ancora accettato con warning di deprecazione.
Flag attivoenabledDefault true. Dichiarato in configurazione ma disabilitato — la riga resta perché i profili che la referenziano restino validi.
Modello di trustDirezionekindblock (default) — i domini si aggiungono al deny set. allow — i domini si aggiungono all’allow set; valido solo con trust = "local".
Provenienzatrustremote-unsigned (default, solo HTTPS), local (file scritto dall’operatore, importato via warden blocklist import-local), o signed (riservato; non ancora supportato).
OrganizzazioneCategoriacategoryRiferimento incrociato a un id di [[categories]]. Una lista appartiene ad al massimo una categoria. I profili possono sottoscrivere per categoria invece che per id di lista.
Riferimenti (esterni)Profili che si sottoscrivono[profiles.<id>].blocklistsDiretto: un profilo nomina questo id.
Profili che matchano per categoria[profiles.<id>].categoriesIndiretto: un profilo nomina un id di categoria; ogni lista taggata con quella categoria viene unita.

Cose che sembrano dimensioni della lista ma non lo sono:

  • Cache directory e cap di byte per sorgente sono globali ([lists].cache_dir, [lists].max_body_bytes) — non per riga.
  • Pinning TLS, integrità sha256, metadata di licenza — non sono nello schema oggi. L’integrità oltre al TLS è il design dietro la variante parcheggiata trust = "signed".
  • Risposta di blocco per lista — vive sul profilo (block_response, blocked_ttl_secs), non sulla lista.

Riferimento dei campi

CampoTipoObbligatorioDefaultScopo
idstringa, [a-z0-9-], ≤64 caratteriRiferimento incrociato stabile.
display_namestringa, non vuotaEtichetta operatore.
urlstringa, http(s)://…URL della sorgente. A runtime solo HTTPS, host privati rifiutati.
formatenumnodomainsdomains | hosts | adguard.
update_interval_hoursu32, > 0no12Cadenza di refresh. Alias legacy refresh_interval_hours accettato con WARN.
max_entriesu64, > 0no5_000_000Cap del parser per lista.
enabledboolnotrueFlag attivo.
auth_token_refstringanoChiave in secrets.toml.
kindenumnoblockblock | allow. allow richiede trust = "local".
trustenumnoremote-unsignedlocal | remote-unsigned. signed è riservato.
categoryid di categorianoRiferimento incrociato a [[categories]].id.

#[serde(deny_unknown_fields)] è attivo — i typo falliscono al caricamento con unknown field. Fonte: src/config/schema/blocklist.rs:97-141.

Le categorie vivono accanto alle liste

Le categorie sono definite dall’operatore, non un enum chiuso, e sono pura organizzazione — niente campi di policy. Una categoria è ciò che permette a un profilo di sottoscriversi a “tutto quel che è taggato family” invece che nominare ogni lista per id.

/etc/purge-warden/categories.d/default.toml
toml
[[categories]]
id           = "default"
display_name = "Default"
description  = "Liste fornite dal catalogo curato"

[[categories]]
id           = "family"
display_name = "Famiglia"
description  = "Filtri rilassati per i dispositivi degli adulti"
color        = "#3a86ff"

La risoluzione al caricamento è deterministica: [profiles.<id>].categories è percorso in ordine alfabetico di id di categoria, poi all’interno di ogni categoria ogni [[blocklists]] corrispondente è aggiunta in ordine alfabetico di id di lista, poi [profiles.<id>].blocklists è aggiunto in ordine di config, deduplicando lungo il cammino. Un riferimento a category pendente fa fallire il caricamento con CATEGORY_NOT_FOUND. Fonte: src/config/schema/category.rs:1-55, src/config/schema/validator.rs:811-904.

Vincoli di direzione e trust

kindtrust richiestoCosa faQuando usarlo
block (default)remote-unsigned o localI domini alimentano il deny set. Il caso standard.Liste del catalogo curato, adlist di terzi, il tuo file di deny.
allowsolo localI domini alimentano l’allow set. Vince sui deny a livello di lista salvo che un’admin $important deny lo superi.Una allowlist lunga scritta da te (domini scolastici, SaaS aziendali) che preferisci esprimere come lista invece che come 200 admin rule.

Il validator rifiuta kind = "allow" accoppiato a trust = "remote-unsigned" al caricamento con ALLOW_LIST_REQUIRES_LOCAL_TRUST. Il messaggio congelato — letterale da src/config/schema/validator.rs:734-738 — è:

Blocklist '<id>' has kind=allow but trust='<got>'. Allow-direction lists
require trust=local. Use `warden blocklist import-local` to import a local file.
Allowlist oggi: meglio admin_rules
Lo schema accetta kind = "allow" e il validator fa rispettare l’accoppiamento con trust. Il percorso allow-mask del motore di filtro è cablato ma le *.public.md upstream segnalano il supporto end-to-end del motore come “in progress” fino al prossimo rilascio. Per una semantica di allow stabile oggi, instrada gli allow operatore tramite [[admin_rules]] referenziati da [profiles.<id>].admin_rules. Il percorso kind = "allow" è la scelta long-form giusta per grandi allowlist curate; per uno o due domini, una admin rule è più semplice e collaudata.

Esempi

Una sottoscrizione a una lista curata di purge.cc:

/etc/purge-warden/blocklists.d/curated.toml
toml
[[blocklists]]
id           = "privacy-ads"
display_name = "Privacy: ads"
url          = "https://lists.purge.cc/privacy/ads.txt"
format       = "domains"

Una lista di terzi in sintassi AdGuard, aggiornata ogni 6 ore:

/etc/purge-warden/blocklists.d/oisd.toml
toml
[[blocklists]]
id                    = "oisd-big"
display_name          = "OISD Big (AdGuard)"
url                   = "https://big.oisd.nl/"
format                = "adguard"
update_interval_hours = 6

Una lista privata aziendale con bearer auth — il segreto resta fuori dalla configurazione fusa:

/etc/purge-warden/secrets.toml
toml
# mode 0600 — il daemon altrimenti rifiuta di partire
corp-ads-token = "bearer-xxxxxxxxxxxxxxxx"
/etc/purge-warden/blocklists.d/corp.toml
toml
[[blocklists]]
id             = "corp-ads"
display_name   = "Corporate ads"
url            = "https://internal.example.com/blocklists/ads.txt"
format         = "domains"
auth_token_ref = "corp-ads-token"

Un setup guidato dalle categorie — i profili si sottoscrivono per categoria, gli id delle singole liste restano locali al file che le dichiara:

/etc/purge-warden/categories.d/_index.toml
toml
[[categories]]
id           = "default"
display_name = "Default"

[[categories]]
id           = "iot-strict"
display_name = "IoT strict"
description  = "Blocca tutto tranne il minimo cloud del produttore"
/etc/purge-warden/blocklists.d/iot.toml
toml
[[blocklists]]
id           = "iot-telemetry"
display_name = "IoT telemetry"
url          = "https://lists.example.org/iot.txt"
format       = "domains"
category     = "iot-strict"
[profiles.iot]
display_name   = "IoT"
categories     = ["iot-strict"]   # nessuna blocklist esplicita; la categoria si risolve
block_response = "soa_nodata"

Una allowlist locale importata da un file che tieni in version control:

sudo warden blocklist import-local ./domini-scolastici.txt \
  --id           school-allow \
  --kind         allow \
  --category     family \
  --display-name "Domini approvati dalla scuola"

L’import copia il file sotto <config-parent>/lists/<id>.txt, registra una riga [[blocklists]] con trust = "local", auto-rileva il format e assegna una URL sintetica https://imported.local/<id>.txt per soddisfare il requisito http(s):// dello schema. Quella URL sintetica è documentata; se leggi il TOML generato e ti chiedi perché un import “local” abbia una URL https://, è il motivo. Fonte: src/cli/commands/blocklists.rs:855-866.

Tip
Suddividi le liste in blocklists.d/<tema>.toml (un file per bundle di sorgente — curated.toml, corp.toml, iot.toml). Il config.toml master li include tramite includes. I verbi della CLI accettano --into <file> per instradare la scrittura nel frammento giusto.

CLI

Ogni sottocomando di scrittura attiva un hot reload (swap atomico della config, niente restart del daemon). I sottocomandi di sola lettura funzionano anche senza il daemon.

ComandoCosa fa
warden blocklist listElenca le righe [[blocklists]] configurate con id, display name, format, intervallo di refresh, kind, trust, categoria.
warden blocklist show <id>Dump di dettaglio completo, comprensivo della telemetria a runtime interrogata via IPC: voci parsate, parsed_skipped, timestamp dell’ultimo fetch, ultimo esito, delta rispetto al refresh precedente, e una sezione “Used by:” con i profili che la sottoscrivono.
warden blocklist add <id> --url <url> [--display-name --format --update-interval-hours --max-entries --enabled --auth-token-ref --into <file>]Aggiunge una nuova lista dichiarata. Rifiutato se l’id esiste già. Verifica auth_token_ref contro secrets.toml ed emette un warning (non un errore) se manca.
warden blocklist set <id> <campo> <valore>Modifica un singolo campo. Supportati: display_name, url, format, update_interval_hours (alias legacy refresh_interval_hours accettato con WARN), max_entries, enabled, auth_token_ref.
warden blocklist set-category <list-id> <category-id> [--into <file>]Sposta una lista tra categorie. Idempotente. Audit-loggato come blocklist.set_category.
warden blocklist set-kind <list-id> <block|allow> [--into <file>]Cambia direzione. Il reload valida il vincolo kind = allow ⇒ trust = local; i tentativi rifiutati fanno rollback del file e audit-loggano un evento Rejected.
warden blocklist set-trust <list-id> <local|remote-unsigned> [--into <file>]Modifica la provenienza. signed è rifiutato dal parser con il messaggio di feature parcheggiata.
warden blocklist remove <id> [--cascade] [--into <file>]Rifiutato se un profilo referenzia ancora l’id. --cascade rimuove l’id da ogni profilo che lo referenzia in un’unica transazione con un solo reload condiviso.
warden blocklist import-local <path> --id <list-id> --kind <block|allow> --category <cat-id> [--display-name --into <file>]Copia un file locale nell’albero di configurazione, registra una riga trust = "local", auto-rileva il formato. È l’unico percorso per arrivare a una lista a trust locale.
warden category list / add <id> / rm <id> [--cascade] / rename <old> <new>Gestisci le categorie. Cascade-rm riassegna le liste referenzianti a “Uncategorized” e rimuove l’id dai profili che la referenziano.
warden lists catalog [--scope <scope>]Sfoglia il catalogo purge.cc (16 liste tra privacy/*, security/*, content/*, services/*). Read-only, tocca la rete, indipendente dal daemon.
warden updateForza un refresh ora. Manda SIGHUP al daemon se è attivo, oppure scarica in foreground per validare la configurazione.

Pattern comuni:

# Sfoglia il catalogo curato, poi sottoscrivi
warden lists catalog --scope privacy
sudo warden blocklist add privacy-tracking \
  --url "https://lists.purge.cc/privacy/tracking.txt" \
  --format domains \
  --display-name "Privacy: tracking"

# Lega una lista al profilo kids (usa la superficie CLI dei profili)
sudo warden profile blocklists kids add privacy-tracking

# Sposta una lista in una categoria e forza un refresh ora
sudo warden blocklist set-category privacy-tracking family
sudo warden update

# Rimuovi una lista in modo pulito, scollegandola da ogni profilo che la referenziava
sudo warden blocklist remove privacy-tracking --cascade

Dopo ogni modifica con hot-reload, viene stampato esattamente uno di quattro messaggi — gli stessi usati da ogni percorso di scrittura della CLI:

  • daemon reloaded — change is live
  • daemon not running — change will take effect on next start
  • note: change landed on disk but no admin token is available to request a daemon reload. Run warden token generate or restart the daemon to activate.
  • warning: change landed on disk but the daemon rejected the reload (<msg>). Check journalctl -u purge-warden and consider systemctl restart purge-warden.

Esiste anche un warden lists add <slug> legacy che modifica la tabella globale [lists].sources invece di [[blocklists]]. Non fa hot-reload — ti dice di eseguire warden update o kill -HUP sul daemon. Per nuovi lavori, preferisci warden blocklist add; il verbo legacy resta utile per la sottoscrizione rapida agli slug del catalogo curato. Fonte: src/cli/mod.rs:743-849, src/cli/commands/blocklists.rs.

TUI

La tab Lists è raggiungibile con 7 dalla barra delle tab in alto. È una tabella raggruppata per categoria — le righe sono blocklist, le righe-separatore portano il display name della categoria e i conteggi aggregati di voci.

ElementoCosa mostraTasti utili
Rigaid, display name, conteggio voci, status, ultimo aggiornamento, profili che la usanoj / k / / scorre (salta le righe-categoria); Enter apre/chiude il drill-down per riga (campioni completi delle righe scartate fino a 8, errori di fetch, delta-pct rispetto al refresh precedente)
Modal di assegnazione profiliCheckbox per profilo; selezione multipla, commit unicop apri, Space toggle, Enter commit (singolo reload condiviso)
Modal di categoriaCrea categoria / sposta lista in evidenzac crea, m sposta, k toggle BLOCK ↔ ALLOW
RefreshForza un re-download della lista in evidenzar

Le statistiche sono interrogate via IPC ogni 30 secondi; il daemon emette anche un IpcNotification::ListStatsUpdated dopo ogni ciclo di refresh, così la tabella riflette successo o fallimento entro pochi secondi.

Cose che oggi può fare solo la CLI: add di una riga, set di campi arbitrari, remove, set-trust, import-local, category rename / rm --cascade. I modal S50 della TUI aggiungono set-category, set-kind, e la creazione di categoria. Fonte: src/tui/tabs/lists.rs.

API REST

MetodoPathCosa
GET/api/blocklists/{id}/statsTelemetria runtime per lista: entries, parsed_ok, parsed_skipped, fetched_at, last_outcome, delta_pct_vs_prev. Risolve l’id per stringa esatta della sorgente, poi per [[blocklists]].id, poi per substring case-insensitive.
GET/api/listsL’array legacy [lists].sources come JSON.
POST/api/lists/addAggiunge uno slug o una URL a [lists].sources. Fa scattare un reload.
DELETE/api/lists/removeSimmetrico. Fa scattare un reload.
POST/api/updateFa scattare un refresh.

Non c’è una CRUD REST per le righe [[blocklists]] — niente POST /api/blocklists, PATCH, o DELETE contro l’entità v1. La superficie REST per il modello v1 è telemetria in sola lettura; l’authoring dichiarativo passa per CLI / modifica TOML / TUI (dove supportato). Tutte le route /api/* sono protette da Bearer token (Authorization: Bearer ps_<64hex>), verificato in tempo costante, con lockout di 10 fallimenti / 5 minuti. Fonte: src/api/handlers.rs:623-852.

IPC

Il socket Unix espone IpcCommand::BlocklistStats { source_id: Option<String> } come verbo read-only senza token — la TUI lo usa per il polling a 30 secondi. Le mutazioni passano per il percorso standard IpcCommand::Reload { token } che ogni scrittura CLI attiva. Fonte: src/ipc/protocol.rs:240-260, 549-608.

Ordine di precedenza

Una lista contribuisce al filtro solo dopo che un profilo è stato scelto. La catena a 5 livelli che sceglie il profilo è documentata in profili — una query si abbina prima a un dispositivo, gruppo, subnet, pianificazione, o default; poi vengono valutate le liste del profilo scelto.

Dentro il profilo scelto

Un singolo walk per sottodominio sul nome della query in minuscolo sonda ogni set abilitato a ogni posizione di punto. Vince la prima decisione, in quest’ordine:

  1. Cortocircuito di block_all. Se il profilo ha block_all = true: nega tranne quando una admin rule di allow o local_records copre il dominio.
  2. Admin rules in priorità a 4 livelli — allow $important > deny $important > allow normale > deny normale. Una allow $important cortocircuita il resto.
  3. Allow set del profilo (HashSet allow_domains, contribuito dalle admin rule di allow del profilo e dai sinonimi delle liste con kind = "allow"): forward.
  4. Deny set del profilo (HashSet deny_domains, contribuito dalle admin rule di deny): block.
  5. Bitmask Tier 1 della lista — per ogni suffisso sondato, si consulta il bitmask della lista: un bit allow_mask (da una lista con kind = "allow") e un bit block_mask (da qualsiasi lista con kind = "block") si accumulano; allow vince i pareggi a questo tier salvo che un’admin $important deny più in alto la batta.
  6. Forward di default — qualsiasi cosa non abbia matchato va a monte.

Il walk è unificato — pre-S50 erano tre scansioni di suffissi indipendenti; ora un solo passaggio sonda ogni set per ogni posizione di punto. Fonte: src/filter/engine.rs:240-443.

Modello di memoria: collasso del bitmask

Ogni dominio distinto attraverso ogni lista sottoscritta è memorizzato una sola volta in una HashMap<CompactString, DomainMasks { allow_mask: u64, block_mask: u64 }>. Quando la lista A e la lista C contengono entrambe ads.com, la voce è ads.com → block_mask = 0b101. Sottoscrivi due liste che si sovrappongono al 90% e il filtro fuso usa circa il 110% della memoria di una lista — non il 200%. Il bitmask è largo 64 bit, quindi il motore supporta fino a 64 sorgenti distinte di lista per profilo. Fonte: src/lists/parser.rs:106-281, DOCUMENTATION.md:437-449.

Allow di lista vs allow admin

Una lista con kind = "allow" contribuisce al percorso allow al Tier 1 — dopo che le admin rule si sono assestate. Quindi:

  • Una admin $important deny vince comunque su una corrispondenza di allow-list (priorità 2 batte Tier 1).
  • Un hit nell’HashSet deny_domains a livello di profilo (admin deny normale, priorità 0) vince comunque sulla corrispondenza di allow-list per design — le deny rule curate dall’operatore sono sovrane sui contributi di allow esterni.
  • block_all = true non è forato da una lista in direzione allow — solo le admin allow possono passare attraverso block_all.

Fonte: src/filter/engine.rs:280-443, e l’invariante W1.2 fissato dal test tests::w1_2_admin_important_deny_overrides_allow_list.

Note di sicurezza

Le liste esterne sono confinate

Il parser AdGuard rimuove e conta ogni token di sintassi che Warden riserva alle admin rule. Da src/lists/parser.rs:228-269, quando una lista remota è parsata in format = "adguard":

  • Regole @@… di allow → scartate, contate in parsed_skipped.
  • Modificatore $important (ovunque nella lista dei modificatori) → scartato, contato.
  • Regole /regex/ → scartate, contate.
  • Regole con wildcard * → scartate, contate.

Solo le righe ||domain^ e ||domain^$<modificatori-senza-important> estraggono un dominio. Una lista remota non può iniettare @@, $important, regex o wildcard anche se il suo contenuto pretende di essere in formato AdGuard.

Il contatore parsed_skipped è la leva di audit dell’operatore: emerge in warden blocklist show <id> e nel drill-down della TUI (fino a 32 righe campione). Una sorgente di lista che improvvisamente inizia a emettere righe scartate è un canarino di supply-chain — investiga prima del prossimo refresh.

I formati domains e hosts non hanno superficie di sintassi da confinare; le righe sono validate solo contro is_valid_domain e scartate se malformate. Fonte: src/lists/parser.rs:330-348.

TLS e SSRF

Ogni fetch passa per reqwest con la verifica TLS attiva di default. In più la guardia SSRF a runtime in validate_list_url (src/lists/http_client.rs:62-105) rifiuta, a ogni hop di redirect:

  • Qualsiasi schema non-HTTPS.
  • Host loopback / RFC1918 / link-local / CGNAT / multicast / ULA / IPv6 link-local.
  • Più di 3 hop di redirect.

A livello di schema il campo accetta http(s)://, ma a runtime si stringe a solo HTTPS. La URL sintetica https://imported.local/<id>.txt usata da warden blocklist import-local evita questo percorso perché il file viene letto da disco, non scaricato.

I refresh falliti tengono il contenuto stantio

Un download fallito — errore DNS, HTTP 404, body troppo grande, loop di redirect — non azzera la lista. Il body cachato precedente continua a servire e last_outcome viene registrato come Failed { reason } nel registry, esposto via IPC e warden blocklist show. L’operatore vede righe rosse nella tab Lists della TUI; le query in volo non vedono cambiamenti di comportamento.

Se non esiste cache (il primo refresh di una riga nuova è fallito), la sorgente non contribuisce per questo caricamento. Viene emesso un tracing::error!. Fonte: src/lists/manager.rs:464-501, 478-501.

Audit log

Le mutazioni di blocklist e categorie sono registrate come righe tracing::info!(target = "audit", action = "..."):

  • blocklists.remove
  • blocklist.set_category / blocklist.set_kind / blocklist.set_trust
  • blocklist.import_local
  • profile.blocklists.add / profile.blocklists.remove / profile.blocklists.cascade_remove / profile.blocklists.cascade_skip
  • category.add / category.remove / category.rename

L’attività di refresh è loggata ma non come record di audit — passa per tracing::info! / warn! / error! nel sottosistema delle liste. Tratta l’audit log come la traccia delle mutazioni operatore; tratta i log lists in journald come la traccia dell’attività di rete.

warden audit tail [-n N] stampa le righe di audit recenti come righe tab-allineate: timestamp, tag dell’evento, uid, ok / rifiutato, dettaglio.

Risoluzione problemi

Un reload fallisce con profile "<id>" references blocklist "<id>" which is not defined. Il profilo nomina un id di lista che nessuna riga [[blocklists]] fornisce. O un typo, o la riga è stata rimossa a mano. Il validator rifiuta il reload e il daemon resta sulla configurazione precedente. Esegui warden config lint per la lista di ogni riferimento incrociato pendente, oppure grep:

grep -RnE 'blocklists\s*=' /etc/purge-warden

Un reload fallisce con Blocklist '<id>' has kind=allow but trust='remote-unsigned'. Le liste in direzione allow devono avere trust locale. O passi trust a local su una riga che è davvero un file locale, oppure — più di frequente — la registri di nuovo via warden blocklist import-local, che imposta entrambi i campi atomicamente.

Un reload fallisce con trust=signed is not supported in this version. La variante signed è riservata per un flusso futuro con integrità attestata. Per ora, usa local per le allowlist fidate e remote-unsigned per tutto ciò che si scarica via HTTPS.

warden blocklist add avvisa di un auth_token_ref mancante. La CLI verifica secrets.toml al momento della scrittura ed emette un warning su stderr se la chiave non c’è. Il warning non è un errore — la riga atterra comunque su disco e la lista farà fetch in anonimo finché non aggiungi il segreto. Aggiungilo con il tuo editor (secrets.toml deve avere mode 0600) ed esegui warden update per fare refresh.

warden blocklist remove <id> viene rifiutato. Qualche profilo referenzia ancora l’id. L’errore li nomina. O riassegni prima, oppure passi --cascade per scollegare ogni profilo in un’unica transazione.

Una lista mostra parsed_skipped > 0 in warden blocklist show. È per design sulle liste remote in formato AdGuard — Warden rimuove @@, $important, /regex/ e wildcard. I primi 8 campioni sono visibili nel drill-down della TUI, e fino a 32 sono tenuti nel registry. Investiga se il numero cresce inaspettatamente: una lista che ieri non spediva sintassi fancy e oggi sì merita un’occhiata.

Un refresh di lista fallisce con HTTP 404 o TooLarge. Il contenuto stantio continua a servire e la riga diventa rossa nella TUI. Se la URL è cambiata, correggila con warden blocklist set <id> url <nuova-url>. Se la lista è cresciuta oltre il cap di body, alza [lists].max_body_bytes (globale, default 200 MB) — non il max_entries per riga, che governa il parsing e non il download.

La stessa lista è dichiarata due volte. Il validator rifiuta gli id duplicati al caricamento con DuplicateId. Scegline uno, rimuovi l’altro a mano.

La lista cresce senza limite. Il parser tronca a max_entries (default 5_000_000) con un WARN. Il bitmask del motore supporta fino a 64 sorgenti distinte di lista per profilo — oltre, le sottoscrizioni aggiuntive non sono rappresentabili. Se ti avvicini a quel limite, raggruppa le sorgenti in categorie così ogni profilo nomina una manciata di categorie invece di decine di id di lista.

warden blocklist import-local scrive una riga TOML con url = "https://imported.local/<id>.txt". Quirk documentato: il validator richiede http(s)://, quindi l’import sintetizza una URL placeholder. Il fetch reale legge il file copiato in <config-parent>/lists/<id>.txt. Fonte: src/cli/commands/blocklists.rs:855-866.

Riuso di un id ritirato da poco. Warden mette in quarantena gli id ritirati per 90 giorni per evitare che riferimenti stantii si rilegheranno silenziosamente. L’errore nomina il timestamp di ritiro originale. Aspetta, oppure scegli un id nuovo.

Per altro, vedi risoluzione problemi.

Vedi anche

  • Profili — come un profilo nomina le liste e le categorie da far valere.
  • Regole admin — l’unico posto dove vivono @@, $important, regex e wildcard.
  • Importazione di liste — guida operativa per portare molte liste alla volta.
  • Pianificazioni — cambi di profilo basati sull’orario che modificano quali liste si applicano e quando.
  • Globali del server — il blocco [lists] (cache directory, cap del body, intervallo di refresh di default).
  • Riferimento TOML — ogni campo, ogni vincolo.
  • Riferimento CLI — la superficie completa di warden blocklist … e warden category ….