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 -tuna
korelować 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 -l
widnieje 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 -p
i 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.
Odpowiedzi:
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
: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)
źródło
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:
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_backlog
parametru 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ść
ListenBacklog
parametru 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.conf
lub jeden z pozostałych plików .conf, które zostaną załadowane przez apache (/etc/apache2/apache2.conf
powinno być również w porządku):powinieneś również ustawić
net.ipv4.tcp_max_syn_backlog
rozsądną wartość. w moim rozumieniu maksimum jądra ograniczy wartość, którą będzie można skonfigurować w konfiguracji apache. więc uruchom:Po dostrojeniu konfiguracji nie zapomnij zrestartować apache:
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.
źródło
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)/proc/sys/net/ipv4/tcp_max_syn_backlog
if/proc/sys/net/ipv4/tcp_syncookies
jest ustawione na0
lub 100% jeśli/proc/sys/net/ipv4/tcp_syncookies
jest 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.
źródło
/bin/echo m >/proc/sysrq-trigger
często prowadzi do możliwego zalania SYN na porcie 80. Wysyłanie wiadomości cookie .