SafeSearch
Un bool sul profilo, otto rewrite Strict iniettati a tempo di resolve. Il tablet dei bambini ora vede Google attraverso forcesafesearch.google.com, non perché il browser l’ha chiesto gentilmente.
Cos’è
SafeSearch è un interruttore per-profilo che forza la modalità Strict di SafeSearch su Google, YouTube, Bing e DuckDuckGo per ogni dispositivo assegnato a quel profilo — al livello DNS, senza alcuna cooperazione del client. Impostare safe_search = true su un profilo fa sì che Warden inietti otto regole di rewrite predefinite nella tabella rewrite risolta di quel profilo, all’avvio, su SIGHUP, e ad ogni tick di ricalcolo delle pianificazioni (60 secondi). Ogni query per www.google.com da un dispositivo sul profilo viene risolta come se il client avesse chiesto forcesafesearch.google.com.
Il meccanismo è lo stesso motore ProfileRewriteRules che alimenta i [[profiles.<id>.rewrite_rules]] scritti dall’operatore. SafeSearch si limita a precaricare otto voci curate che l’operatore non deve mantenere.
Quando ti serve
- Gestisci un profilo
kidse vuoi che i Chromebook e i tablet di casa smettano di restituire risultati espliciti su Google Immagini e Bing, senza installare estensioni lato client. - Hai una classe o piccola biblioteca che fa girare Warden su un Raspberry Pi e vuoi SafeSearch attivo anche sui dispositivi ospiti che non rispettano una preferenza browser impostata dall’operatore.
- Vuoi la modalità ristretta di YouTube attiva per i bambini, sapendo che la protezione è solo Strict (
restrict.youtube.com) — oggi non esiste un livello Moderate.
Non ti serve SafeSearch quando:
- Vuoi bloccare del tutto i motori di ricerca. Aggiungi
google.com,bing.com,youtube.comneideny_rulesdel profilo o in una blocklist — le blocklist sono valutate prima dei rewrite di SafeSearch, quindi il deny vince. - Vuoi un override per-dispositivo di un profilo che ha già SafeSearch attivo. SafeSearch segue il profilo; se un dispositivo è sul profilo kids, SafeSearch è attivo per quel dispositivo. Per esentare un dispositivo, dagli un profilo diverso.
Come funziona
SafeSearch non è uno stage di filtro separato. Si innesta nel motore di rewrite esistente attraverso due punti:
- A tempo di resolve del profilo (avvio,
warden reload, ogni 60 s quando le pianificazioni ricalcolano),ResolvedProfile::build_v1guardaProfile.safe_search. Quando ètrue, invocasafesearch::populate()sulla tabella rewrite del profilo, che aggiunge gli otto preset a meno che una voce scritta dall’operatore non rivendichi già lo stesso hostfrom. - Sull’hot path, ogni query attraversa: filter (allow / deny / blocklist) → rewrite → cache lookup → upstream. SafeSearch sta nello step di rewrite, dopo il filter, prima che venga calcolata la chiave di cache. Quindi:
- Una voce di blocklist per
www.youtube.comvince su SafeSearch — la query è bloccata, mai riscritta. - Un hit di cache per
forcesafesearch.google.comè riutilizzato fra tutti i client sullo stesso profilo. - La risposta DNS rimandata al client mantiene il qname originale; solo la lookup verso l’upstream è cambiata. Il client non vede mai il rewrite.
- Una voce di blocklist per
www.google.com nel browser e nelle risposte di dig. Warden risolve forcesafesearch.google.com verso l’upstream e stampa la risposta sotto il nome originale. È voluto — niente TLS rotto, niente mismatch di certificati, niente effetti collaterali visibili al client.Sorgenti: src/profiles/safesearch.rs:1-234, src/profiles/profile.rs:486-489, src/dns/handler.rs:894-903, src/dns/rewrite.rs:1-90.
Provider coperti
Ogni preset è una corrispondenza esatta (match_subdomains = false). Gli host gestiti dal vendor sulla destra eseguono il blocco SafeSearch lato loro.
| qname originale | Riscritto in | Livello |
|---|---|---|
google.com | forcesafesearch.google.com | Strict |
www.google.com | forcesafesearch.google.com | Strict |
www.youtube.com | restrict.youtube.com | Strict |
m.youtube.com | restrict.youtube.com | Strict |
www.youtube-nocookie.com | restrict.youtube.com | Strict |
www.bing.com | strict.bing.com | Strict |
edgeservices.bing.com | strict.bing.com | Strict |
duckduckgo.com | safe.duckduckgo.com | Strict |
Cosa non è coperto:
- Apex nudo
youtube.comebing.com. Vengono riscritti solo gli hostwww.— piùm.youtube.com,www.youtube-nocookie.comeedgeservices.bing.com. Gli apex nudi sono lasciati intatti di proposito: Google e Microsoft documentano il lock SafeSearch solo per quei nomi specifici, e puntare un apex non documentato sull’host SafeSearch rischia di rompere il sito. L’apexgoogle.comdi Google è l’unica eccezione documentata e resta coperto. In pratica è raramente un buco — browser e app di ricerca risolvono l’hostwww.— ma un client che chiede l’apex nudo riceve una risposta normale. - Livello Moderate di YouTube (
restrictmoderate.youtube.com). Differito — Strict (restrict.youtube.com) è l’unica opzione YouTube oggi. - Superficie API di YouTube (
youtubei.googleapis.com,youtube.googleapis.com). Un bambino che guarda la app ufficiale YouTube Kids usa il filtro dei contenuti interno alla app, non un hostname web, quindi l’enforcement a livello DNS non lo raggiunge. - Domini Google regionali (
google.co.uk,google.it, ecc.). Se un client interroga esplicitamentegoogle.co.uk, la lista non corrisponde. Il subdomain-walk sui preset è stato volutamente saltato per tenere la tabella prevedibile; aggiungi rewrite per-profilo espliciti se ti serve copertura per Paese.
Sorgente: src/profiles/safesearch.rs:80-113.
Schema
SafeSearch è un singolo campo booleano sul profilo:
| Campo | Tipo | Obbligatorio | Default | Scopo |
|---|---|---|---|---|
safe_search | bool | no | false | Quando true, gli otto rewrite preimpostati vengono iniettati a tempo di resolve. |
Non esiste una tabella [safesearch]. Non ci sono interruttori per-provider. Il senso della feature è che è un singolo interruttore.
Sorgente: src/config/schema/profile.rs:123-124.
Esempi
Il profilo kids più piccolo possibile con SafeSearch attivo:
[profiles.kids]
display_name = "Bambini"
safe_search = trueUn profilo kids completo che combina SafeSearch e blocklist di contenuti — i due si sommano:
[profiles.kids]
display_name = "Bambini"
safe_search = true
categories = ["adult-content"]
blocklists = ["security-malicious"]
block_response = "nxdomain"
blocked_ttl_secs = 300Sovrascrivi il preset per uno specifico host mantenendo gli altri sette — i rewrite scritti dall’operatore hanno precedenza:
[profiles.kids]
display_name = "Bambini"
safe_search = true
# Reindirizza www.google.com sulla intranet domestica invece che su forcesafesearch.
# Gli altri sette preset SafeSearch continuano ad applicarsi.
[[profiles.kids.rewrite_rules]]
from = "www.google.com"
to = "intranet.local"
match_subdomains = falseOrdine di precedenza
L’ordine conta quando SafeSearch convive con altre feature.
- Blocklist e deny admin vincono. SafeSearch si trova dopo lo stage del filtro. Se
www.youtube.comè in una deny-list attiva per il profilo, la query è bloccata. SafeSearch non arriva mai a riscriverla. - I rewrite scritti dall’operatore vincono sul preset. Quando la stessa coppia
(from, match_subdomains)è presente in entrambi,populate()salta il preset e tiene la voce operatore. È così che l’esempio precedente sostituisce solo una delle otto regole. - Le pianificazioni scambiano l’intero profilo. Un dispositivo che passa da
defaultakidsper uno schedule alle 21:00 prende SafeSearch insieme al resto del profilo; tornando indietro alle 07:00 lo lascia. Il cambio è limitato dal tick di 60 secondi delle pianificazioni. - L’overlay per-dispositivo non vede SafeSearch.
[[devices]].allow_rulesedeny_rulessono regole dello stage di filtro, non rewrite. La allow rule di un dispositivo non può esentare un singolo host search da SafeSearch — il rewrite avviene dopo il filter, e l’overlay del dispositivo partecipa solo allo step di filter.
Sorgenti: src/dns/handler.rs:894-903 (ordine dell’hot path), src/profiles/safesearch.rs:119-134 (logica di collisione).
CLI
Non esiste un sottocomando warden safesearch dedicato. L’attivazione è un edit TOML più un reload:
# 1. Edita il profilo
sudo $EDITOR /etc/purge-warden/profiles.d/kids.toml
# aggiungi o ribalta: safe_search = true
# 2. Reload
sudo warden reload
Per ispezionare:
# Flag del profilo (la fonte di verità — mostrato verbatim dalla config)
warden profile show kids | grep -i safe
# Verifica a runtime — dovrebbe rispondere con l'indirizzo di forcesafesearch.google.com
dig @127.0.0.1 -p 53 www.google.com
# Cosa restituisce il motore di rewrite per il profilo risolto.
# Nota: warden rewrite list mostra SOLO le regole scritte dall'operatore;
# gli otto preset SafeSearch sono iniettati a tempo di resolve e sono
# nascosti di proposito dalle liste per non sporcare il modello mentale.
warden rewrite list --profile kids
warden rewrite list e warden profile show omettono volutamente gli otto rewrite SafeSearch anche con safe_search = true. Il bool è il contratto; i preset sono un dettaglio implementativo. Se vuoi sapere cosa viene applicato, questa pagina è il riferimento — l’insieme delle regole è fisso e viaggia con il daemon.Sorgente: src/profiles/safesearch.rs:21-24.
TUI
Oggi non c’è un tab SafeSearch dedicato. Il flag non compare ancora nel modale di edit dei Dispositivi né nel drilldown dei Profili — modificalo dal TOML e fai warden reload.
È un gap noto; il campo è un bool primitivo e si infila nel form di edit del profilo senza problemi non appena anche il lato TUI si allinea.
API REST
Leggere il flag:
| Metodo | Path | Cosa |
|---|---|---|
GET | /api/config | Config completa fusa. Il booleano appare come profiles.<id>.safe_search nel payload JSON. |
Non esiste un endpoint dedicato POST /api/profile/<id>/safesearch e non c’è una superficie di scrittura per i campi arbitrari del profilo via REST — le mutazioni del profilo sono solo CLI o edit a mano.
Limiti
Vale la pena conoscerli prima di promettere ai genitori che SafeSearch è attivo:
- Enforcement solo via DNS. Un dispositivo che usa DNS-over-HTTPS (DoH) verso un resolver pubblico (es. browser-level
https://dns.google/dns-query) bypassa Warden completamente. Abbina SafeSearch a un blocco di DoH a livello di rete se la cosa è rilevante. Vedi le ricette di blocco DoH (in arrivo). - DNS-over-TLS (DoT) sulla porta 853 verso un resolver pubblico è la stessa storia — un client che interroga Quad9 direttamente non passa mai da Warden.
- Solo livello Strict. YouTube non ha un’opzione Moderate in Warden oggi. Alcune famiglie vogliono Restricted-Moderate; è un gap di config da segnalare, non un workaround.
- Niente domini Google regionali.
google.co.uk,google.it, ecc. passano senza rewrite. Aggiungi voci esplicite[[profiles.<id>.rewrite_rules]]se la tua famiglia li usa. - Le superfici SafeSearch delle app mobile sono fuori scopo. L’app Google Search di Android e l’app YouTube Kids di iOS incorporano il loro filtro dei contenuti; SafeSearch a livello DNS intercetta solo gli hostname web elencati sopra.
- L’IP restituito dall’upstream non è validato. Se un resolver ostile restituisce un IP non-SafeSearch per
forcesafesearch.google.com, Warden lo passa al client. Usa un upstream affidabile (Cloudflare, Quad9, il tuo ISP) e valuta di abilitare DNSSEC sul forwarder.
Risoluzione problemi
Un dispositivo sul profilo kids vede ancora risultati immagine per adulti.
- Verifica che il dispositivo sia effettivamente sul profilo:
warden device show <id>e controlla il campoprofile. - Verifica che il flag sia impostato:
grep safe_search /etc/purge-warden/profiles.d/*.toml. - Verifica che il daemon abbia preso la modifica:
journalctl -u purge-warden -n 50 | grep -i reload. - Verifica il rewrite:
dig @127.0.0.1 -p 53 www.google.comdeve rispondere con l’IP a cui risolverebbeforcesafesearch.google.com. - Se lo step 4 mostra l’IP reale di
www.google.com, il dispositivo sta interrogando l’upstream direttamente — verifica che il DHCP del router pubblicizzi Warden come server DNS e che il dispositivo non abbia un endpoint DoH proprio.
I rewrite SafeSearch e un rewrite scritto dall’operatore puntano allo stesso host.
Vince la voce operatore; il preset è saltato in silenzio. È voluto. Per confermare: edita il TOML rimuovendo il rewrite operatore, fai warden reload, poi dig di nuovo — la risposta deve tornare a quella SafeSearch.
Modalità ristretta di YouTube mostra la barra di avviso ma fa passare comunque alcuni contenuti.
È il comportamento di YouTube, non di Warden. restrict.youtube.com è l’hostname Strict di YouTube; la piattaforma decide cosa ricade dentro Strict. Il contratto di Warden è “instrada l’utente sul livello più severo di YouTube”, non “garantisce che il livello più severo blocchi tutto”.
warden reload ha accettato la modifica ma dig continua a restituire l’host non riscritto.
Il tick di 60 secondi delle pianificazioni è il limite superiore per i rebuild di profilo, ma warden reload dovrebbe ricostruire immediatamente. Verifica che il daemon stia davvero girando con la nuova config:
warden status | grep -i config
journalctl -u purge-warden -n 20 --no-pager
Se i timestamp non corrispondono al reload, il daemon potrebbe non aver acked il SIGHUP — come ultima risorsa fai systemctl restart purge-warden.
Per diagnostica più profonda, vedi risoluzione problemi.
Vedi anche
- Profili — l’entità che contiene il campo
safe_search. - Record DNS locali — l’altro modo per scambiare risposte dell’upstream, ma per-record invece che per-vendor.
- Liste di blocco — lo stage di deny che gira prima di SafeSearch sull’hot path.
- Ricetta — famiglia — esempio end-to-end di profilo kids.
- Schema TOML — ogni campo, ogni vincolo.