«Возможное переполнение SYN» в журнале, несмотря на небольшое количество соединений SYN_RECV

30

Недавно у нас был сервер 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.

Vinko Vrsalovic сообщил мне, что это означает, что synlog 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 не имеет никакого эффекта, когда включены синхронизаторы (по этой ссылке )

В качестве следующего шага я установил следующее в 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и отключил syncookies sysctl -w net.ipv4.tcp_syncookies=0.

После этого количество соединений в состоянии SYN_RECV по-прежнему оставалось около 220-250, но соединения снова начинали задерживаться. Как только я заметил эти задержки, я снова включил syncookies, и задержки прекратились.

Я считаю, что то, что я видел, все еще улучшало исходное состояние, однако некоторые запросы все еще задерживались, что намного хуже, чем включение syncookies. Похоже, я застрял с ними, пока мы не подключим еще несколько серверов, чтобы справиться с нагрузкой. Даже тогда, я не уверен, что вижу вескую причину, чтобы отключить их снова, поскольку они отправляются (очевидно), когда буферы сервера переполняются.

Но, похоже, что отставание в синхронизации не заполнено всего лишь ~ 250 соединениями в состоянии SYN_RECV! Возможно ли, что сообщение о затоплении SYN - это красная сельдь, а это не что иное, как syn_backlog, который заполняет?

Если у кого-то есть какие-либо другие параметры настройки, которые я еще не пробовал, я был бы более чем счастлив попробовать их, но я начинаю удивляться, если параметр syn_backlog по какой-то причине не применяется должным образом.

Алекс Форбс
источник
См. Соответствующий serverfault.com/questions/78820/dmesg-syn-flood-on-80-sysctl-p
Винко Врсалович,

Ответы:

27

Итак, это аккуратный вопрос.

Сначала я был удивлен тем, что вы видели какие-либо соединения в состоянии SYN_RECV с включенными файлами cookie SYN. Преимущество файлов cookie SYN заключается в том, что вы можете без участия государства участвовать в трехстороннем рукопожатии TCP в качестве сервера с использованием криптографии, поэтому я ожидаю, что сервер вообще не будет представлять полуоткрытые соединения, поскольку это будет то же состояние, что и не хранится

Фактически, быстрый взгляд на источник (tcp_ipv4.c) показывает интересную информацию о том, как ядро ​​реализует файлы cookie SYN. По сути, несмотря на их включение, ядро ​​ведет себя как обычно, пока его очередь ожидающих соединений не заполнится. Это объясняет ваш существующий список соединений в состоянии SYN_RECV.

Только когда очередь ожидающих подключений заполнена, и получен другой пакет SYN (попытка подключения), и прошло более минуты с момента последнего предупреждающего сообщения, ядро ​​отправляет сообщение с предупреждением, которое вы видели («отправка файлов cookie») ). SYN-куки отправляются, даже если предупреждающее сообщение отсутствует; предупреждающее сообщение просто для того, чтобы дать вам понять, что проблема не исчезла.

Другими словами, если вы отключите файлы cookie SYN, сообщение исчезнет. Это сработает только для вас, если вы больше не будете залиты SYN.

Для решения некоторых других вещей, которые вы сделали:

  • net.ipv4.tcp_synack_retries:
    • Увеличение этого значения не будет иметь положительного эффекта для тех входящих соединений, которые подделаны, а также для тех, которые получают файл cookie SYN вместо состояния на стороне сервера (повторных попыток для них тоже нет).
    • Для входящих поддельных соединений увеличение этого значения увеличивает количество пакетов, отправляемых на поддельный адрес, и, возможно, количество времени, которое этот поддельный адрес остается в вашей таблице соединений (это может быть существенным отрицательным эффектом).
    • При нормальной нагрузке / количестве входящих соединений, чем выше это значение, тем выше вероятность того, что вы быстро / успешно завершите соединения по ссылкам, которые отбрасывают пакеты. Есть уменьшающиеся доходы для увеличения этого.
  • net.ipv4.tcp_syn_retries: Изменение этого параметра не может повлиять на входящие подключения (это влияет только на исходящие подключения)

Другие переменные, о которых вы упоминаете, я не исследовал, но я подозреваю, что ответы на ваш вопрос в значительной степени прямо здесь.

Если вы не залили SYN, а машина реагирует на соединения, отличные от HTTP (например, SSH), я думаю, что, возможно, есть проблема с сетью, и у вас должен быть сетевой инженер, который поможет вам в этом разобраться. Если машина вообще не отвечает, даже если вы не залили SYN, это звучит как серьезная проблема загрузки, если она влияет на создание соединений TCP (довольно низкий уровень и не интенсивный ресурс)

Слартибартфаст
источник
Спасибо - это интересный и информативный ответ. Это, безусловно, отвечает на мой запрос о связи между соединениями в состоянии SYN_RECV и отправкой файлов cookie. Машина реагировала на не HTTP, включая SSH и HTTPS, который получает намного меньше трафика, чем HTTP. Таким образом, мы решили, что сокращение трафика - это путь.
Алекс Форбс
Что касается привлечения сетевого инженера, это хорошее предложение, но мы уходим от этого центра обработки данных, поэтому, вероятно, не стоит, когда мы подключаем пару новых серверов в другом месте. Я думаю, что вы, возможно, правы в том, что это проблема сети - возможно, проблема с балансировщиком нагрузки или брандмауэром. Еще раз спасибо за ваши идеи!
Алекс Форбс
13

Я столкнулся с точно такой же проблемой на новой установке Ubuntu Oneiric 11.10 с веб-сервером (apache2) с сильно загруженным веб-сайтом. В Ubuntu Oneiric 11.10 синхронизация была включена по умолчанию.

У меня были те же сообщения ядра о возможной атаке SYN-флуд на порт веб-сервера:

kernel: [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 на сайте Red Hat, в котором говорится, что сообщение ядра может быть результатом ошибки (или неправильной конфигурации) на стороне приложения. , Конечно, сообщение журнала очень вводит в заблуждение! Так как это не параметр ядра, который отвечает в этом случае, а параметр вашего приложения, передаваемый ядру.

Поэтому мы также должны взглянуть на параметры конфигурации нашего приложения веб-сервера. Захватите документы Apache и перейдите по ссылке http://httpd.apache.org/docs/2.0/mod/mpm_common.html#listenbacklog.

Значение по умолчанию для этого ListenBacklogпараметра - 511. (Это соответствует количеству соединений, которые вы наблюдали на своем сервере Red Hat. Возможно, на вашем другом сервере настроено меньшее число.)

Apache имеет собственный параметр конфигурации для очереди невыполненных работ для входящих соединений. если у вас много входящих соединений, и в любой момент (как случайные вещи) они приходят все вместе почти одновременно, так что веб-сервер не может обслуживать их достаточно быстро соответствующим образом, ваше отставание будет наполнитесь 511 соединениями, и ядро ​​запустит вышеприведенное сообщение о возможной атаке SYN-флуд.

Чтобы решить эту проблему, я добавляю следующую строку /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.

Джефф
источник
2
Отличный ответ. Предполагая, что вы говорите правильно, я бы пометил это как принятый ответ, но я не могу его проверить - снижение нагрузки решило проблему, и у меня есть политика не возиться с производственными серверами без уважительной причины :)
Алекс Форбс,
Я могу подтвердить, что это работает, по сути, это функция ядра против DDOS, однако, когда вы получаете, скажем, большое количество веб-трафика, это блокирует ваших законных пользователей!
Ариб Су Ясир
5

После некоторых тестов с ядром 3.4.9 количество соединений SYN_RECV в netstat зависит от

  • /proc/sys/net/core/somaxconn округляется до следующей степени 2 (например, 128 -> 256)
  • 75% /proc/sys/net/ipv4/tcp_max_syn_backlogif /proc/sys/net/ipv4/tcp_syncookiesустановлено на 0или 100% if /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.

usoft
источник
А также вызов /bin/echo m >/proc/sysrq-triggerчасто приводит к возможному переполнению SYN на порту 80. Отправка куки- сообщения.
usoft