6. Gestione della Connessione (Connection Handling)
6.1. Pratiche Attuali (Current Practices)
La sezione 4.2.2 della [RFC1035] afferma:
-
Il server dovrebbe presumere che il client avvierà la chiusura della connessione e dovrebbe ritardare la chiusura della sua estremità della connessione fino a quando tutte le richieste del client in sospeso non sono state soddisfatte.
-
Se il server deve chiudere una connessione dormiente per recuperare risorse, dovrebbe attendere fino a quando la connessione è rimasta inattiva per un periodo dell'ordine di due minuti. In particolare, il server dovrebbe consentire che la sequenza di richieste SOA e AXFR (che avvia un'operazione di aggiornamento) venga effettuata su una singola connessione. Poiché il server non sarebbe comunque in grado di rispondere alle query, è possibile utilizzare una chiusura unilaterale o un reset invece di una chiusura graduale.
Altri protocolli più moderni (ad esempio, HTTP/1.1 [RFC7230], HTTP/2 [RFC7540]) hanno il supporto predefinito per connessioni TCP persistenti per tutte le richieste. Le connessioni vengono quindi normalmente chiuse tramite un segnale di "chiusura connessione" da una delle parti.
La descrizione nella [RFC1035] è chiara sul fatto che i server dovrebbero vedere le connessioni come persistenti (in particolare dopo aver ricevuto un SOA), ma sfortunatamente non fornisce abbastanza dettagli per un'interpretazione inequivocabile del comportamento del client per query diverse da un SOA. Inoltre, il DNS non ha ancora un meccanismo di segnalazione per il timeout o la chiusura della connessione, sebbene ne siano stati proposti alcuni.
6.1.1. Client
Non esiste oggi una guida chiara in alcuna RFC su quando un client DNS dovrebbe chiudere una connessione TCP e non ci sono raccomandazioni specifiche per quanto riguarda i timeout di inattività del client DNS. Tuttavia, al momento della stesura di questo documento, è pratica comune per i client chiudere la connessione TCP dopo aver inviato una singola richiesta (a parte il caso SOA/AXFR).
6.1.2. Server
Molte implementazioni di server DNS utilizzano un lungo timeout di inattività fisso e per impostazione predefinita un numero limitato di connessioni TCP. Offrono anche poco in termini di opzioni di gestione della connessione TCP. Gli svantaggi di questo includono:
-
L'esperienza operativa ha dimostrato che lunghi timeout del server possono facilmente causare esaurimento delle risorse e scarsa risposta in caso di carico pesante.
-
L'apertura intenzionale di molte connessioni e il lasciarle inattive può creare banalmente un attacco TCP denial of service (DoS) poiché molti server DNS sono scarsamente attrezzati per difendersi da questo modificando i loro timeout di inattività o altre politiche di gestione della connessione.
-
Un numero modesto di client che tentano contemporaneamente di utilizzare connessioni persistenti con timeout di inattività diversi da zero verso un tale server potrebbe causare involontariamente lo stesso problema DoS.
Si noti che questo DoS è solo sul servizio TCP. Tuttavia, in questi casi, colpisce non solo i client che desiderano utilizzare TCP per le loro query per motivi operativi, ma tutti i client che scelgono di ripiegare su TCP da UDP dopo aver ricevuto un flag TC=1.
6.2. Raccomandazioni (Recommendations)
Le sezioni seguenti includono raccomandazioni intese a tradursi in implementazioni più coerenti e scalabili di DNS-over-TCP.
6.2.1. Riutilizzo della Connessione (Connection Reuse)
Uno svantaggio percepito del DNS su TCP è la latenza aggiuntiva di configurazione della connessione, generalmente uguale a un RTT. Per ammortizzare i costi di configurazione della connessione, sia i client che i server DOVREBBERO (SHOULD) supportare il riutilizzo della connessione inviando più query e risposte su una singola connessione TCP persistente.
Quando si inviano più query su una connessione TCP, i client NON DEVONO (MUST NOT) riutilizzare l'ID del messaggio DNS di una query in volo su quella connessione per evitare collisioni di ID messaggio. Questo è particolarmente importante se il server potrebbe eseguire un'elaborazione fuori ordine (vedere la Sezione 7).
6.2.1.1. Pipelining delle Query (Query Pipelining)
A causa dell'uso storico di TCP principalmente per il trasferimento di zona e le risposte troncate, nessuna RFC esistente discute l'idea di pipelining delle query DNS su una connessione TCP.
Per ottenere prestazioni alla pari con UDP, i client DNS DOVREBBERO (SHOULD) eseguire il pipelining delle loro query. Quando un client DNS invia più query a un server, NON DOVREBBE (SHOULD NOT) attendere una risposta in sospeso prima di inviare la query successiva. I client DOVREBBERO (SHOULD) trattare TCP e UDP in modo equivalente quando considerano il momento in cui inviare una particolare query.
È probabile che i server DNS debbano elaborare le query in pipeline contemporaneamente e anche inviare risposte fuori ordine su TCP per fornire il livello di prestazioni possibile con il trasporto UDP. Se le prestazioni TCP sono importanti, i client potrebbero trovare utile utilizzare i tempi di elaborazione del server come input per gli algoritmi di selezione del server e del trasporto.
I server DNS (specialmente quelli ricorsivi) DEVONO (MUST) aspettarsi di ricevere query in pipeline. Il server DOVREBBE (SHOULD) elaborare le query TCP contemporaneamente, proprio come farebbe per UDP. Il server DOVREBBE (SHOULD) rispondere a tutte le query in pipeline, anche se vengono ricevute in rapida successione. La gestione delle risposte alle query in pipeline è trattata nella Sezione 7.
6.2.2. Connessioni Concorrenti (Concurrent Connections)
Per mitigare il rischio di sovraccarico involontario del server, i client DNS DEVONO (MUST) fare attenzione a ridurre al minimo il numero di connessioni TCP simultanee effettuate verso un singolo server. Si RACCOMANDA (RECOMMENDED) che per ogni data interazione client/server NON ci dovrebbe (SHOULD) essere più di una connessione per query regolari, una per i trasferimenti di zona e una per ogni protocollo utilizzato su TCP (ad esempio, se il risolutore stava utilizzando TLS). Tuttavia, si nota che alcune configurazioni primarie/secondarie con molte zone occupate potrebbero dover utilizzare più di una connessione TCP per i trasferimenti di zona per motivi operativi (ad esempio, per supportare trasferimenti simultanei di più zone).
Allo stesso modo, i server POSSONO (MAY) imporre limiti al numero di connessioni TCP simultanee gestite per un particolare indirizzo IP client o sottorete. Questi limiti DOVREBBERO (SHOULD) essere molto più ampi delle linee guida del client sopra riportate, perché il server non sa, ad esempio, se un indirizzo IP client appartiene a un singolo client, è più risolutori su una singola macchina o è più client dietro un dispositivo che esegue Network Address Translation (NAT).
6.2.3. Timeout di Inattività (Idle Timeouts)
Per mitigare il rischio di sovraccarico involontario del server, i client DNS DEVONO (MUST) fare attenzione a ridurre al minimo il tempo di inattività delle sessioni DNS-over-TCP stabilite verso un singolo server. I client DNS DOVREBBERO (SHOULD) chiudere la connessione TCP di una sessione inattiva, a meno che non sia stato stabilito un timeout di inattività utilizzando qualche altro meccanismo di segnalazione, ad esempio, [edns-tcp-keepalive].
Per mitigare il rischio di sovraccarico involontario del server, si RACCOMANDA (RECOMMENDED) che il periodo di inattività predefinito a livello di applicazione server sia dell'ordine di secondi, ma non viene specificato alcun valore particolare. In pratica, il periodo di inattività può variare dinamicamente e i server POSSONO (MAY) consentire alle connessioni inattive di rimanere aperte per periodi più lunghi se le risorse lo consentono. Un timeout di almeno alcuni secondi è consigliabile per le normali operazioni per supportare quei client che si aspettano che la sequenza di richieste SOA e AXFR venga effettuata su una singola connessione come originariamente specificato nella [RFC1035]. I server POSSONO (MAY) utilizzare timeout zero quando sono sottoposti a carichi pesanti o sono sotto attacco.
I messaggi DNS consegnati su TCP potrebbero arrivare in più segmenti. Un server DNS che ripristina il suo timeout di inattività dopo aver ricevuto un singolo segmento potrebbe essere vulnerabile a un "slow-read attack". Per questo motivo, i server DOVREBBERO (SHOULD) ripristinare il timeout di inattività alla ricezione di un messaggio DNS completo, piuttosto che alla ricezione di qualsiasi parte di un messaggio DNS.
6.2.4. Smontaggio (Teardown)
In condizioni normali, i client DNS in genere avviano la chiusura della connessione su connessioni inattive; tuttavia, i server DNS possono chiudere la connessione se viene superato il timeout di inattività impostato dalla politica locale. Inoltre, le connessioni possono essere chiuse da entrambe le estremità in condizioni insolite come la difesa da un attacco o un guasto/riavvio del sistema.
I client DNS DOVREBBERO (SHOULD) riprovare le query senza risposta se la connessione si chiude prima di ricevere tutte le risposte in sospeso. Nessun algoritmo di riprova specifico è specificato in questo documento.
Se un server DNS scopre che un client DNS ha chiuso una sessione TCP (o se la sessione è stata altrimenti interrotta) prima che tutte le risposte in sospeso siano state inviate, allora il server NON DEVE (MUST NOT) tentare di inviare quelle risposte. Naturalmente, il server DNS PUÒ (MAY) memorizzare nella cache quelle risposte.