_____
 / ____|
| |  __
| | |_ |
| |__| |
 \_____|
  ___
 / _ \
| (_) |
 \___/
 _ __
| '__|
| |
|_|
 _
| |
| |
| |
| |
|_|
  __ _ 
 / _` |
| (_| |
 \__,_|
 _ __  
| '_ \ 
| | | |
|_| |_|
 _ 
(_)
 _ 
| |
| |
|_|
      ___    ___    _ __ ___  
     / __|  / _ \  | '_ ` _ \ 
 _  | (__  | (_) | | | | | | |
(_)  \___|  \___/  |_| |_| |_|

Privacy e security col DNS - Pihole, dnscrypt-proxy e un po' di buon senso

2019-06-28

Questo articolo è una versione ridotta dell'originale pubblicato su Hakin9 con il titolo "Using a Pi-hole DNS setup for privacy and security"

Applicare la crittografia al DNS

Parte 0: perché?

Il DNS è un elemento critico di ogni rete basata su IP. È importante sapere quali sono i problemi che possiamo affrontare e risolvere adottando le tecnologie adatte.

Parte 1: Pihole

Esiste molta documentazione su Pihole online (https://pi-hole.net/), quindi mi limiterò a fare un breve riassunto. Pihole è un pacchetto software che comprende un'installazione di un server DNS e un'interfaccia web per la sua gestione. L'idea di mettersi un DNS in casa è dettata dal fatto che possiamo controllare puntualmente la risoluzione dei nomi, ad esempio bloccando quella legata a particolari categorie di domini per questioni di sicurezza o produttività: pubblicità, pornografia, botnet, malware, tracking, ecc. Le liste si possono scaricare già fatte, costruite in casa o entrambe le cose. In questo modo chiunque nella rete usi il Pihole come DNS non saprà come raggiungere certi domini e le connessioni in uscita non verranno completate. Selezionando una lista relativa alle pubblicità ad esempio, tutti i dispositivi (tablet, telefoni, PC, TV, ...) non visualizzeranno più gli annunci, una forma di AdBlocking di rete con tutto quello che ne consegue. Questa è l'idea alla base di Pihole, ma ci si può fare altro.

Oltre alla "pulizia" delle richieste, avere un DNS locale ha un impatto positivo dal punto di vista delle prestazioni, in particolare sulla latenza legata alla prima connessione in seguito alla quale poi intervengono meccanismi di caching locali al dispositivo. Siccome Pihole stesso fa caching delle informazioni ricevute, tanti più utilizzatori ci sono in rete tanto più efficiente sarà il meccanismo: se navigo su www.google.com il mio dispositivo (computer e browser) dopo la prima richiesta manterrà l'informazione senza dover chiedere nemmeno al Pihole locale, ma se un altro dispositivo in rete ha bisogno della medesima informazione allora Pihole risponderà direttamente senza dover passare da internet. Una cosa simile la fanno anche i router che vengono forniti dagli ISP, ma ne parliamo in seguito.

Pihole come DNS server (e anche dhcp volendo) utilizza una sua fork di dnsmasq ribattezzata FTL. La logica che viene applicata è semplice: ricevere la richiesta locale, verificare se il nome è in una delle liste vietate, verificare la cache, eventualmente chiedere all'esterno, inserire il risultato nella cache e quindi rispondere al client. Ovviamente ad un certo punto bisogna rivolgersi a dei DNS esterni, e qui inizia la seconda parte.

Parte 2: i DNS esterni

In rete trovate diverse spiegazioni di come funzioni un DNS e quali siano le sue differenti modalità operative, quindi non scriverò a riguardo. In sostanza il nostro Pihole dovrà riferirsi ad un DNS terzo per servire la risposta al client. Pihole permette di selezionare i DNS esterni (Upstream DNS) da un elenco in cui sono presenti i soliti sospetti (Google, Cloudfare, OpenDNS, Quad9, ...) e altri, oltre che poter utilizzare quelli decisi dall'utente.

Supponiamo di aver selezionato 8.8.8.8/8.8.4.4 (Google). Quello che succede è che Google potrà mantenere una lista completa delle nostre risoluzioni DNS ed usarla come meglio crede (all'interno delle policy del servizio auspicabilmente). Tuttavia la richiesta DNS transita per almeno un'altra rete, cioè quella del nostro ISP, che potrà a sua volta fare un elenco di cosa abbiamo visitato. L'ISP conosce nome e cognome dell'intestatario della linea, Google può ricollegare all'IP in uso tutti i device su cui ci sia un Google account, come ad esempio tablet, TV e telefoni Android. Entrambi possono quindi più o meno legittimamente interessarsi di cosa raggiungiamo su internet. E questa non è la parte negativa della storia.

Parte 3: paciugare il DNS

Siamo rimasti al nostro Pihole che chiede a 8.8.8.8 come risolvere un nome DNS, ad esempio quello del nostro sito di home banking. Nel flusso di attività del DNS per come l'abbiamo sempre conosciuto prima o poi questo si traduce in un pacchetto UDP che ritorna a Pihole e contiene ad esempio gli IP dei server della banca. Sia Google che l'ISP quindi sanno che io ho rapporti con questa banca. Tuttavia potrebbe esserci anche qualcun altro nella strada tra Pihole e i DNS di Google, o tra questi ed i server autoritativi/root necessari, che intercetta il pacchetto di risposta e lo modifica inserendo IP differenti da quelli reali della banca. Ho scritto IP ma potrebbe trattarsi ad esempio dei record MX che indicano dove trovare i server di posta, giusto per rendere l'idea. Il DNS viene usato per molte cose al giorno d'oggi.

In questa situazione Pihole semplicemente rende la risposta al client che quindi potrebbe connettersi ai server sbagliati. Chiaramente non è che Pihole in questa situazione tolga qualche elemento di sicurezza, è il protocollo DNS che è stato pensato per un mondo che ormai non esiste più.

Pihole tuttavia permette di attivare una funzione specifica nella sua pagina di configurazione dei DNS di upstream, ovvero il DNSSEC.

Abilitare DNSSEC su Pihole

Per i dettagli trovate tutto qui https://www.dnssec.net/. In breve DNSSEC è una serie di estensioni al protocollo DNS, che ovviamente non può essere abbandonato facilmente, che consentono di firmare digitalmente le risposte utilizzando un meccanismo di chiave pubblica/privata. Chi riceve le risposte può quindi verificare che esse provengano dal server inteso e che nessuno le abbia modificate in transito, un po' come quello che si può fare con https rispetto ad http.

Quindi con DNSSEC possiamo sapere con certezza che al nome www.dominio.xyz corrisponde l'IP 1.2.3.4, dal punto di vista della sicurezza è certamente un passo avanti importante. Tuttavia abbiamo lavorato sull'integrità del dato e sulla sua origine, ma non sulla confidenzialità.

Parte 4: cifrare le richieste DNS

Qui la cosa si fa un pochino più complicata. A differenza di DNSSEC che è stato standardizzato da tempo, per la cifratura del contenuto si sono sviluppate un paio di strade che sono molto più "fresche": DoH e DoT. La prima indica il DNS over HTTPS, in sostanza una richiesta DNS ottenuta mediante un web service su HTTP/2 o HTTPS sulla solita porta 443. La seconda è il DNS over TLS, cioè una richiesta col protocollo DNS veicolata su un canale cifrato (su TCP oppure UDP) con TLS su porta 853. Trattare entrambe le soluzioni è fuori dallo scopo di questo documento, ci basta sapere che in questo caso il contenuto del pacchetto DNS, quindi la nostra query e la relativa response saranno cifrati.

Non essendoci uno standard accettato e condiviso ognuno si è mosso in ordine sparso. Dnsmasq e la fork di Pihole (FTL) non li supportano per la difficoltà di implementazione che richiede molto lavoro e, a standard ancora freschi, potrebbe essere prematuro.

Parte 5: quindi?

La soluzione è a portata di mano. È infatti possibile inserire tra Pihole ed i DNS remoti un ulteriore software che prenda le richieste in chiaro da Pihole, le trasformi in DoH/DoT e le spedisca ai DNS remoti, facendo il percorso inverso poi per le risposte.

Per prima cosa è necessario assicurarsi che i DNS di Upstream supportino uno tra DoH/DoT. Qui https://dnscrypt.info/public-servers si può trovare una lista abbastanza nutrita.

Poi bisogna procurarsi il software adatto, ad esempio https://github.com/jedisct1/dnscrypt-proxy. Questo, ma anche altri prodotti simili, ha due punti di configurazione essenziali: l'endpoint dove ascoltare (ad esempio localhost:5300) e a chi inviare le richieste (DNS upstream).

Nella configurazione di Pihole questo diventa un upstream DNS, facendo attenzione che è necessario separare indirizzo e porta con il carattere #

La catena di elementi che abbiamo immaginato è quindi composta in questo modo:

Percorso richiesta DNS

In questo disegno appare evidente che ci sono un po' più elementi che configurare 1.1.1.1 sul proprio laptop: ognuno aggiunge lavoro da fare ma anche qualche funzionalità. Nello specifico la fase 1 è tipicamente in LAN e costa poco, Pihole filtra (eventualmente) la richiesta, quindi la invia in fase 2 a dnscrypt-proxy che tipicamente risiede sul medesimo server su una porta accessibile solo localmente. Da questo software la richiesta esce verso gli Upstream DNS in forma cifrata (fase 3) e tale ritorna.

Dnscrypt-proxy ha una funzione che gli consente di monitorare costantemente le prestazioni degli upstream DNS, almeno per ridurre in quella fase la latenza, se possibile. Le operazioni legate al DNS aggiungono normalmente latenza, ed alcune applicazioni (o persone) sono più o meno sensibili ad essa. Quello che stiamo aggiungendo non fa che peggiorare la cosa da questo punto di vista, ma è il prezzo per avere maggiore sicurezza e confidenzialità.

Esistono poi metodi un po' meno generali tipo l'installazione di software resolver DNS di uno specifico provider, come ad esempio quello di Cloudfare, ma di nuovo sono fuori dallo scopo del documento che vuole esporre qualche considerazione sul processo piuttosto che sui singoli prodotti.

Parte 6: no, non è tutto a posto

Ok, paghiamo con un po' di latenza ed otteniamo indietro della sicurezza. Sembra un bilancio equo. Quindi abbiamo risolto tutti i nostri problemi col DNS? Direi di no e vediamo alcuni dei problemi più evidenti.

La fase 1 dello schema sopra avviene in LAN solitamente, oppure via WiFi. Chiunque abbia le competenze e la possibilità di intromettersi in questo segmento della comunicazione ha ancora la possibilità di fare tutto ciò che ci siamo ripromessi di risolvere. Se per qualche motivo abbiamo separato dnscrypt-proxy e Pihole su server differenti, anche la fase 2 potrebbe soffrire dello stesso problema. Solitamente sono comunicazioni sull'interfaccia locale della macchina, quindi a basso costo ed alta sicurezza, ma scelte architetturali varie possono far si che si preferisca separare le due cose.

Per capire quanto sia banale praticare un attacco sul segmento 1, è sufficiente ragionare sul fatto che il client normalmente accetta la prima risposta DNS che torna indietro a seguito della richiesta. Vuol dire che possiamo facilmente realizzare (l'ho fatto 15 anni fa, da qualche parte in rete si trova) un software che sniffi il traffico DNS, estragga la query e risponda immediatamente con una response modificata ad arte. Questo tipo di attacco rischia di funzionare bene in quanto la risposta reale impiega diverso tempo (rispetto alla LAN) per tornare. Inoltre il protocollo UDP su cui si appoggia il DNS non richiede nessuna forma di "sessione".

La fase 3 prevede che noi ci fidiamo del server DNS. A sua volta questo dovrà chiedere all'esterno per risolvere la nostra query, e lo farà se tutto va bene usando al massimo DNSSEC. Tuttavia lo farà direttamente quindi non ci saranno associazioni dirette tra il nostro IP e la richiesta DNS. In ogni caso l'upstream DNS conoscerà direttamente tutte le nostre richieste, esattamente come nella configurazione standard all'inizio del documento: in questo senso non è cambiato nulla se non che il nostro ISP non potrà profilarci usando il DNS.

Ok, quindi non saprà che siti stiamo visitando? Sbagliato, potrebbe saperlo comunque. Se usiamo connessioni http è fin troppo facile: saprà cosa stiamo visitando con il massimo dettaglio possibile, URL, pagine, contenuti, password, ha tutto a disposizione (e con lui chiunque sia tra noi e il server web). Potrà sapere quale sia il nostro sito porno preferito, ma anche cosa cerchiamo e quali sezioni frequentiamo. Conoscerà la nostra utenza e la password per accedere ecc. ecc. Fortunatamente, almeno in quest'ottica, l'https sta diventando ubiquo in rete, quindi cosa resta di visibile? Almeno un paio di cose: l'indirizzo IP contattato, da cui è spesso possibile risalire al sito visitato, ma soprattutto si può catturare l'indicazione SNI che viene scambiata durante l'handshake iniziale del TLS, almeno fino a che Encrypted SNI non sarà disponibile per tutti (e non sarà a breve). Catturando lo SNI è possibile sapere il nome dell'host virtuale http richiesto (il server deve sapere che certificato fornire), quindi se chiedo www.sitoporno.xyz l'ISP (e gli altri) potranno registrare questa informazione. Tuttavia poi non potranno sapere quali siano le mie credenziali oppure le URL che visito e le ricerche che faccio su quel sito. Quindi le richieste per https://www.sitoporno.xyz/milf e https://www.sitoporno.xyz/midget saranno indistinguibili. Attenzione però che se il sito usa il terzo livello per distinguere le aree, ad esempio https://milf.sitoporno.xyz/ e https://midget.sitoporno.xyz/ queste informazioni saranno visibili.

Attenzione poi alle applicazioni che hanno un proprio meccanismo interno di risoluzione dei nomi: alcuni browser ad esempio possono usare dei loro servizi di risoluzione dei nomi per i motivi più disparati: raccolta di dati sull'utente, bypass della censura via DNS, aggiungere appunto DoH senza necessità che l'utente abbia una infrastruttura apposita (ad esempio Firefox) ed altro. Questo può essere vero per molti tipi di applicazione e che spesso hanno una configurazione apposita per usare un DNS differente da quello di sistema.

Molti dispositivi supportano la configurazione di più DNS, di solito almeno un paio. L'idea è che normalmente vengano usati in failover (se non va uno usiamo l'altro), ma non è assolutamente certo che questo avvenga (e nella mia esperienza non avviene). Solo un'analisi del traffico di rete può dimostrare l'uso effettivo. Quindi se il laptop dell'immagine sopra avesse configurato 192.168.1.250 e 8.8.8.8 come DNS primario e secondario, è molto probabile che usi 8.8.8.8 in diverse occasioni anche col primario disponibile, vanificando buona parte del lavoro fatto.

Per risolvere i problemi in fase 1 e per evitare di avere da mantenere l'infrastruttura necessaria che abbiamo visto, la soluzione è quella di avere direttamente dei client DNS nel sistema operativo che supportino DoH/DoT. Stanno sicuramente arrivando, ma ci vorrà tempo e molti dispositivi non saranno sicuramente aggiornati. Restano i problemi indicati nelle altre fasi.

Parte ultima: considerazioni

I possibili attacchi al DNS ed il suo utilizzo per il tracciamento delle attività utente sono problemi molto ampi. Questa esposizione non pretende di affrontarli in maniera esaustiva così come gli strumenti indicati (Pihole, dnscrypt-proxy) sono solo alcuni tra quelli disponibili, Google è più bravo di me a fornire liste di alternative. La configurazione di ognuno di questi strumenti si trova descritta in dettaglio sui siti di chi li sviluppa e spesso sui fora di discussione (io non fornisco supporto in tal senso a meno che non vogliate diventare miei clienti). La mia idea è che un minimo ci si debba attrezzare dove possibile, anche in reti semplici, dotandosi di meccanismi che una volta configurati garantiscono un migliore livello di privacy sulle nostre attività, nella piena consapevolezza che quanto descritto è solo un passo avanti su un problema complesso che non ha una soluzione semplice. Nella peggiore delle ipotesi avrete imparato qualcosa.

Sperando che abbiate trovato il pezzo interessante vi rimando alla pagina di contatto per ogni considerazione.