Почему сервер не отправляет пакет SYN / ACK в ответ на пакет SYN


46

В последнее время нам стало известно о проблеме TCP-соединения, которая в основном ограничена пользователями Mac и Linux, которые просматривают наши веб-сайты.

С точки зрения пользователя, это очень длительное время подключения к нашим веб-сайтам (> 11 секунд).

Нам удалось отследить техническую сигнатуру этой проблемы, но мы не можем понять, почему это происходит или как ее исправить.

По сути, происходит то, что клиентский компьютер отправляет пакет SYN для установления соединения TCP, а веб-сервер получает его, но не отвечает пакетом SYN / ACK. После того, как клиент отправил много пакетов SYN, сервер наконец отвечает пакетом SYN / ACK, и все в порядке для оставшейся части соединения.

И, конечно, кикер к проблеме: она прерывистая и не происходит все время (хотя это случается между 10-30% времени)

Мы используем Fedora 12 Linux в качестве операционной системы и Nginx в качестве веб-сервера.

Снимок экрана анализа проволочной акулы

Снимок экрана анализа проволочной акулы

Обновить:

Отключение масштабирования окна на клиенте остановило проблему. Теперь мне просто нужно разрешение на стороне сервера (мы не можем заставить всех клиентов делать это) :)

Окончательное обновление:

Решение было отключить как TCP масштабирования окна и TCP временные метки на наших серверах, которые доступны для общественности.


1
Я думаю, нам нужно будет увидеть, как это происходит.
coredump

Есть ли у вас какие-либо acls или правила, основанные на обратном DNS? Возможно, вам придется взглянуть не только на связь между клиентом и сервером. Возможно, поиск DNS истекает?
Зоредаче

@coredump: вот снимок экрана анализа wireshark, в котором показана проблема i.imgur.com/Bnzrm.png (не удалось выяснить, как экспортировать только поток ....)
codemonkey

@Zoredache: нет, у нас нет acls или правил, основанных на обратном DNS. Это общедоступный веб-сервер, и мы разрешаем всем доступ к нему
codemonkey

Просто догадка, но вы делаете какие-либо ограничения скорости входящих соединений на сервере? Скажите, с iptables?
Стивен Понедельник,

Ответы:


15

У нас была точно такая же проблема. Простое отключение меток времени TCP решило проблему.

sysctl -w net.ipv4.tcp_timestamps=0

Чтобы сделать это изменение постоянным, сделайте запись в /etc/sysctl.conf.

Будьте очень осторожны при отключении опции TCP Window Scale. Эта опция важна для обеспечения максимальной производительности через Интернет. У кого-то с соединением 10 мегабит / сек будет субоптимальная передача, если время прохождения сигнала туда и обратно (в основном такое же, как пинг) больше 55 мс.

Мы действительно заметили эту проблему, когда за одним и тем же NAT было несколько устройств. Я подозреваю, что сервер мог быть сбит с толку, увидев временные метки с устройств Android и компьютеров OSX одновременно, так как они помещали совершенно разные значения в поля временных меток.


4
В случае, если кто-то еще окажется здесь через ту же кроличью нору, что я только что прошел: перед отключением временных меток TCP или масштабированием окна, что может иметь серьезные последствия для производительности на канале с высоким трафиком, проверьте, не является ли ваша проблема tcp_tw_recycle: stackoverflow .com / questions / 8893888 /…
nephtes

12

В моем случае следующая команда устранила проблему с отсутствующими ответами SYN / ACK с сервера Linux:

sysctl -w net.ipv4.tcp_tw_recycle=0

Я думаю, что это более правильно, чем отключение временных меток TCP, поскольку временные метки TCP полезны для высокой производительности (PAWS, масштабирование окна и т. Д.).

В документации tcp_tw_recycleявно указывается, что не рекомендуется включать ее, так как многие маршрутизаторы NAT сохраняют временные метки и, следовательно, запускается PAWS, поскольку временные метки с одного и того же IP не согласованы.

   tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
          Enable fast recycling of TIME_WAIT sockets.  Enabling this
          option is not recommended for devices communicating with the
          general Internet or using NAT (Network Address Translation).
          Since some NAT gateways pass through IP timestamp values, one
          IP can appear to have non-increasing timestamps.  See RFC 1323
          (PAWS), RFC 6191.

1
Хорошее объяснение здесь: vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux На стороне сервера не включайте net.ipv4.tcp_tw_recycle, если вы не уверены, что у вас никогда не будет устройств NAT в смеси.
Gnought

1
В моем случае net.ipv4.tcp_tw_recycleэто настоящая причина. Благодарю.
bluearrow

tcp_tw_recycle был удален в последних ядрах. Есть ли другое решение? @nephtes подразумевает, что отключение метки времени снижает производительность.
MappaM

Так как tcp_tw_recycle был удален, проблема не должна возникать снова, поскольку это произошло только со значением не по умолчанию tcp_tw_recycle.
лавы

5

Просто интересно, но почему для пакета SYN (кадр # 539; тот, который был принят) поля WS и TSV отсутствуют в столбце «Информация»?

WS - масштабирование окна TCP, а TSV - значение метки времени . Оба они находятся в поле tcp.options, и Wireshark по-прежнему должен показывать их, если они присутствуют. Возможно, клиентский стек TCP / IP повторно отправляет другой пакет SYN при 8-й попытке, и по этой причине он неожиданно был подтвержден?

Не могли бы вы предоставить нам рамку 539 внутренних ценностей? Всегда ли SYN / ACK приходит для пакета SYN, для которого не включен WS?


@Ansis: вот некоторые снимки экрана для кадра 539 деталей (должен был сделать это в двух частях): i.imgur.com/D84GC.png & i.imgur.com/4riq3.png
codemonkey

@codemonkey: ваш 8-й пакет SYN, похоже, отличается от первых семи пакетов SYN. Отвечает ли сервер с SYN / ACK на SYN клиента, только если поле tcp.options имеет размер 8 байтов (первые семь пакетов SYN, вероятно, имеют tcp.options размера 20 байтов.)? Можете ли вы отключить масштабирование окна TCP на стороне клиента, чтобы увидеть, исчезнет ли проблема? Похоже, проблема со стеком TCP / IP на стороне сервера или неправильной настройкой брандмауэра где-то ...
Ханс Соло

@Ansis: да, я смотрю на это с тех пор, как вы на это указали, а все остальные пакеты SYN занимают 24 байта. Я попытаюсь отключить масштабирование окна на клиенте и проверю результаты утром.
codemonkey

@Ansis: отключение масштабирования окон на клиенте остановило проблему. Спасибо! Однако теперь мне нужно выяснить, как это исправить на стороне сервера (поскольку мы не можем заставить всех наших клиентов отключить масштабирование окон) :) На рассматриваемом сервере действительно есть net.ipv4.tcp_windows_scaling = 1
codemonkey

@Codemonkey: Я согласен, что отключение WS на всех клиентах не является решением, но мы, по крайней мере, отследили эту проблему до проблем с размером WS / Packet Size. Чтобы найти причину, мы должны посмотреть, как настроен ваш брандмауэр. Можно ли установить TCP-соединения с WS на разные TCP-порты? Из разных источников IP?
Ганс Соло

4

Мы только что столкнулись с той же самой проблемой (действительно, потребовалось много времени, чтобы прикрепить ее к серверу, не отправляющему syn-ack).

«Решением было отключить масштабирование tcp windows и tcp timestamp на наших серверах, которые доступны для общественности».


2

Чтобы продолжить то, что сказал Ansis, я видел такие проблемы, когда брандмауэр не поддерживает TCP Windows Scaling. Что такое межсетевой экран make / model между этими двумя хостами?


Брандмауэр - это коробка Fedora 13, использующая iptables. net.ipv4.tcp_windows_scaling устанавливается в 1 на этой машине также
codemonkey

2

Отсутствие SYN / ACK может быть вызвано слишком низкими пределами защиты SYNFLOOD на брандмауэре. Это зависит от того, сколько соединений с вашим сервером создает пользователь. Использование spdy уменьшит количество соединений и может помочь в ситуации, когда net.ipv4.tcp_timestampsотключение не помогает.


1

Это поведение прослушивающего сокета TCP, когда его резерв заполнен.

Ngnix позволяет прослушивать аргумент backlog в конфигурации: http://wiki.nginx.org/HttpCoreModule#listen

прослушать 80 отставание = число

Попробуйте установить для num нечто большее, чем значение по умолчанию, например 1024.

Я не даю никаких гарантий, что полная очередь прослушивания на самом деле является вашей проблемой, но это хорошее первое, что нужно проверить.


Спасибо за чаевые. Я это попробую. Мы установили отставание на уровне ОС, но не в явном виде в конфигурации Nginx. Я обновлю с результатом.
codemonkey

это не изменило поведение вообще. Угадай, это не проблема? или единственная проблема ...
codemonkey

1
Параметр backlog уровня приложения управляет размером очереди для завершенных соединений tcp, т. е. завершено 3-х стороннее рукопожатие, т.е. получен syn-ack - поэтому он не соответствует ситуации OP
ygrek

1

Я только что обнаружил, что клиенты Linux TCP меняют свой пакет SYN после 3 попыток и удаляют опцию масштабирования окна. Я думаю, разработчики ядра поняли, что это частая причина сбоя соединения в интернете.

Это объясняет, почему этим клиентам удается подключиться через 11 секунд (в моем кратком тесте с настройками по умолчанию через 9 секунд произойдет TCP-SYN без окон)


0

У меня была похожая проблема, но в моем случае это была контрольная сумма TCP, которая была неправильно рассчитана. Клиент был за веткой, а запуск ethtool -K veth0 rx off tx off сделал свое дело.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.