Perché il DNS cifrato scavalca il router?

Il DNS classico viaggia in chiaro sulla porta 53: il router lo vede, lo può girare a sé, filtrare, registrare. È quello che facciamo nell’howto sul DNS trasparente con il bridge NAT, e funziona bene con PC, telecamere e smart TV.

Il DNS cifrato no. Ci sono due modi per farlo, e passano tutti e due sotto il naso del router:

  • DNS over TLS (DoT): le richieste viaggiano cifrate su una porta dedicata, la 853. È quello che usa Android con l’opzione “DNS privato”;
  • DNS over HTTPS (DoH): le richieste viaggiano dentro una normale connessione HTTPS, sulla porta 443, la stessa di tutti i siti web. È quello dei browser: Firefox, Chrome, Edge.

Il DoT si blocca con una regola. Il DoH no: non puoi chiudere la porta 443 senza chiudere internet. Si combatte riconoscendo a chi va la connessione. In laboratorio ho provato quattro tecniche, una dopo l’altra, da un PC Linux dietro il MikroTik: alla fine DoT e DoH verso Cloudflare, Google e 1.1.1.1 erano bloccati, e la navigazione normale funzionava.

Schema: PC con browser, router MikroTik che blocca DoT e DoH verso i server noti e lascia passare i siti normali, DNS del router che risponde NXDOMAIN al dominio canary di Firefox
Il router chiude la porta 853 e la 443 solo verso i server DNS cifrati noti; i siti normali passano, e il canary dice a Firefox di non attivare il DoH.

Passo 1: come blocco il DNS over TLS?

È una porta: la chiudi in forward, per tutto il traffico che attraversa il router.

/ip firewall filter
add chain=forward protocol=tcp dst-port=853 action=reject reject-with=tcp-reset \
    comment="Blocca DNS over TLS" place-before=[find action=fasttrack-connection]
add chain=forward protocol=udp dst-port=853 action=drop \
    comment="Blocca DNS over QUIC" place-before=[find action=fasttrack-connection]

place-before=[find action=fasttrack-connection] mette la regola subito prima del fasttrack, in alto nella catena. Non usare destination=0 o place-before=0: sul firewall di serie la regola 0 è quella dinamica dei contatori del fasttrack, e RouterOS risponde cannot move builtin.

La regola UDP copre il DNS over QUIC, il fratello più giovane del DoT, che usa la stessa porta. Il reject con tcp-reset fa capire subito al dispositivo che la strada è chiusa, invece di lasciarlo ad aspettare: un telefono Android con il DNS privato in automatico torna al DNS normale.

In laboratorio, prima: kdig +tls @1.1.1.1 mikrotik.com rispondeva. Dopo: nessuna risposta, né da 1.1.1.1 né da 8.8.8.8.

Passo 2: come riconosco i server DoH?

I server DoH sono pochi e famosi: Google, Cloudflare, Quad9, OpenDNS, AdGuard. RouterOS permette di mettere in una address list un nome invece di un indirizzo: il router lo risolve da solo e tiene aggiornati gli indirizzi.

/ip firewall address-list
add list=server-doh address=dns.google
add list=server-doh address=one.one.one.one
add list=server-doh address=cloudflare-dns.com
add list=server-doh address=mozilla.cloudflare-dns.com
add list=server-doh address=dns.quad9.net
add list=server-doh address=doh.opendns.com
add list=server-doh address=dns.adguard-dns.com

Guarda il risultato:

/ip firewall address-list print where list=server-doh

Sotto ogni nome compaiono le voci dinamiche (flag D) con i suoi indirizzi: dns.google porta con sé 8.8.8.8 e 8.8.4.4, one.one.one.one porta 1.1.1.1 e 1.0.0.1, dns.quad9.net porta 9.9.9.9. Per questo non aggiungere a mano anche gli indirizzi: in laboratorio, con 8.8.8.8 scritto insieme a dns.google, il router ha risposto already have such entry. I nomi nelle liste sono spiegati nel manuale MikroTik: Address-lists.

Passo 3: come blocco il DoH verso quei server?

Chiudi la porta 443, TCP e UDP (l’HTTP/3 viaggia in UDP), solo verso la lista:

/ip firewall filter
add chain=forward protocol=tcp dst-port=443 dst-address-list=server-doh \
    action=reject reject-with=tcp-reset comment="Blocca DoH verso i server noti" \
    place-before=[find action=fasttrack-connection]
add chain=forward protocol=udp dst-port=443 dst-address-list=server-doh \
    action=drop comment="Blocca DoH su HTTP/3" place-before=[find action=fasttrack-connection]

In laboratorio, dal PC dietro il router, prima di queste regole le richieste DoH a cloudflare-dns.com, a dns.google e direttamente a https://1.1.1.1/dns-query rispondevano tutte; dopo, nessuna. E https://mikrotik.com continuava ad aprirsi.

⚠️ Attenzione: 8.8.8.8, 1.1.1.1 e 9.9.9.9 restano raggiungibili sulla porta 53. Blocchi solo il loro DNS cifrato; il DNS normale verso di loro continua a funzionare, a meno che tu non lo giri al router come nel DNS trasparente.

Passo 4: e il nome dentro la connessione TLS?

Quando un browser apre una connessione HTTPS, nel primo pacchetto scrive in chiaro il nome del sito che vuole (lo SNI). Il matcher tls-host del firewall lo legge, e serve per i server DoH che cambiano indirizzo spesso perché stanno dietro una CDN:

/ip firewall filter
add chain=forward protocol=tcp dst-port=443 tls-host=*dns.google \
    action=reject reject-with=tcp-reset comment="Blocca DoH per nome" \
    place-before=[find action=fasttrack-connection]

Due cose che ho visto in laboratorio, e una che dice il manuale:

  • la regola deve stare prima del fasttrack e dell’accept established, ed è il motivo del place-before. Il primo pacchetto TLS arriva quando la connessione è già “established”: in fondo alla catena lo accetta prima la regola di serie, e la tua non lo vede mai. Messa in fondo, il DoH passava; messa prima del fasttrack, bloccato. Se il tuo firewall non ha il fasttrack, il place-before non trova niente e la regola finisce in fondo: spostala tu sopra l’accept established;
  • senza nome non funziona: https://1.1.1.1/dns-query non ha un nome dentro, e con il solo tls-host passava. Per questo serve anche la lista del passo 2;
  • il manuale avverte che il matcher non vede il nome se il primo pacchetto TLS è diviso in più segmenti, cosa che con i browser recenti succede. Il tls-host è un rinforzo, non la difesa principale.

Tutti i matcher sono nel manuale MikroTik: Filter.

Passo 5: come spengo il DoH di Firefox senza toccare i PC?

Firefox, prima di attivare il DoH da solo, chiede al DNS della rete il nome use-application-dns.net. Se la risposta è “non esiste”, capisce che la rete vuole gestire il DNS e lascia il DoH spento. Basta una voce statica:

/ip dns static add name=use-application-dns.net type=NXDOMAIN

In laboratorio, chiesto al router, use-application-dns.net risponde “not found”; chiesto direttamente a 9.9.9.9, risponde normalmente. Quindi funziona solo se i PC usano il DNS del router: il DHCP di serie glielo dà, e per gli apparati che hanno un DNS scritto dentro c’è il DNS trasparente con il bridge NAT. Le voci statiche sono nel manuale MikroTik: DNS.

Vale solo per l’attivazione automatica: se l’utente ha acceso il DoH a mano, Firefox lo usa lo stesso, e lì intervengono le regole dei passi 3 e 4.

Passo 6: come verifico che sia tutto chiuso?

Da un PC Linux dietro il router:

kdig +tls @1.1.1.1 mikrotik.com
curl -H 'accept: application/dns-json' 'https://cloudflare-dns.com/dns-query?name=mikrotik.com&type=A'
curl 'https://dns.google/resolve?name=mikrotik.com&type=A'
curl -I https://mikrotik.com/

Le prime tre devono fallire, l’ultima deve rispondere. Sul router i contatori dicono cosa sta lavorando:

/ip firewall filter print stats where comment~"Blocca"

Cosa controllo prima di metterlo in produzione?

  • non è un muro perfetto: chi usa un server DoH che non è nella lista, o una VPN, passa. Per i dispositivi aziendali la soluzione definitiva è spegnere il DoH con le policy dei browser (Firefox, Chrome ed Edge le hanno) e il DNS privato sui telefoni gestiti; il router copre tutto il resto;
  • tieni la lista curata: se un servizio smette di funzionare, guarda i contatori del passo 6 prima di cercare altrove;
  • le regole sono in forward e non toccano il router stesso, che continua a usare i suoi DNS, anche in DoH se lo hai configurato;
  • il router che decide il DNS di tutta la rete va protetto: segui l’Hardening di base di un router MikroTik.

Come funziona dentro, nella Knowledge base del Dojo: le address list, anche con i nomi DNS, l’ordine delle regole e la regola dummy del fasttrack.

Provato in laboratorio su PNETLab con CHR RouterOS 7.24.5 (stable) e un client Debian 12 dietro il router, con il firewall di serie e il fasttrack attivo: DoT verso 1.1.1.1 e 8.8.8.8 bloccato, address list con i nomi dei server DoH (e l’errore aggiungendo anche gli indirizzi), DoH verso cloudflare-dns.com, dns.google e 1.1.1.1 bloccato con la navigazione normale funzionante, tls-host efficace solo in cima alla catena e inutile senza nome, use-application-dns.net in NXDOMAIN dal DNS del router. Il comportamento di Firefox con il dominio canary viene dalla documentazione di Mozilla.

Domande frequenti

Come blocco il DNS over HTTPS con MikroTik?

Con una address list che contiene i nomi dei server DoH (dns.google, cloudflare-dns.com, dns.quad9.net…), che il router risolve da solo, e due regole in forward che chiudono la porta 443 TCP e UDP verso quella lista. Come rinforzo, il matcher tls-host in cima alla catena.

Come blocco il DNS over TLS?

Chiudendo in forward la porta 853, TCP per il DoT e UDP per il DNS over QUIC. Il reject con tcp-reset fa tornare subito al DNS normale i dispositivi in modalità automatica.

Perché la regola tls-host non blocca niente?

Di solito perché sta dopo il fasttrack o dopo l’accept established: il primo pacchetto TLS appartiene a una connessione già stabilita e viene accettato prima. Va spostata in cima. Inoltre non funziona con le connessioni a un indirizzo IP senza nome, né quando il primo pacchetto TLS è diviso in più segmenti.

Come disattivo il DoH automatico di Firefox su tutta la rete?

Facendo rispondere “non esiste” al nome use-application-dns.net dal DNS del router, con /ip dns static add name=use-application-dns.net type=NXDOMAIN. Funziona solo se i PC usano il DNS del router e se l’utente non ha acceso il DoH a mano.