AdGuard Home su Raspberry Pi
AdGuard Home su Raspberry Pi (3/4/5, Docker, boot da SSD USB)
Guida per installare AdGuard Home su Raspberry Pi 3, 4 o 5, con boot da SSD USB al posto della SD card, integrazione con router e blocklist per pubblicità/tracker/scam. Le sezioni 4 in poi (Docker, container, DNS, MikroTik, blocklist, verifica) sono identiche su tutti e tre i modelli; la sezione 2 distingue le procedure specifiche per modello.
Si è scelto di fare l’installazione su Docker in quanto isola AdGuard Home dal sistema operativo host: aggiornamenti, rollback e rimozione non toccano mai il resto del Raspberry, e se qualcosa va storto nel container lo si ricrea da zero in pochi secondi senza reinstallare l’OS. Con un’installazione nativa (binario o pacchetto), dipendenze, versioni di Go e configurazioni finiscono mescolate col sistema, e un aggiornamento andato male è più complicato da disfare.
In più, l’immagine ufficiale adguard/adguardhome è mantenuta direttamente dal progetto ed è multi-arch: stesso comando, stesso file compose, funziona identico su Pi 3, 4 o 5 senza gestire manualmente pacchetti specifici per architettura ARM.
Contro: un filo di overhead di risorse rispetto al binario nudo (trascurabile per questo carico) e la necessità di avere Docker installato — costo accettabile per la praticità di gestione che offre in cambio, specie su un dispositivo dove poi vorrai probabilmente affiancare altri container in futuro.
1. Scelta dello storage
Non usare la SD card come disco principale: il pattern di scrittura di Docker (log, journaling, database SQLite di AdGuard) è random e continuo, ed è esattamente il tipo di carico che degrada rapidamente le SD card, che hanno controller minimali senza wear leveling efficace.
Alternative, in ordine di preferenza:
- SSD USB (anche economico, 120-128GB bastano) — controller SSD reale, wear leveling maturo. Scelta consigliata.
- Chiavetta USB — sconsigliata anche di fascia alta: internamente è NAND senza controller dedicato, si comporta come una SD più lenta a degradarsi.
- Se una chiavetta dichiara esplicitamente “SSD portatile” (es. Netac US5) e ha un vero controller SSD dietro, è accettabile come compromesso economico (~25-30€ per 128GB) rispetto a un SSD di marca (100€+). Verificare sempre le specifiche del controller prima di comprare marchi sconosciuti.
Il Raspberry Pi 3 è comunque limitato a USB 2.0 (~35MB/s reali), quindi non si sfrutta la velocità massima dell’SSD — ma per questo caso d’uso conta la longevità del componente, non la velocità.
2. Boot da USB
Il meccanismo per abilitare il boot USB cambia tra Pi 3 e Pi 4/5. Questa guida copre entrambi i casi.
Pi 3
Sul Pi 3B+ il boot USB è supportato nativamente. Sul Pi 3B “liscio” va abilitato aggiornando il bootloader.
Il Pi 3 non ha EEPROM bootloader separata (introdotta dal Pi 4 in poi): rpi-eeprom-update su un Pi 3 risponde sempre “Device does not have a Raspberry Pi bootloader EEPROM”. Non è un errore, è normale. Il bootloader di primo stadio sta nei file della partizione boot (bootcode.bin, start.elf) e viene aggiornato tramite i normali apt upgrade. Se non c’è una SD inserita e il bootcode è aggiornato, il Pi prova USB automaticamente — non c’è un boot order da configurare esplicitamente.
Se il Pi parte direttamente da USB senza interventi, il punto è chiuso: non serve fare altro.
Pi 4 / Pi 5
Hanno EEPROM bootloader dedicata, quindi il boot order va configurato esplicitamente:
sudo rpi-eeprom-update -a
sudo reboot
Poi verifica/imposta l’ordine di boot con sudo raspi-config → Advanced Options → Boot Order, scegliendo l’opzione che mette USB prima della SD (o USB/NVMe se applicabile, vedi nota sotto).
Nota prestazioni: Pi 4/5 hanno USB 3.0, quindi con un SSD USB 3.0 si ottengono velocità reali molto superiori al collo di bottiglia USB 2.0 del Pi 3 — per sfruttarlo serve un adattatore/cavo effettivamente USB 3.0, non solo con supporto UASP.
Nota: NVMe sul Pi 5 (non testato in questa guida)
Il Pi 5 è l’unico modello con interfaccia PCIe nativa (connettore FFC accanto al connettore display), che permette di collegare un HAT NVMe (es. Raspberry Pi M.2 HAT+ ufficiale, Pimoroni NVMe Base, Geekworm) per un vero SSD M.2 su bus PCIe, non tramite bridge USB. Prestazioni potenzialmente superiori anche al miglior SSD USB.
Questa configurazione non è stata verificata in questa guida (richiede l’HAT, non disponibile in fase di stesura). Se la si vuole seguire, tenere presente che serve abilitare il PCIe da raspi-config prima che il boot da NVMe funzioni, ed è una procedura diversa da quella del boot USB descritta sopra. Pi 3 e Pi 4 non hanno interfaccia PCIe fisica: eventuali “HAT NVMe” per quei modelli sono in realtà adattatori USB con le stesse prestazioni e limiti di un SSD USB.
3. Flash dell’immagine
Usa Raspberry Pi Imager (raspberrypi.com/software), che scrive l’immagine direttamente sull’SSD/chiavetta collegata al PC.
- Sistema operativo: Raspberry Pi OS Lite, 64-bit (non “Legacy”, non full desktop). Il Pi 3 usa un SoC Cortex-A53 con supporto nativo armv8-a a 64-bit; la versione 64-bit (Debian Bookworm) è quella attivamente supportata.
- Storage: seleziona l’SSD/chiavetta, non la SD.
- Nelle opzioni avanzate (icona ingranaggio): abilita SSH, configura hostname e utente. Non serve configurare il Wi-Fi se il Pi resta collegato via ethernet — anzi è preferibile lasciarlo disattivato per stabilità su un servizio DNS che deve girare 24/7.
- Ignora l’opzione “Raspberry Pi Connect”: è un servizio di accesso remoto che passa dai server Raspberry Pi come relay, introduce una dipendenza esterna non necessaria su una macchina critica come il resolver DNS di casa. SSH via chiave è sufficiente.
4. Installazione Docker
Stesso metodo ufficiale di qualsiasi sistema Debian-based, lo script rileva automaticamente l’architettura ARM64:
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
sudo usermod -aG docker $USER
Disconnetti e riconnetti la sessione SSH perché il gruppo abbia effetto. Verifica con docker --version e docker compose version (il plugin compose è già incluso nello script).
5. Container AdGuard Home
Immagine ufficiale: adguard/adguardhome, multi-arch, include ARM64.
mkdir -p ~/adguard/{work,conf}
cd ~/adguard
nano docker-compose.yml
Copiare nel file docker-compose.yml il testo seguente
services:
adguardhome:
image: adguard/adguardhome
container_name: adguardhome
restart: unless-stopped
volumes:
- ./work:/opt/adguardhome/work
- ./conf:/opt/adguardhome/conf
network_mode: host
Salvare con CTRL + O e uscire con CTRL + X
Note:
network_mode: hostè la scelta corretta per un servizio DNS: evita problemi di NAT tra container e rete, la porta 53 deve essere raggiungibile direttamente dai client LAN.- Con
network_mode: hostattivo, un eventuale bloccoports:nel file viene ignorato da Docker — non aggiungerlo, è fuorviante in rilettura futura. - Se in futuro vuoi cambiare la porta dell’interfaccia web (default 80/3000), si fa dal pannello AdGuard (Impostazioni generali → porta interfaccia), non dal docker-compose.yml, proprio perché il mapping porte non è attivo in modalità host.
Avvio:
docker compose up -d
Setup guidato su http://<IP-del-Pi>:3000.
Aggiornare l’immagine
cd ~/adguard
docker compose pull
docker compose up -d
docker image prune -f
I dati in ./work e ./conf sono bind-mount esterni, non vengono toccati dalla ricreazione del container.
6. Configurazione DNS upstream
In Impostazioni → DNS Upstreams va configurato il server verso cui AdGuard inoltra le richieste dopo il filtro (es. 1.1.1.1, 9.9.9.9, o via DoH/DoT se serve cifratura). Senza upstream configurato, AdGuard blocca solo quello che è in lista ma non risolve il resto.
Se usi upstream DoH/DoT, configura anche il Bootstrap DNS (stessa sezione): serve ad AdGuard per risolvere l’hostname del provider DNS stesso prima di stabilire la connessione cifrata. Senza bootstrap valido, l’upstream cifrato non parte.
Controlla anche il rate limit per client (Impostazioni → DNS generali): se il router fa NAT prima del Pi, più dispositivi dietro lo stesso IP interno possono sforare il limite di default, causando risoluzioni intermittenti.
7. Configurazione router
Imposta l’IP del Pi come unico DNS server nel DHCP, ogni router ha un pannello di impostazione diverso, ma sostanzialmente i dati sono sempre gli stessi, una volta che si è nelle impostazioni del router cercare le impostazioni DHCP e cercare la voce DNS
Punti critici:
- Non aggiungere un secondo DNS esterno nello stesso campo (es. 8.8.8.8): alcuni client alternano tra i DNS disponibili, bypassando AdGuard in modo imprevedibile.
8. Blocklist consigliate
Per uso domestico standard (ads, tracker, anti-scam, zero restrizioni di contenuto):
| Lista | URL |
|---|---|
| AdGuard DNS filter | preselezionata di default in AdGuard Home |
| HaGeZi Threat Intelligence Feeds | https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/tif.txt |
| HaGeZi Fake (scam, fake shop) | https://raw.githubusercontent.com/hagezi/dns-blocklists/main/adblock/fake.txt |
Non serve aggiungere anche OISD Big insieme ad AdGuard DNS filter: sono ridondanti tra loro, scegline una come lista base principale.
Aggiunta: Filtri → Filtri DNS → Aggiungi filtro blocklist. Verifica dopo l’aggiunta che il numero di regole caricate sia alto (centinaia di migliaia) e che siano finite nella sezione Liste nere, non in allowlist.
9. Verifica del blocco — come testare correttamente
Non fidarti del comportamento del browser (redirect, 404, pagina vuota): non distingue un dominio bloccato da uno raggiungibile che semplicemente non ha contenuto su quel path. L’unico test affidabile è una query DNS diretta al Pi, bypassando completamente il browser.
Da PC: nslookup <dominio> <IP-del-Pi3> Da Android: installa Termux (da F-Droid, non dal Play Store), poi pkg install dnsutils e usa nslookup allo stesso modo.
Domini corretti per il test (ad-serving/tracking reale, coperti dalle liste sopra):
doubleclick.net
googlesyndication.com
googleadservices.com
scorecardresearch.com
adnxs.com
criteo.com
outbrain.com
taboola.com
Se un test fallisce (il dominio risolve quando non dovrebbe), verifica prima di tutto che il DNS sicuro (DoH) del browser sia disattivato — su Chrome/Brave: Impostazioni → Privacy e sicurezza → DNS sicuro. Se attivo, il browser bypassa completamente il DNS di sistema e va diretto via HTTPS a un proprio provider, indipendentemente da cosa hai configurato su AdGuard e sul router.
Su Brave, controlla anche che Brave Shields non stia mascherando il test bloccando lato browser per conto suo.