W moim pliku konfiguracyjnym ustawiłem opcję tcp_tw_recycle / reuse na 1.
Jakie są tego konsekwencje?
Czy ponowne użycie gniazda TCP może stanowić zagrożenie dla bezpieczeństwa? tj. 2 różne połączenia, z których oba potencjalnie mogą wysyłać dane?
Czy nadaje się do krótkotrwałych połączeń z niewielką szansą na ponowne połączenie?
Odpowiedzi:
Domyślnie, gdy oba
tcp_tw_reuse
itcp_tw_recycle
są wyłączone, jądro będzie upewnić się, że gniazda wTIME_WAIT
stanie pozostanie w tym stanie wystarczająco długo - wystarczająco długo, aby mieć pewność, że pakiety należące do połączeń przyszłości nie będą mylone z późnych pakietów starego połączenia.Gdy włączysz
tcp_tw_reuse
, gniazda wTIME_WAIT
stanie mogą być używane przed ich wygaśnięciem, a jądro spróbuje upewnić się, że nie dojdzie do kolizji w odniesieniu do numerów sekwencji TCP. Jeśli włączysztcp_timestamps
(inaczej PAWS, dla ochrony przed zawiniętymi numerami sekwencji), upewni się, że kolizje te nie będą miały miejsca. Musisz jednak włączyć znaczniki czasu TCP na obu końcach (przynajmniej tak rozumiem). Zobacz definicję tcp_twsk_unique dla szczegółów krwawych.Po włączeniu
tcp_tw_recycle
jądro staje się znacznie bardziej agresywne i przyjmuje założenia dotyczące znaczników czasu używanych przez zdalne hosty. Będzie śledził ostatni znacznik czasu używany przez każdy zdalny host mający połączenie wTIME_WAIT
stanie) i pozwoli na ponowne użycie gniazda, jeśli znacznik czasu prawidłowo się zwiększył. Jeśli jednak znacznik czasu używany przez host zmieni się (tzn. Wypaczy się w czasie),SYN
pakiet zostanie po cichu odrzucony, a połączenie nie zostanie nawiązane (zobaczysz błąd podobny do „limitu czasu połączenia”). Jeśli chcesz zanurzyć się w kodzie jądra, definicja tcp_timewait_state_process może być dobrym punktem wyjścia.Teraz znaczniki czasu nigdy nie powinny cofać się w czasie; chyba że:
TIME_WAIT
gniazdo prawdopodobnie wygasło, więc nie będzie problemu);TIME_WAIT
połączenia pozostaną trochę, ale prawdopodobnie inne połączenia zostaną naruszoneTCP RST
, co zwolni miejsce);W tym drugim przypadku możesz mieć wiele hostów za tym samym adresem IP, a zatem różne sekwencje znaczników czasu (lub wspomniane znaczniki czasu są losowo przydzielane przy każdym połączeniu przez zaporę). W takim przypadku niektóre hosty nie będą mogły połączyć się losowo, ponieważ są mapowane na port, dla którego
TIME_WAIT
segment serwera ma nowszą sygnaturę czasową. Dlatego dokumenty mówią, że „urządzenia NAT lub moduły równoważenia obciążenia mogą zacząć upuszczać ramki z powodu ustawienia”.Niektóre osoby zalecają pozostawienie w
tcp_tw_recycle
spokoju, ale włączanietcp_tw_reuse
i obniżanietcp_timewait_len
. Zgadzam się :-)źródło
Właśnie mnie ugryzł, więc może ktoś mógłby skorzystać z mojego bólu i cierpienia. Po pierwsze, zaangażowany link z dużą ilością informacji: http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html
W szczególności:
Korzystałem z tego, że włączono je z powodzeniem, aby zapewnić możliwie małe opóźnienie, haproxy łączność od klientów do klastra MySql NDB. To było w prywatnej chmurze i żadne połączenia z żadnego do żadnego nie miały żadnego NAT w miksie. Przypadek użycia miał sens, zmniejsz opóźnienie dla klientów promienia uderzających w NDB przez haproxy tak bardzo, jak to tylko możliwe. Tak się stało.
Zrobiłem to jeszcze raz w publicznym systemie haproxy, równoważąc obciążenie ruchem sieciowym, tak naprawdę nie badając wpływu (głupi, prawda ?!) i odkryłem po wielu problemach i ściganiu duchów, które:
Po stronie klienta będą widzieć okresy, w których nie będą już otrzymywać odpowiedzi na pakiety SYN, czasem tu i tam, a czasem przez długi czas. Znowu losowo.
Krótka historia, w moim niedawnym, bolesnym doświadczeniu, polega na pozostawieniu ich samych / wyłączonych na publicznych serwerach, bez względu na rolę!
źródło
Od 'man 7 tcp' Zobaczysz to:
Niewiele tam pomocy. Ta wersja ma również dobry wgląd:
/programming/6426253/tcp-tw-reuse-vs-tcp-tw-recycle-which-to-use-or-both
Ale nie konkretne informacje o tym, dlaczego ponowne użycie jest bezpieczniejsze niż recykling. Podstawowa odpowiedź jest taka, że tcp_tw_reuse pozwoli na skorzystanie z tego samego gniazda, jeśli jest już jedno w TIME_WAIT z tymi samymi parametrami TCP i jest w stanie, w którym nie oczekuje się dalszego ruchu (wierzę, że po wysłaniu FIN ). Z drugiej strony tcp_tw_recycle ponownie użyje gniazd w TIME_WAIT z tymi samymi parametrami niezależnie od stanu, co może dezorientować stanowe zapory ogniowe, które mogą oczekiwać różnych pakietów.
tcp_tw_reuse można wykonać selektywnie w kodzie, ustawiając opcję gniazda SO_REUSEADDR, udokumentowaną
man 7 socket
jako:źródło
SO_REUSEADDR
jest to powiązanetcp_tw_reuse
? O ile mi wiadomo,SO_REUSEADDR
ma zastosowanie tylko wtedy, gdy chceszbind()
,tcp_tw_reuse
i poinstruuje jądro, aby ponownie użyło portu lokalnego gniazda wTIME_WAIT
stanie, jeśli będzie musiało utworzyć nowe połączenie wychodzące.