Чому сервер не надсилає пакет SYN / ACK у відповідь на пакет SYN


46

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

З точки зору користувача, він представляє себе як дуже довгий час підключення до наших веб-сайтів (> 11 секунд).

Нам вдалося віднайти технічний підпис цієї проблеми, але не можемо з’ясувати, чому це відбувається або як його виправити.

В основному, що відбувається, це те, що машина клієнта відправляє пакет SYN для встановлення TCP-з'єднання і веб-сервер отримує його, але не відповідає з пакетом SYN / ACK. Після того, як клієнт надіслав багато SYN-пакетів, сервер нарешті реагує пакетом SYN / ACK, і все в порядку до кінця з'єднання.

І, звичайно, головна проблема: вона переривається і не відбувається весь час (хоча це відбувається між 10-30% часу)

Ми використовуємо Fedora 12 Linux як ОС та Nginx як веб-сервер.

Скріншот аналізу проводів

Скріншот аналізу проводів

Оновлення:

Якщо вимкнути масштабування вікон на клієнті, це зупинило ситуацію. Тепер мені просто потрібна роздільна здатність сервера (ми не можемо змусити всіх клієнтів це робити) :)

Остаточне оновлення:

Рішення полягало в тому, щоб вимкнути масштабування вікон TCP та часові позначки TCP на наших серверах, доступних для широкої публіки.


1
Я думаю, нам буде потрібно побачити деякий tcpdump цього.
coredump

Чи є у вас acls або правила, засновані на зворотному DNS? Можливо, вам доведеться розглянути більше, ніж просто з'єднання між клієнтом і сервером. Можливо, час пошуку DNS закінчується?
Зоредаче

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

@Zoredache: ні, у нас немає жодних acls або правил, заснованих на зворотному DNS. Це загальнодоступний веб-сервер, і ми дозволяємо всім отримати доступ до нього
codemonkey

Просто підказка, але чи робите ви якісь обмеження швидкості вхідного з'єднання на сервері? Скажіть, з iptables?
Стівен, понеділок,

Відповіді:


15

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

sysctl -w net.ipv4.tcp_timestamps=0

Щоб зробити цю зміну постійною, зробіть запис /etc/sysctl.conf.

Будьте дуже обережні щодо відключення параметра масштабу вікна TCP. Цей варіант важливий для забезпечення максимальної продуктивності через Інтернет. Хто - то з підключенням до 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 - значення Timestamp . Обидва вони знаходяться під полем 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 стеком на стороні сервера або неправильно налаштований брандмауер десь ...
Hans Solo

@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 та часові позначки tcp на наших серверах, доступних для громадськості."


2

Щоб продовжувати те, про що заявив Ansis, я бачив подібні проблеми, коли брандмауер не підтримує масштаб TCP Windows. Що між брандмауером та моделем між тими двома хостами?


Брандмауер - це поле Fedora 13 з використанням iptables. net.ipv4.tcp_windows_scaling встановлено на 1 також на цій машині
codemonkey

2

Відсутній SYN / ACK може бути викликаний занадто низькими межами захисту SYNFLOOD на брандмауері. Це залежить від того, скільки з'єднань із вашим сервером створює користувач. Використання spdy зменшило б кількість підключень і могло б допомогти в ситуації, коли net.ipv4.tcp_timestampsвідключення не допомагає.


1

Така поведінка прослуховуваного сокета TCP, коли його відставання заповнене.

Ngnix дозволяє прослуховувати аргумент відставання в конфігурації: http://wiki.nginx.org/HttpCoreModule#listen

прослухати 80 відставання = число

Спробуйте встановити num на щось більше, ніж за замовчуванням, наприклад 1024.

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


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

це зовсім не змінило поведінку. Вгадайте, це не проблема? або єдина проблема ...
codemonkey

1
Параметр відсталого рівня програми керує розміром черги для завершених підключень tcp, тобто завершено трехсторонне рукостискання, тобто отримано syn-ack - значить, це не відповідає ситуації з ОП
ygrek

1

Щойно я виявив, що клієнти Linux TCP змінюють свій SYN-пакет після 3-х спроб і видаляють вікно масштабування. Я думаю, що розробники ядра подумали, що це поширена причина збою підключення в Інтернеті

Це пояснює, чому цим клієнтам вдається підключитися через 11 секунд (без вікон TCP SYN відбувається через 9 секунд у моєму короткому тесті з налаштуваннями за замовчуванням)


0

У мене була подібна проблема, але в моєму випадку неправильно обчислена контрольна сума TCP. Клієнт був позаду veth і працює ettool -K veth0 rx off tx off зробив свою справу.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.