Recentemente abbiamo avuto un server Apache che stava rispondendo molto lentamente a causa dell'inondazione SYN. La soluzione alternativa era abilitare tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf
).
Ho pubblicato una domanda su questo qui se vuoi più background.
Dopo aver abilitato i syncookie abbiamo iniziato a vedere il seguente messaggio in / var / log / messages circa ogni 60 secondi:
[84440.731929] possible SYN flooding on port 80. Sending cookies.
Vinko Vrsalovic mi ha informato che questo significa che il backlog di syn si sta riempiendo, quindi ho aumentato tcp_max_syn_backlog a 4096. Ad un certo punto ho anche abbassato tcp_synack_retries a 3 (invece del valore predefinito di 5) emettendo sysctl -w net.ipv4.tcp_synack_retries=3
. Dopo aver fatto ciò, la frequenza sembrava diminuire, con l'intervallo dei messaggi che variava tra circa 60 e 180 secondi.
Successivamente ho emesso sysctl -w net.ipv4.tcp_max_syn_backlog=65536
, ma sto ancora ricevendo il messaggio nel registro.
Durante tutto questo ho osservato il numero di connessioni nello stato SYN_RECV (eseguendolo watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'
) e non supera mai i 240, molto più basse delle dimensioni del backlog. Eppure ho un server Red Hat che si aggira intorno a 512 (il limite su questo server è il valore predefinito di 1024).
Ci sono altre impostazioni di tcp che limiterebbero le dimensioni del backlog o sto abbaiando l'albero sbagliato? Il numero di connessioni SYN_RECV dovrebbe essere netstat -tuna
correlato alla dimensione del backlog?
Aggiornare
Come meglio posso dire che ho a che fare con connessioni legittime qui, si netstat -tuna|wc -l
aggira intorno al 5000. Ho cercato questo oggi e ho trovato questo post da un dipendente last.fm, che è stato piuttosto utile.
Ho anche scoperto che tcp_max_syn_backlog non ha alcun effetto quando i syncookie sono abilitati (come da questo link )
Quindi come passo successivo ho impostato quanto segue in sysctl.conf:
net.ipv4.tcp_syn_retries = 3
# default=5
net.ipv4.tcp_synack_retries = 3
# default=5
net.ipv4.tcp_max_syn_backlog = 65536
# default=1024
net.core.wmem_max = 8388608
# default=124928
net.core.rmem_max = 8388608
# default=131071
net.core.somaxconn = 512
# default = 128
net.core.optmem_max = 81920
# default = 20480
Ho quindi impostato il test del tempo di risposta, ho eseguito sysctl -p
e disabilitato i syncookies da sysctl -w net.ipv4.tcp_syncookies=0
.
Dopo aver fatto ciò, il numero di connessioni nello stato SYN_RECV è rimasto intorno a 220-250, ma le connessioni stavano iniziando di nuovo a ritardare. Una volta notato questi ritardi, ho riattivato i syncookies e i ritardi si sono fermati.
Credo che quello che stavo vedendo fosse ancora un miglioramento rispetto allo stato iniziale, tuttavia alcune richieste erano ancora in ritardo, il che è molto peggio che avere i syncookie abilitati. Quindi sembra che io sia bloccato con loro abilitati fino a quando non avremo altri server online per far fronte al carico. Anche allora, non sono sicuro di vedere un motivo valido per disabilitarli di nuovo poiché vengono inviati (apparentemente) solo quando i buffer del server si riempiono.
Ma il backlog di syn non sembra essere pieno con solo ~ 250 connessioni nello stato SYN_RECV! È possibile che il messaggio di allagamento SYN sia un'aringa rossa ed è qualcosa di diverso dal syn_backlog che si sta riempiendo?
Se qualcuno ha altre opzioni di ottimizzazione che non ho ancora provato, sarei più che felice di provarle, ma sto iniziando a chiedermi se l'impostazione syn_backlog non viene applicata correttamente per qualche motivo.