MikroTik Dojo · prova di esistenza (OpenTimestamps) Versione: 2 Registrato il: 2026-11-13T12:38:37+00:00 Verifica: ots verify mikrotikdojo-2661-v2.txt.ots (o su https://opentimestamps.org) Indirizzo: https://mikrotikdojo.com/dojo/adguard-home-container-mikrotik/ ID: 2661 (post) Titolo: AdGuard Home dentro il MikroTik: un DNS che blocca pubblicità, in un container Pubblicato: 2026-11-12T06:30:00Z Immagini (sha256 del file): a1f8c4ee9258e28fceeb7536173a0b651180cb323bececf83157a160638ab919 https://mikrotikdojo.com/media/2026/10/2661.jpg --- Contenuto (HTML originale, in italiano) ---
Nel primo articolo sui container abbiamo guardato dentro un container per capire cosa condivide con il router. Ora lo usiamo per qualcosa di utile: far girare AdGuard Home, un server DNS che blocca pubblicità e tracker per tutta la rete, dentro il router stesso. Niente Raspberry Pi acceso in un angolo: il filtro DNS vive nel router, in un container isolato. Lo montiamo in laboratorio, lo configuriamo, lo mettiamo alla prova (risolve, blocca) e lo chiudiamo come si deve.
AdGuard Home è un server DNS che fa da filtro per tutta la rete: ogni dispositivo gli chiede "a che indirizzo sta questo nome?", e lui risponde — tranne quando il nome è di un circuito pubblicitario o di un tracker, nel qual caso lo blocca. Un solo punto di controllo per telefoni, TV, computer, senza installare niente sui singoli dispositivi. In più ha una web UI con statistiche e log delle richieste.
Perché dentro il router? Perché il router è sempre acceso ed è già il cuore della rete: è il posto naturale per un DNS. E con i container non serve un apparato in più. Ricordando il primo articolo: un container non è una macchina virtuale, condivide il kernel del router, ma porta con sé il suo userland (qui l'immagine di AdGuard Home). AdGuard gira nel suo spazio, con le sue librerie, e parla con la rete tramite una veth.
Prerequisito concettuale: Device-mode su RouterOS — i container vanno prima sbloccati con device-mode container=yes e una conferma fisica.
Come nel primo articolo, diamo al container un'interfaccia veth su un bridge dedicato, con il NAT verso l'esterno (ad AdGuard serve Internet per interrogare i DNS upstream):
/interface veth add name=veth-adg address=172.17.0.4/24 gateway=172.17.0.1
/interface bridge add name=ctbr
/ip address add address=172.17.0.1/24 interface=ctbr
/interface bridge port add bridge=ctbr interface=veth-adg
/ip firewall nat add chain=srcnat src-address=172.17.0.0/24 action=masquerade
Il container avrà l'indirizzo 172.17.0.4; il router è 172.17.0.1 sullo stesso segmento.
Un container, se lo cancelli e lo ricrei, riparte da zero. Ma AdGuard deve ricordare la sua configurazione e le statistiche. Per questo gli diamo due cartelle persistenti del router, montate dentro il container nei punti dove AdGuard si aspetta i suoi file:
/container mounts add list=adg src=adg/conf dst=/opt/adguardhome/conf
/container mounts add list=adg src=adg/work dst=/opt/adguardhome/work
Due cose da notare. src è una cartella sul router (percorso relativo, il router la crea da solo); dst è dove compare dentro il container. E le abbiamo messe nella stessa lista (list=adg), così il container le richiama tutte con un nome solo.
Qui torna il tema del primo articolo: ogni mount è un accesso che concedi. Ma c'è una differenza importante. mikroscope montava /proc e /sys del router per spiarne lo stato; qui montiamo solo cartelle dati di AdGuard (/opt/adguardhome/...): non diamo al container nessuna finestra sul router. È il modo sano di usare i mount — solo ciò che serve al servizio, niente del sistema.
Diciamo da dove scaricare le immagini e creiamo il container, agganciando la lista di mount. Nota: niente privileged. AdGuard è un normale servizio di rete, non ha bisogno dei poteri di root sul router — e quindi non glieli diamo.
/container config set registry-url=https://registry-1.docker.io tmpdir=tmp
/container add remote-image=adguard/adguardhome:latest interface=veth-adg \
root-dir=ct/adguard mountlists=adg logging=yes name=adguard
/container start adguard
Dopo lo scaricamento, il container gira. In laboratorio l'ingombro era contenuto:
/container print
# NAME ROOT-DIR INTERFACE MEMORY-CURRENT CONTAINER-SIZE
0 R adguard /ct/adguard veth-adg 56.1MiB 43.5MiB
Circa 56 MiB di RAM e 43 MiB su disco per un DNS che serve tutta la casa. Controlla sempre RAM e spazio liberi del router prima: su un apparato piccolo è un conto da fare.
Al primo avvio AdGuard apre una procedura guidata sulla porta 3000. Dal browser, da un PC della LAN, vai su http://172.17.0.4:3000 (se il container non è raggiungibile direttamente dalla tua LAN, vedi il Passo 6 per esporlo). La procedura chiede:
80);53, quella standard);⚠️ Attenzione: scegli una password robusta. Questa web UI comanda il DNS di tutta la rete; con le credenziali in mano si decide cosa risolvono tutti.
Finita la procedura, AdGuard si riavvia sulle porte scelte: la 3000 si chiude, la web UI passa sulla 80 (ora protetta: senza login risponde 401) e il DNS sulla 53 è attivo. Da qui in poi lo gestisci da http://172.17.0.4/.
Perché AdGuard filtri davvero, i dispositivi devono usarlo come DNS. Due modi:
/ip dns set servers=172.17.0.4 per far passare da AdGuard anche le richieste del router.Proviamo in laboratorio. Con il DNS puntato al container, un nome normale si risolve:
/ip dns set servers=172.17.0.4
:put [:resolve "example.com"]
104.20.23.154
Ora aggiungiamo una regola di blocco (dalla web UI, oppure via API) per un dominio pubblicitario e riproviamo:
:put [:resolve "doubleclick.net"]
0.0.0.0
AdGuard ha risposto 0.0.0.0: il nome è bloccato, il browser non raggiungerà quel server. Nella web UI, alla voce statistiche, le due richieste compaiono subito — una passata, una bloccata:
num_dns_queries: 2
num_blocked_filtering: 1
E le liste di blocco, chi le mette? Non si compilano a mano. AdGuard Home arriva con un catalogo di liste pronte: la AdGuard DNS filter è già attiva appena finito il setup (in laboratorio, oltre 185.000 regole), e altre liste note (AdAway, OISD, le hagezi…) sono lì da accendere con un clic nella sezione Filtri → Liste di blocco DNS. Sono liste online: AdGuard le scarica da un URL e le aggiorna da sola a intervalli regolari (di default una volta al giorno), così restano al passo senza che tu faccia niente. Puoi aggiungerne altre incollando il loro URL, scrivere regole tue a mano, e nel log vedere chi ha chiesto cosa. Ma il meccanismo di base è quello che hai appena visto.
Tutto quello che abbiamo fatto a mano — immagine, veth, bridge, NAT, mount, porte — nelle versioni recenti di RouterOS si può chiedere in un comando solo. Si chiama Apps (/app): un livello che sta sopra i container e li orchestra a partire da un catalogo. Un'«app» è una ricetta in stile Docker-Compose (un file YAML) che descrive immagine, porte e volumi; RouterOS la legge e costruisce il container, la rete e persino un indirizzo HTTPS per la web UI, da solo.
Il senso didattico è proprio questo: l'app fa sotto il cofano esattamente i Passi 2-4 che hai appena visto a mano. Averli fatti a mano una volta ti fa capire cosa succede davvero quando premi «un clic».
Servono tre cose, una volta sola:
container e partitions sbloccati (più la conferma fisica) — vedi la KB sul device-mode.ext4: a differenza del container manuale, /app vuole uno storage vero (la documentazione parla di ≥100 MB/s), non la flash interna./app quale disco, quale bridge della LAN e quale IP del router usare.# sblocca container + partizioni (richiede la conferma fisica sul dispositivo)
/system/device-mode/update container=yes partitions=yes
# dopo aver formattato il disco esterno in ext4 (menu Disks), indica disco/bridge/ip
/app settings set disk=<disco-esterno> lan-bridge=<bridge-lan> router-ip=<ip-del-router>
# installa AdGuard dal catalogo, in un comando
/app enable <nome-app>
Da qui RouterOS scarica l'immagine (nella ricetta del Dojo la teniamo pinnata a una versione precisa, non latest), crea e avvia il container, e genera un indirizzo per la web UI del tipo https://<nome-app>.<seriale>.routingthecloud.com.
Nota di sicurezza (verificata). Quel nome cloud è pubblico, ma risolve all'IP privato del router nella LAN: da Internet punta a un indirizzo non instradabile. In pratica la web UI di AdGuard resta raggiungibile solo dalla tua rete e non viene esposta su Internet dal cloud MikroTik. Vale comunque la regola del metodo manuale: non inoltrare quella porta verso la WAN.
Dove funziona, e dove no — detto onestamente. Il deploy un-clic si completa su hardware reale (apparati arm64/x86 con un disco esterno veloce): immagine scaricata, container creato e avviato, UI che risponde. Sul CHR / in macchina virtuale con disco su file, invece, /app enable si ferma su «wait for reverse proxy» e non crea mai il container: a /app serve storage veloce vero, che un disco virtuale su file non garantisce. Su un CHR con un disco reale dedicato e veloce è plausibile che vada, ma non l'abbiamo ancora verificato. Il menu /app è una funzione recente e ancora in maturazione: confidiamo che MikroTik la renda solida su più configurazioni. E se nel frattempo il tuo deploy si pianta su «wait for reverse proxy», il metodo manuale qui sopra funziona ovunque, oggi, su ogni versione stabile e anche senza disco esterno.
privileged. AdGuard non ne ha bisogno: lasciandolo senza, un'eventuale falla nel servizio resta chiusa nel container e non tocca il router.memory-max, così un problema del container non si mangia la RAM del router.Sì: AdGuard gira in un container, e i container vanno sbloccati una volta con device-mode container=yes più la conferma fisica. Una volta fatto, vale per tutti i container.
Se vuoi che i dispositivi lo interroghino direttamente, il loro DNS deve poterlo raggiungere: o il container sta su un bridge della LAN, o il router inoltra la porta 53 verso il container solo dall'interno. In entrambi i casi la porta 53 non deve mai affacciarsi sulla WAN.
No, se hai fatto i mount del Passo 3: configurazione e statistiche stanno nelle cartelle del router (src), non dentro il container. Ricreando il container con gli stessi mount, AdGuard ritrova tutto.
In laboratorio circa 56 MiB di RAM e 43 MiB su disco, con CPU quasi a zero da fermo. Dipende da quante liste di blocco carichi e da quante richieste serve: più liste e più client, più RAM. Su un apparato piccolo, verifica prima.
No, ed è voluto. Qui non c'è privileged e non montiamo /proc o /sys: AdGuard vede solo il suo filesystem e le sue due cartelle dati. È un servizio ospite, non un osservatore del router.
Provato in laboratorio su CHR RouterOS 7.25 (stable): pacchetto container e device-mode container=yes; container adguard/adguardhome su una veth con bridge dedicato e NAT, con due mount persistenti (list=adg, /opt/adguardhome/conf e /opt/adguardhome/work) e senza privileged; procedura guidata iniziale sulla porta 3000, poi web UI sulla 80 (protetta, risposta 401 senza credenziali) e DNS sulla 53; risoluzione di un nome attraverso il container (example.com) e blocco di un dominio pubblicitario (doubleclick.net → 0.0.0.0) con conferma nelle statistiche (2 richieste, 1 bloccata); ingombro misurato 56,1 MiB di RAM e 43,5 MiB su disco.