Недавно у нас был сервер apache, который очень медленно отвечал из-за переполнения SYN. Обходным путем для этого было включение tcp_syncookies (net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf
).
Я разместил вопрос об этом Вот если вы хотите больше фона.
После включения syncookies мы начали видеть следующее сообщение в / var / log / messages примерно каждые 60 секунд:
[84440.731929] possible SYN flooding on port 80. Sending cookies.
Винко Врсалович сообщил мне, что это означает, что backlog синхронизации заполняется, поэтому я поднял tcp_max_syn_backlog до 4096. В какой-то момент я также снизил tcp_synack_retries до 3 (по умолчанию 5), выполнив sysctl -w net.ipv4.tcp_synack_retries=3
. После этого частота, казалось, упала, а интервал сообщений варьировался от 60 до 180 секунд.
Далее я выдал sysctl -w net.ipv4.tcp_max_syn_backlog=65536
, но я все еще получаю сообщение в журнале.
На протяжении всего этого я наблюдал за количеством соединений в состоянии SYN_RECV (запустив watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'
), и он никогда не превышает 240, что намного меньше размера невыполненной работы. Тем не менее, у меня есть сервер Red Hat, который колеблется около 512 (ограничение на этом сервере по умолчанию 1024).
Существуют ли какие-либо другие настройки tcp, которые ограничивают размер невыполненной работы, или я лаяю не на то дерево? Если количество соединений SYN_RECV в netstat -tuna
соотносятся с размером отставания?
Насколько я могу судить, здесь я имею дело с законными связями, netstat -tuna|wc -l
колеблется около 5000. Я исследовал это сегодня и обнаружил эта почта от сотрудника last.fm, что оказалось весьма полезным.
Я также обнаружил, что tcp_max_syn_backlog не действует, если включены файлы cookie (согласно эта ссылка)
Итак, следующим шагом я установил в 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
Затем я настроил тест времени отклика, запустил sysctl -p
и отключил файлы cookie sysctl -w net.ipv4.tcp_syncookies=0
.
После этого количество соединений в состоянии SYN_RECV по-прежнему оставалось на уровне 220-250, но соединения снова начинали задерживаться. Как только я заметил эти задержки, я снова включил файлы cookie, и задержки прекратились.
Я считаю, что то, что я видел, было улучшением по сравнению с начальным состоянием, однако некоторые запросы все еще задерживались, что намного хуже, чем включение синхронных файлов cookie. Так что, похоже, я застрял с их включением, пока мы не сможем подключить еще несколько серверов, чтобы справиться с нагрузкой. Даже в этом случае я не уверен, что вижу вескую причину для их повторного отключения, поскольку они отправляются (по-видимому) только тогда, когда буферы сервера заполняются.
Но backlog синхронизации, похоже, не заполнен только ~ 250 подключениями в состоянии SYN_RECV! Возможно ли, что сообщение о наводнении SYN является отвлекающим маневром и заполняется чем-то другим, кроме syn_backlog?
Если у кого-то есть какие-либо другие параметры настройки, которые я еще не пробовал, я был бы более чем счастлив попробовать их, но я начинаю задаваться вопросом, не применяется ли параметр syn_backlog должным образом по какой-либо причине.
Итак, это интересный вопрос.
Изначально меня удивило, что вы увидели любой соединения в состоянии SYN_RECV с включенными файлами cookie SYN. Прелесть файлов cookie SYN заключается в том, что вы можете без сохранения состояния участвовать в трехстороннем рукопожатии TCP в качестве сервера, использующего криптографию, поэтому я ожидаю, что сервер вообще не будет представлять полуоткрытые соединения, потому что это будет то же состояние, что и не не удерживается.
Фактически, беглый взгляд на источник (tcp_ipv4.c) показывает интересную информацию о том, как ядро реализует файлы cookie SYN. По сути, несмотря на их включение, ядро ведет себя как обычно, пока его очередь ожидающих соединений не заполнится. Это объясняет ваш существующий список соединений в состоянии SYN_RECV.
Только когда очередь ожидающих подключений заполнена, И получен другой SYN-пакет (попытка подключения), И с момента последнего предупреждающего сообщения прошло больше минуты, ядро отправляет предупреждение, которое вы видели («отправка файлов cookie» ). Файлы cookie SYN отправляются, даже если предупреждающего сообщения нет; предупреждающее сообщение предназначено только для того, чтобы предупредить вас о том, что проблема не исчезла.
Другими словами, если вы отключите файлы cookie SYN, сообщение исчезнет. Это сработает для вас только в том случае, если вас больше не будет лавировать SYN.
Чтобы решить некоторые другие дела, которые вы уже сделали:
net.ipv4.tcp_synack_retries
: net.ipv4.tcp_syn_retries
: Изменение этого параметра не может повлиять на входящие соединения (влияет только на исходящие соединения)Другие упомянутые вами переменные я не исследовал, но подозреваю, что ответы на ваш вопрос в значительной степени прямо здесь.
Если у вас нет SYN-лавинной рассылки и машина реагирует на соединения, отличные от HTTP (например, SSH), я думаю, что, вероятно, возникла проблема с сетью, и вам нужен сетевой инженер, который поможет вам разобраться в ней. Если машина обычно не отвечает, даже если вы не залиты SYN, это звучит как серьезная проблема с загрузкой, если она влияет на создание TCP-соединений (довольно низкий уровень и не требует больших ресурсов)
Я столкнулся с точно такой же проблемой при новой установке Ubuntu Oneiric 11.10 с запущенным веб-сервером (apache2) с сильно загруженным веб-сайтом. В Ubuntu Oneiric 11.10 синхронные файлы cookie были включены по умолчанию.
У меня были те же сообщения ядра, в которых говорилось о возможной атаке SYN-флуда на порт веб-сервера:
ядро: [739408.882650] TCP: Возможное лавинное рассылание SYN на порт 80. Отправка файлов cookie.
В то же время я был почти уверен, что нападения не было. Эти сообщения возвращались с интервалом в 5 минут. Это было похоже на просмотр нагрузки, потому что злоумышленник будет постоянно поддерживать высокую нагрузку, пытаясь заставить сервер перестать отвечать на запросы.
Настройка net.ipv4.tcp_max_syn_backlog
параметр не привел к улучшению - сообщения продолжались с той же скоростью. тот факт, что количество соединений SYN_RECV всегда было очень низким (в моем случае менее 250), был индикатором того, что должен быть какой-то другой параметр, который отвечает за это сообщение.
Я нашел это сообщение об ошибке https://bugzilla.redhat.com/show_bug.cgi?id=734991 на сайте с красной шляпой, где говорится, что сообщение ядра могло быть результатом ошибки (или неправильной конфигурации) на стороне приложения. Конечно, сообщение журнала вводит в заблуждение! Поскольку в этом случае отвечает не параметр ядра, а параметр вашего приложения, передаваемый ядру.
Поэтому нам также следует взглянуть на параметры конфигурации нашего приложения веб-сервера. Возьмите документы apache и перейдите в http://httpd.apache.org/docs/2.0/mod/mpm_common.html#listenbacklog
Значение по умолчанию ListenBacklog
параметр - 511. (Это соответствует количеству подключений, которые вы наблюдали на своем сервере Red Hat. Возможно, на вашем другом сервере настроено меньшее число.)
Apache имеет собственный параметр конфигурации для очереди невыполненных работ для входящих подключений. если у вас много входящих подключений, и в любой момент (как раз случайным образом) они прибывают все вместе почти одновременно, так что веб-сервер не может обслуживать их достаточно быстро надлежащим образом, ваш бэклог будет будет заполнено 511 соединений, и ядро выдаст вышеуказанное сообщение о возможной атаке SYN flood.
Чтобы решить эту проблему, я добавляю следующую строку в /etc/apache2/ports.conf
или один из других файлов .conf, который будет загружен apache (/etc/apache2/apache2.conf
тоже должно быть хорошо):
ListenBackLog 5000
вы также должны установить net.ipv4.tcp_max_syn_backlog
по разумной цене. Насколько я понимаю, максимум ядра ограничивает значение, которое вы сможете настроить в конфигурации apache. так что беги:
sudo sysctl -w net.ipv4.tcp_max_syn_backlog=5000
После настройки конфигурации не забудьте перезапустить apache:
sudo service apache2 restart ( or sudo /etc/init.d/apache2 restart )
В моем случае это изменение конфигурации немедленно остановило предупреждения ядра. Я могу воспроизвести сообщения, установив низкое значение ListenBackLog в конфигурации apache.
После некоторых тестов с ядром 3.4.9 количество соединений SYN_RECV в netstat зависит от
/proc/sys/net/core/somaxconn
округляется до следующей степени 2 (например, 128 -> 256)/proc/sys/net/ipv4/tcp_max_syn_backlog
если /proc/sys/net/ipv4/tcp_syncookies
установлен на 0
или 100%, если /proc/sys/net/ipv4/tcp_syncookies
установлен на 1
ListenBackLog
в конфигурации apache с округлением до следующей степени 2 (например, 128 -> 256)используется минимум каждого из этих параметров. После изменения somaxconn или ListenBackLog необходимо перезапустить apache.
И после увеличения tcp_max_syn_backlog необходимо перезапустить apache.
Без tcp_syncookies apache блокирует, почему в этом случае только 75% tcp_max_syn_backlog является пределом, странно. и увеличение этого параметра увеличивает количество соединений SYN_RECV до 100% от старого значения без перезапуска apache.