Blog ·
Possesso di un nome host, senza certificato
Un modulo con un campo nome host è un generatore di traffico finché il possesso non è provato. Due tipi di challenge, perché scadono e chi deve recuperarli.
Di Provibr
Qualunque prodotto che lasci digitare a un cliente un nome host e poi lo controlli ogni minuto ha costruito due cose. La prima è il monitoraggio. La seconda è un generatore distribuito di richieste, puntato dove piace al cliente, con il nome della sua azienda nello user agent e l’indirizzo di fatturazione del suo cliente alle spalle.
L’obiezione consueta è che il bersaglio ha un indirizzo pubblico, quindi chiunque potrebbe comunque inviargli traffico. È vero e non è il punto. Un indirizzo pubblico non è il permesso di misurare qualcuno, e «chiunque potrebbe» non è una difesa che sopravvive alla prima segnalazione di abuso, tanto meno quando il traffico è periodico, continuato e proviene da una piattaforma commerciale identificabile.
Perciò un bersaglio che sia un nome host va guadagnato. Questo è il progetto su cui ci siamo fermati, comprese le parti meno ovvie di quanto sembrino.
Due metodi che dimostrano cose diverse
Ci sono due modi pratici perché qualcuno dimostri che un nome è suo, e vale la pena essere chiari sul fatto che non sono equivalenti.
Un record TXT nel DNS dimostra il controllo della zona. Chi può metterci un valore decide dove punta il nome, che è la rivendicazione più forte che esista su un nome.
Un file sul server web dimostra il controllo della macchina a cui il nome si risolve al momento. È più debole: sull’hosting condiviso sono di più le persone che possono produrlo di quelle che possono modificare la zona. È anche molto più alla portata di un cliente che ha un server ma nessun accesso al fornitore DNS del proprio datore di lavoro.
È la stessa coppia di compromessi che fanno le autorità di certificazione con i loro due tipi di challenge più comuni, e ne segue la stessa conclusione: si offrano entrambi, si registri quale è stato usato, e non si finga che abbiano lo stesso peso.
La forma del challenge
Il record TXT sta sotto un’etichetta propria anziché sul dominio stesso. Non è ordine. Un record sull’apice atterra accanto ai record di politica della posta del cliente, dove ogni stringa in più spinge la risposta più vicino alla dimensione oltre la quale i resolver cominciano a passare una brutta giornata, e dove la pulizia dei «vecchi record TXT» fatta da qualcun altro lo rimuove senza cattiveria. Sotto un’etichetta propria sta da solo.
Il file vive sotto un percorso riservato con il token come nome del file, e il file contiene il token e nient’altro.
Il token in sé è di trentadue caratteri esadecimali, cioè centoventotto bit. Non è un segreto e non è una chiave: finirà nel DNS pubblico o su un server web pubblico. Ciò che deve essere è non indovinabile, perché chiunque possa prevedere un token valido può rivendicare un nome che non possiede mettendolo prima sul proprio server. L’esadecimale minuscolo lo rende sicuro in un record DNS, sicuro in un URL, e libero da caratteri che si possono leggere male quando un cliente lo ricopia a mano.
Una regola strutturale: esattamente un pezzo di codice scrive il challenge, e il risultato viaggia con la richiesta fino a chi esegue il controllo. Se entrambe le parti conoscessero il prefisso in modo indipendente, prima o poi arriverebbe il giorno in cui il pannello mostra un’etichetta e il verificatore ne cerca un’altra, e il messaggio che ne esce è «il record non c’è» a proposito di un record che c’è. Nulla è più costoso da assistere di una risposta corretta a una domanda che nessuno ha posto.
Perché è l’agente a fare il recupero
È la decisione da cui pende tutto il resto.
La piattaforma non risolve il nome e non recupera il file. Se lo facesse, la nostra infrastruttura si metterebbe a fare connessioni verso un nome digitato da un utente, il che è una server side request forgery con un campo di modulo come superficie d’attacco. L’esito classico è una richiesta verso un endpoint di metadati di un cloud dall’interno della nostra stessa rete, fatta da noi, su richiesta.
Lo fa invece l’agente del cliente: lo stesso agente che poi eseguirà i controlli, che risiede dentro la rete del cliente e connesso solo verso l’esterno. Mentire sull’esito non porta alcun guadagno, perché il premio è il permesso di misurare qualcosa che l’agente poteva già raggiungere. La verifica viene eseguita dalla parte che ha già l’accesso, che è l’unica disposizione in cui l’incentivo a barare sparisce.
C’è una conseguenza che vale la pena dire ad alta voce, perché sembra una protezione mancante. Le indicazioni per questo genere di funzione di solito dicono di bloccare gli intervalli privati, il loopback, gli indirizzi link-local e quelli di metadati. Quella regola appartiene alle sonde ospitate, cioè ai punti di misura che gestiamo noi e che stanno nella nostra rete. Per un agente dentro la rete del cliente, gli indirizzi privati sono il caso normale: il suo hypervisor, il suo switch, il suo storage. Bloccarli disabiliterebbe l’unica fonte di misura proprio per la situazione a cui serve.
Ciò che i due percorsi condividono è un’unica funzione che decide quali indirizzi sono ammessi. Se verifica e misura avessero ciascuna il proprio elenco, ci sarebbe un giorno in cui non sarebbero d’accordo, e quel giorno uno dei due è una scorciatoia attorno all’altro.
Chiudersi davanti a risposte miste
Un nome può risolversi in più indirizzi, e non è detto che siano ugualmente accettabili.
Se un nome risponde sia con l’indirizzo pubblico del cliente sia con un endpoint di metadati, allora ogni esecuzione è una nuova estrazione. Nove esecuzioni misurano l’indirizzo pubblico e la decima parla con tutt’altro. Perciò il numero di risposte accettabili non porta alcuna informazione: un solo indirizzo vietato nell’insieme rende inutilizzabile l’intero nome, e al cliente viene detto quale indirizzo fosse, perché un rifiuto su cui non può agire è soltanto un messaggio d’errore.
Vale lo stesso durante la verifica e durante i controlli ordinari, che è di nuovo il motivo per cui esiste una politica degli indirizzi e non due.
Dettagli che si imparano solo mettendolo in funzione
Tre di questi sono usciti dal costruire il verificatore; il quarto è una decisione di progettazione che sta bene accanto a loro.
Confrontare con «contiene», non con l’uguaglianza. A un fornitore DNS è consentito presentare un valore TXT con delle virgolette intorno, e alcuni pannelli di controllo aggiungono virgolette che poi tolgono di nuovo nella propria visualizzazione. Il token è lungo e opaco: o c’è o non c’è, e pretendere una corrispondenza esatta punisce soltanto i clienti che hanno fatto tutto giusto.
Inviare il nome nell’intestazione host e nel nome server TLS. La connessione va a un indirizzo che ha già superato il controllo della politica, ma a un server web con sopra più siti bisogna dire quale si sta chiedendo. Senza entrambi, un cliente configurato correttamente fallisce la verifica perché gli è stato servito il sito predefinito di qualcun altro.
Consentire esattamente un redirect. Un server web che spinge tutto su HTTPS è normale, e rifiutare il redirect farebbe fallire mezza Internet. Consentirne molti lascerebbe finire la prova da tutt’altra parte. Un salto, e solo verso lo stesso host.
Non richiedere HTTPS per il challenge su file. La prova è il token. Un certificato non gli aggiunge nulla, e richiederne uno trasforma un controllo di possesso in un controllo di certificato, che è una domanda diversa con modalità di guasto diverse. È lo stesso ragionamento dietro al tipo di challenge in HTTP semplice nell’emissione dei certificati. Si noti che questo comportamento predefinito è specifico della verifica: quando lo schema è la cosa che viene misurata, indovinarlo produrrebbe una misura verde di qualcosa di diverso da ciò che il cliente ha configurato, e lì il comportamento giusto è rifiutare.
La prova scade, perché i domini cambiano proprietario
Un nome verificato non deve restare verificato per sempre, e il motivo non è la paranoia sui nostri stessi registri.
I domini cambiano proprietario senza dirlo a nessuno. Un cliente lascia scadere una registrazione, qualcun altro la raccoglie, e da quel momento stiamo misurando la macchina di uno sconosciuto ogni minuto con il nome del nostro cliente attaccato alla pianificazione. Nessuno in quella catena ha fatto qualcosa di sbagliato e l’esito resta inaccettabile.
Novanta giorni è la validità che abbiamo scelto, che è lo stesso ordine di grandezza di un certificato a vita breve e per lo stesso motivo: abbastanza breve perché un trasferimento si noti presto, abbastanza lunga perché i clienti non facciano pratiche burocratiche ogni settimana. La riverifica comincia quattordici giorni prima della scadenza, il che è deliberatamente generoso, perché una riverifica fallita di solito vuol dire che l’agente era offline o che un resolver era lento, non che il possesso sia cambiato.
I tentativi sono limitati a uno ogni sei ore, e non sono legati all’intervallo di monitoraggio. Una verifica non è una misura: non dice nulla sulla disponibilità, non appartiene a una cifra di uptime, e chiederla più spesso genera soltanto traffico contro il DNS del cliente. Sei ore su quattordici giorni fanno più di cinquanta tentativi, il che trasforma «scaduto» in un segnale vero anziché in sfortuna.
Gli stati che ne escono sono in attesa, verificato, in scadenza, scaduto e revocato, e uno di essi non è un cancello. «In scadenza» esiste perché l’interfaccia possa avvisare qualcuno; una prova che scade fra dieci giorni oggi è valida, e i controlli continuano a girare. Trattarla come uno stato di blocco a sé toglierebbe a un cliente il monitoraggio in un giorno in cui non è cambiato nulla.
È il database a imporre l’accoppiamento, anziché fidarsi del codice: una riga o ha sia un momento di verifica sia un momento di scadenza, oppure non ha nessuno dei due. Una riga verificata senza scadenza è una concessione permanente che nessuno ha scelto, che è esattamente la cosa che tutto questo progetto esiste per impedire.
Che cosa metteremmo per iscritto
- Decida che cosa dimostra il challenge, controllo della zona o controllo della macchina, e conservi quale dei due è stato usato.
- Metta il challenge sotto un’etichetta sua, mai sull’apice accanto ai record di posta di qualcuno.
- Faccia in modo che il verificatore sia la parte che ha già l’accesso. Se la sua piattaforma recupera un nome fornito da un utente, ha costruito una funzione di request forgery.
- Una sola politica degli indirizzi per verifica e misura. Due elenchi diventano due comportamenti.
- Si chiuda davanti a risposte miste, e nomini l’indirizzo colpevole nel rifiuto.
- Dia una scadenza alla prova, e cominci a rinnovarla molto prima, perché il guasto da cui si sta proteggendo è silenzioso per natura.
Per essere chiari sul nostro stato: questo è un progetto che esiste nel codice con i propri test, il monitoraggio non è una cosa che oggi ci si possa comprare, e nulla di quanto sopra va letto come l’annuncio di un prodotto. È la forma che costruiremmo di nuovo.
Dal lavoro sul monitoraggio di Provibr. La questione correlata del misurare senza toccare, e di quanti byte può inviare un controllo, è in perché uno scanner deve inviare zero byte; come un agente decide quale usare fra più punti di misura è in come un agente sceglie il server edge giusto.