Domanda

Supponiamo che ci sia un client che crea molte connessioni di breve durata con un server.

Se il client chiude la connessione, ci saranno molte porte nello stato TIME_WAIT sul lato client. Poiché il client esaurisce le porte locali, diventa impossibile tentare rapidamente una nuova connessione.

Se il server chiude la connessione, vedrò molti TIME_WAIT sul lato server. Tuttavia, questo fa del male? Il client (o altri client) può continuare a fare tentativi di connessione poiché non si esaurisce mai dalle porte locali e il numero dello stato TIME_WAIT aumenterà sul lato server. Cosa succede alla fine? Succede qualcosa di brutto? (rallentamento, arresto anomalo, interruzioni delle connessioni, ecc.)

Tieni presente che la mia domanda non è " Qual è lo scopo di TIME_WAIT ? " ma " Cosa succede se ci sono così tanti stati TIME_WAIT sul server? " So già cosa succede quando una connessione viene chiusa in TCP / IP e perché è richiesto lo stato TIME_WAIT . Non sto cercando di risolverlo ma voglio solo sapere qual è il potenziale problema con esso.

Per dirla semplicemente, diciamo netstat -nat | grep: 8080 | grep TIME_WAIT | wc -l stampa 100000 . Cosa succederebbe? Lo stack di rete O / S rallenta? " Troppi file aperti " errore? O semplicemente niente di cui preoccuparsi?

È stato utile?

Soluzione

Ogni socket in TIME_WAIT consuma un po 'di memoria nel kernel, in genere un po' meno di un STABILITO ma ancora significativo. Un numero sufficientemente grande potrebbe esaurire la memoria del kernel, o almeno degradare le prestazioni perché quella memoria potrebbe essere utilizzata per altri scopi. I socket TIME_WAIT non contengono descrittori di file aperti (supponendo che siano stati chiusi correttamente), quindi non dovresti preoccuparti di "troppi file aperti" di errore.

Il socket lega anche quel particolare indirizzo IP src / dst in modo che non possa essere riutilizzato per la durata dell'intervallo TIME_WAIT . (Questo è lo scopo previsto dello stato TIME_WAIT .) Il collegamento della porta non è in genere un problema a meno che non sia necessario ricollegare un con la stessa coppia di porte. Molto spesso un lato utilizzerà una porta effimera, con un solo lato ancorato a una porta ben nota. Tuttavia, un numero molto elevato di socket TIME_WAIT può esaurire lo spazio della porta effimera se si effettua ripetutamente e frequentemente la connessione tra gli stessi due indirizzi IP. Nota che ciò influisce solo su questa particolare coppia di indirizzi IP e non influisce sulla creazione di connessioni con altri host.

Altri suggerimenti

Risultati finora:

Anche se il server ha chiuso il socket usando la chiamata di sistema, il suo descrittore di file non verrà rilasciato se entra nello stato TIME_WAIT. Il descrittore di file verrà rilasciato successivamente quando lo stato TIME_WAIT è scomparso (ovvero dopo 2 * MSL secondi). Pertanto, troppi TIME_WAIT porteranno probabilmente all'errore "troppi file aperti" nel processo del server.

Credo che lo stack TCP / IP O / S sia stato implementato con una struttura dati adeguata (ad es. tabella hash), quindi il numero totale di TIME_WAIT non dovrebbe influire sulle prestazioni dello stack TCP / IP O / S. Solo il processo (server) proprietario dei socket nello stato TIME_WAIT ne risentirà.

Ogni connessione è identificata da una tupla (IP del server, porta del server, IP del client, porta del client). Fondamentalmente, le connessioni TIME_WAIT (siano esse lato server o lato client) occupano ciascuna una di queste tuple.

Con i TIME_WAIT sul lato client, è facile capire perché non è possibile effettuare ulteriori connessioni: non ci sono più porte locali. Tuttavia, lo stesso problema si applica sul lato server: una volta che ha 64k connessioni nello stato TIME_WAIT per un singolo client , non può accettare altre connessioni da quel client , perché non ha modo di distinguere tra la vecchia connessione e la nuova connessione - entrambe le connessioni sono identificate dalla stessa tupla. In questo caso, il server dovrebbe semplicemente inviare RST ai nuovi tentativi di connessione da quel client.

Se si dispone di molte connessioni da molti IP client diversi agli IP del server, è possibile che si verifichino limitazioni nella tabella di tracciamento delle connessioni.

Check:

sysctl net.ipv4.netfilter.ip_conntrack_count
sysctl net.ipv4.netfilter.ip_conntrack_max

Su tutte le tuple src ip / port e dest ip / port puoi avere solo net.ipv4.netfilter.ip_conntrack_max nella tabella di tracciamento. Se questo limite viene raggiunto, vedrai un messaggio nei tuoi registri " nf_conntrack: tabella piena, pacchetto di rilascio. & Quot; e il server non accetterà nuove connessioni in entrata fino a quando non vi sarà più spazio nella tabella di tracciamento.

Questa limitazione potrebbe colpirti molto prima che finiscano le porte effimere.

Nel mio scenario ho eseguito uno script che pianifica ripetutamente i file, il mio prodotto esegue alcuni calcoli e invia una risposta al client, ovvero il client sta effettuando una chiamata http ripetitiva per ottenere la risposta di ciascun file. Quando circa 150 file sono programmate porte socket in il mio server va nello stato time_wait e viene generata un'eccezione nel client che apre una connessione http, cioè

 Error : [Errno 10048] Only one usage of each socket address (protocol/network address/port) is normally permitted

Il risultato è stato che la mia applicazione è stata bloccata. Non so che il thread sia andato in stato di attesa o cosa è successo, ma devo interrompere tutti i processi o riavviare la mia applicazione per farla funzionare di nuovo.

Ho provato a ridurre il tempo di attesa a 30 secondi poiché sono 240 secondi per impostazione predefinita ma non ha funzionato.

Quindi, in pratica, l'impatto complessivo è stato fondamentale in quanto ha reso la mia applicazione non reattiva

sembra che il server possa esaurire le porte per assegnare le connessioni in entrata (per la durata degli TIMED_WAIT esistenti) - un caso per un attacco DOS.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top