„Możliwe zalanie SYN” w dzienniku pomimo niskiej liczby połączeń SYN_RECV

30

Ostatnio mieliśmy serwer Apache, który reagował bardzo wolno z powodu zalania SYN. Obejściem tego problemu było włączenie funkcji tcp_syncookies ( net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf).

Wysłałem pytanie na ten temat , jeśli chcesz uzyskać więcej informacji.

Po włączeniu synchronizacji zaczęliśmy widzieć następującą wiadomość w / var / log / messages co około 60 sekund:

[84440.731929] possible SYN flooding on port 80. Sending cookies.

Vinko Vrsalovic poinformował mnie, że to oznacza, że ​​zaległości syn są pełne, więc podniosłem tcp_max_syn_backlog do 4096. W pewnym momencie obniżyłem również tcp_synack_retries do 3 (w porównaniu z domyślną wartością 5), wydając sysctl -w net.ipv4.tcp_synack_retries=3. Po wykonaniu tej czynności częstotliwość wydawała się spadać, a odstępy między wiadomościami wahały się od około 60 do 180 sekund.

Następnie wydałem sysctl -w net.ipv4.tcp_max_syn_backlog=65536, ale nadal otrzymuję komunikat w dzienniku.

Przez cały ten czas obserwowałem liczbę połączeń w stanie SYN_RECV (przez uruchomienie watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l') i nigdy nie przekracza ona około 240, znacznie mniej niż rozmiar zaległości. Mam jednak serwer Red Hat, który unosi się wokół 512 (limit na tym serwerze to domyślnie 1024).

Czy są jakieś inne ustawienia TCP, które ograniczałyby rozmiar zaległości, czy też szczekam niewłaściwe drzewo? Czy liczba połączeń SYN_RECV powinna netstat -tunakorelować z wielkością zaległości?


Aktualizacja

Najlepiej, jak mogę powiedzieć, że mam tutaj do czynienia z legalnymi połączeniami, na których netstat -tuna|wc -lwidnieje około 5000. Badałem to dzisiaj i znalazłem ten post od pracownika last.fm, który był raczej przydatny.

Odkryłem również, że tcp_max_syn_backlog nie działa, gdy synchronizacje są włączone (zgodnie z tym linkiem )

Więc jako następny krok ustawiam następujące w 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

Następnie skonfigurowałem test czasu odpowiedzi, uruchomiłem sysctl -pi wyłączyłem synchronizację sysctl -w net.ipv4.tcp_syncookies=0.

Po wykonaniu tej czynności liczba połączeń w stanie SYN_RECV nadal pozostawała na poziomie około 220–250, ale połączenia zaczęły się ponownie opóźniać. Gdy zauważyłem te opóźnienia, ponownie włączyłem syncookie i opóźnienia ustały.

Wierzę, że to, co widziałem, wciąż poprawiało się od stanu początkowego, jednak niektóre żądania były nadal opóźnione, co jest znacznie gorsze niż włączenie synchronizacji. Wygląda na to, że utknąłem z nimi włączonymi, dopóki nie będziemy mogli uzyskać więcej serwerów online, aby poradzić sobie z obciążeniem. Nawet wtedy nie jestem pewien, czy widzę prawidłowy powód, aby je ponownie wyłączyć, ponieważ są one wysyłane (najwyraźniej), gdy bufory serwera się zapełniają.

Ale zaległości synchronizacji nie wydają się być pełne tylko ~ 250 połączeń w stanie SYN_RECV! Czy to możliwe, że komunikat zalewania SYN to czerwony śledź i wypełnia go coś innego niż syn_backlog?

Jeśli ktoś ma jakieś inne opcje dostrajania, których jeszcze nie wypróbowałem, chętnie je wypróbuję, ale zaczynam się zastanawiać, czy z jakiegoś powodu ustawienie syn_backlog nie jest właściwie stosowane.

Alex Forbes
źródło

Odpowiedzi:

27

To miłe pytanie.

Początkowo byłem zaskoczony, że widziałeś jakiekolwiek połączenia w stanie SYN_RECV z włączonymi plikami cookie SYN. Piękno plików cookie SYN polega na tym, że możesz bezpaństwowo uczestniczyć w potrójnym uzgadnianiu TCP jako serwer wykorzystujący kryptografię, więc oczekiwałbym, że serwer w ogóle nie będzie reprezentował półotwartych połączeń, ponieważ byłby to ten sam stan, który nie jest są trzymane.

W rzeczywistości szybki podgląd źródła (tcp_ipv4.c) pokazuje interesujące informacje o tym, jak jądro implementuje pliki cookie SYN. Zasadniczo, pomimo ich włączenia, jądro zachowuje się tak, jak zwykle, do momentu zapełnienia kolejki oczekujących połączeń. To wyjaśnia twoją istniejącą listę połączeń w stanie SYN_RECV.

Tylko gdy kolejka oczekujących połączeń jest pełna, OTRZYMANY jest kolejny pakiet SYN (próba połączenia) ORAZ minęła minuta od ostatniego komunikatu ostrzegawczego, jądro wysyła ostrzeżenie, które widziałeś („wysyłanie plików cookie” ). Pliki cookie SYN są wysyłane, nawet jeśli komunikat ostrzegawczy nie jest; komunikat ostrzegawczy ma na celu poinformowanie cię, że problem nie zniknął.

Innymi słowy, jeśli wyłączysz pliki cookie SYN, wiadomość zniknie. To zadziała tylko wtedy, gdy nie będziesz już zalany SYN.

Aby rozwiązać niektóre z innych rzeczy, które zrobiłeś:

  • net.ipv4.tcp_synack_retries:
    • Zwiększenie tej liczby nie przyniesie żadnego pozytywnego efektu dla połączeń przychodzących, które są sfałszowane, ani dla tych, które otrzymują ciasteczko SYN zamiast stanu po stronie serwera (nie ma też dla nich ponownych prób).
    • W przypadku przychodzących sfałszowanych połączeń zwiększenie to zwiększa liczbę pakietów wysyłanych na fałszywy adres i prawdopodobnie czas, przez jaki ten sfałszowany adres pozostaje w tabeli połączeń (może to być znaczący negatywny efekt).
    • Przy normalnym obciążeniu / liczbie połączeń przychodzących, im wyższa, tym większe prawdopodobieństwo, że szybko / pomyślnie wykonasz połączenia za pośrednictwem łączy odrzucających pakiety. Zwiększenie tej kwoty maleje.
  • net.ipv4.tcp_syn_retries: Zmiana tego nie może mieć żadnego wpływu na połączenia przychodzące (dotyczy tylko połączeń wychodzących)

Inne zmienne, o których wspomniałeś, których nie badałem, ale podejrzewam, że odpowiedzi na twoje pytanie znajdują się tutaj.

Jeśli nie jesteś zalany SYN, a urządzenie reaguje na połączenia nie HTTP (np. SSH), myślę, że prawdopodobnie występuje problem z siecią i powinieneś poprosić inżyniera sieci o pomoc w rozwiązaniu problemu. Jeśli maszyna ogólnie nie reaguje, nawet jeśli nie zalewany jest SYN, brzmi to jak poważny problem z obciążeniem, jeśli wpływa na tworzenie połączeń TCP (dość niski poziom i niewystarczające zasoby)

Slartibartfast
źródło
Dzięki - to ciekawa i pouczająca odpowiedź. Z pewnością odpowiada na moje pytanie dotyczące związku między połączeniami w stanie SYN_RECV a wysyłaniem plików cookie. Maszyna reagowała na nie HTTP, w tym SSH i HTTPS, które otrzymują znacznie mniejszy ruch niż HTTP. Dlatego zdecydowaliśmy, że należy zmniejszyć ruch.
Alex Forbes,
Jeśli chodzi o poproszenie inżyniera sieci - dobra sugestia, ale przeprowadzamy migrację z tego centrum danych, więc prawdopodobnie nie warto, gdy wprowadzimy kilka nowych serwerów online gdzie indziej. Myślę, że masz rację, ponieważ jest to problem z siecią - być może problem z modułem równoważenia obciążenia lub zaporą ogniową. Jeszcze raz dziękuję za wgląd!
Alex Forbes,
13

Napotkałem dokładnie ten sam problem podczas nowej instalacji Ubuntu Oneiric 11.10 z serwerem WWW (apache2) z mocno obciążoną stroną internetową. Na Ubuntu Oneiric 11.10 synchronizacje były domyślnie włączone.

Miałem te same komunikaty jądra informujące o możliwym ataku powodziowym SYN na port serwera WWW:

jądro: [739408.882650] TCP: Możliwe zalanie SYN na porcie 80. Wysyłanie plików cookie.

Jednocześnie byłem całkiem pewien, że nie doszło do ataku. Miałem te wiadomości powracające co 5 minut. Wydawało się to podobne do podglądu obciążenia, ponieważ osoba atakująca utrzymywałaby obciążenie przez cały czas, próbując sprawić, aby serwer przestał odpowiadać na żądania.

Strojenie net.ipv4.tcp_max_syn_backlogparametru nie spowodowało żadnej poprawy - komunikaty były kontynuowane w tym samym tempie. fakt, że liczba połączeń SYN_RECV była zawsze bardzo niska (w moim przypadku poniżej 250) była wskaźnikiem, że musi istnieć jakiś inny parametr, który jest odpowiedzialny za ten komunikat.

Znalazłem ten komunikat o błędzie https://bugzilla.redhat.com/show_bug.cgi?id=734991 na stronie red hat stwierdzający, że komunikat jądra może być wynikiem błędu (lub błędnej konfiguracji) po stronie aplikacji . Oczywiście komunikat w dzienniku jest bardzo mylący! Ponieważ w tym przypadku nie jest to parametr jądra, ale parametr aplikacji, przekazany do jądra.

Powinniśmy więc również przyjrzeć się parametrom konfiguracyjnym naszej aplikacji serwera WWW. Chwyć dokumenty apache i przejdź do http://httpd.apache.org/docs/2.0/mod/mpm_common.html#listenbacklog

Domyślna wartość ListenBacklogparametru to 511. (Odpowiada to liczbie połączeń zaobserwowanych na serwerze Red Hat. Twój inny serwer może mieć skonfigurowaną niższą liczbę).

Apache ma własny parametr konfiguracyjny dla kolejki zaległości dla połączeń przychodzących. jeśli masz dużo połączeń przychodzących i w dowolnym momencie (przypadkowo) docierają one do siebie prawie w tym samym czasie, tak że serwer sieciowy nie jest w stanie obsłużyć ich wystarczająco szybko w odpowiedni sposób, twój zaległości będą zapełnij się połączeniami 511, a jądro uruchomi powyższy komunikat informujący o możliwym ataku powodziowym SYN.

Aby rozwiązać ten problem, dodaję następujący wiersz /etc/apache2/ports.conflub jeden z pozostałych plików .conf, które zostaną załadowane przez apache ( /etc/apache2/apache2.confpowinno być również w porządku):

ListenBackLog 5000

powinieneś również ustawić net.ipv4.tcp_max_syn_backlogrozsądną wartość. w moim rozumieniu maksimum jądra ograniczy wartość, którą będzie można skonfigurować w konfiguracji apache. więc uruchom:

sudo sysctl -w net.ipv4.tcp_max_syn_backlog=5000

Po dostrojeniu konfiguracji nie zapomnij zrestartować apache:

sudo service apache2 restart ( or sudo /etc/init.d/apache2 restart )

W moim przypadku ta zmiana konfiguracji natychmiast zatrzymała ostrzeżenia jądra. Jestem w stanie odtworzyć wiadomości, ustawiając niską wartość ListenBackLog w konfiguracji apache.

Jeff
źródło
2
Świetna odpowiedź. Zakładając, że to, co mówisz, jest poprawne, oznaczę to jako zaakceptowaną odpowiedź, ale tak naprawdę nie mogę jej przetestować - zmniejszenie obciążenia rozwiązało problem i mam politykę nie majstrowania przy serwerach produkcyjnych bez dobrego powodu :)
Alex Forbes
Mogę potwierdzić, że to działa w zasadzie jest to funkcja anty-DDOS jądra, ale kiedy otrzymujesz powiedzieć, że duży ruch w sieci blokuje twoich legalnych użytkowników!
Areeb Soo Yasir
5

Po kilku testach z jądrem 3.4.9 liczba połączeń SYN_RECV w netstat zależy od

  • /proc/sys/net/core/somaxconn zaokrąglona w górę do następnej potęgi 2 (np. 128 -> 256)
  • 75% z /proc/sys/net/ipv4/tcp_max_syn_backlogif /proc/sys/net/ipv4/tcp_syncookiesjest ustawione na 0lub 100% jeśli /proc/sys/net/ipv4/tcp_syncookiesjest ustawione na1
  • ListenBackLog w konfiguracji apache zaokrąglonej w górę do następnej potęgi 2 (np. 128 -> 256)

użyto minimum każdego z tych parametrów. Po zmianie somaxconn lub ListenBackLog należy ponownie uruchomić apache.

Po zwiększeniu tcp_max_syn_backlog należy ponownie uruchomić apache.

Bez tcp_syncookies apache blokuje się, dlatego w tym przypadku tylko 75% tcp_max_syn_backlog jest dziwne. a zwiększenie tego parametru zwiększa połączenia SYN_RECV do 100% starej wartości bez restartowania apache.

usoft
źródło
A także wywołanie /bin/echo m >/proc/sysrq-triggerczęsto prowadzi do możliwego zalania SYN na porcie 80. Wysyłanie wiadomości cookie .
usoft