Які наслідки встановлення tcp_tw_recycle / повторного використання до 1?


10

Я встановив як tcp_tw_recycle / повторне використання у своєму файлі конфігурації.

Які наслідки цього робити?

Якщо розетка tcp буде повторно використана, чи несе це ризик для безпеки? тобто два різних з'єднання, при цьому потенційно в змозі надсилати дані?

Чи підходить він для короткочасних зв’язків з можливістю відновлення з'єднання?


Очевидне питання: що ви очікуєте від цієї зміни?
Роберт Мунтяну

1
@RobertMunteanu пов’язаний із: serverfault.com/questions/342501/…
завершення коду

Відповіді:


24

За замовчуванням, коли обидва tcp_tw_reuseі tcp_tw_recycleвідключені, ядро ​​переконається, що сокети в TIME_WAITстані залишаться в цьому стані досить довго - досить довго, щоб бути впевненим, що пакети, що належать до майбутніх з'єднань, не будуть помилятися з пізніми пакетами старого з'єднання.

Коли ви ввімкнете tcp_tw_reuse, сокети в TIME_WAITстані можна використовувати до їх закінчення, і ядро ​​спробує переконатися у відсутності зіткнення щодо номерів послідовностей TCP. Якщо ви включите tcp_timestamps(він же PAWS, для захисту від загорнутих послідовних номерів), це переконається, що цих зіткнень не може відбутися. Однак вам потрібно включити часові позначки TCP з обох кінців (принаймні, це я розумію). Дивіться визначення tcp_twsk_unique для деталей горі.

Коли ви ввімкнете tcp_tw_recycle, ядро ​​стає набагато більш агресивним і зробить припущення щодо часових позначок, які використовуються віддаленими хостами. Він буде відслідковувати останню часову позначку, яку використовує кожен віддалений хост, який має з'єднання у TIME_WAITстані), і дозволить повторно використовувати сокет, якщо часова мітка правильно збільшена. Однак якщо часова мітка, використовувана хостом, зміниться (тобто повертається назад у часі), SYNпакет буде мовчки відкинутий, а з'єднання не встановиться (ви побачите помилку, подібну до "timeout time"). Якщо ви хочете зануритися в код ядра, визначення tcp_timewait_state_process може стати хорошою відправною точкою.

Тепер часові позначки ніколи не повинні повертатися у часі; якщо:

  • хост перезавантажується (але тоді, до моменту його повернення, TIME_WAITсокет, ймовірно, закінчився, тому це не буде проблемою);
  • IP-адресу швидко використовуватимуть щось інше ( TIME_WAITз’єднання залишаться трохи, але, ймовірно, будуть вражені інші з'єднання, TCP RSTщо звільнить простір);
  • трансляція мережевої адреси (або брандмауер смарт-штанів) бере участь у середині з'єднання.

В останньому випадку ви можете мати кілька хостів за однією і тією ж IP-адресою, отже, різні послідовності часових міток (або, згадані часові позначки рандомізовані при кожному з'єднанні між брандмауером). У такому випадку деякі хости випадково не зможуть підключитися, оскільки вони відображаються до порту, для якого TIME_WAITвідро сервера має новішу часову позначку. Ось чому документи говорять вам, що "NAT пристрої або балансири завантаження можуть запускати кадри через налаштування".

Деякі люди рекомендують залишити в tcp_tw_recycleспокої, але включити tcp_tw_reuseта опуститиtcp_timewait_len . Я погоджуюсь :-)


чудове пояснення
yanglei

6

Я просто перекусив мене, тому, можливо, хтось може отримати користь від мого болю і страждань. По-перше, пов'язане посилання із великою кількістю інформації: http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html

Зокрема:

Простий результат цього браку документації полягає в тому, що ми знаходимо численні посібники з налаштування, що радить встановити обидва ці налаштування на 1, щоб зменшити кількість записів у режимі ЧАС-ЗАЧЕКАЙТЕ. Однак, як зазначено на сторінці керівництва tcp (7), параметр net.ipv4.tcp_tw_recycle є досить проблематичним для публічних серверів, оскільки він не буде обробляти з'єднання двох різних комп’ютерів за одним і тим же пристроєм NAT, що є важкою проблемою виявити і чекати, коли вас вкусить:

Я використовував такі можливості, які досить швидко ввімкнули можливість забезпечити якомога меншу затримку, гапроксі-з'єднання від клієнтів до кластера NDB MySql. Це було в приватній хмарі, і жодних зв’язків від будь-якого до будь-якого не було NAT в суміші. Випадок використання має сенс - максимально знизити затримку для радіусних клієнтів, які потрапляють на NDB через haproxy, наскільки це можливо по-людськи. Це так і робилося.

Знову я це зробив у загальнодоступній системі haproxy, завантажуючи баланс веб-трафіку, не вивчаючи дійсно вплив (німий, правда ?!) і виявив після багатьох проблем з усунення несправностей та переслідування привидів, що:

  • Це створить хаос для клієнтів, що підключаються через NAT.
  • Ідентифікувати це майже неможливо, оскільки це абсолютно випадковий, переривчастий характер, і симптоми будуть вражати клієнта A, у зовсім інші (або ні) часи, ніж клієнт B тощо.

З боку замовника вони побачать періоди часу, коли вони більше не отримують відповіді на пакети SYN, іноді тут і там, а іноді протягом тривалих періодів. Знову випадково.

Коротка історія тут, в моєму недавньому, болісному досвіді, залишає їх у спокої / відключених на загальнодоступних серверах, незалежно від ролі!


4

Від 'man 7 tcp' Ви побачите це:

   tcp_tw_recycle (Boolean; default: disabled; since Linux 2.4)
          Enable fast recycling of TIME_WAIT sockets.  Enabling this option is not recommended since this causes problems when working with NAT
          (Network Address Translation).

   tcp_tw_reuse (Boolean; default: disabled; since Linux 2.4.19/2.6)
          Allow  to  reuse  TIME_WAIT  sockets  for  new connections when it is safe from protocol viewpoint.  It should not be changed without
          advice/request of technical experts.

Там не дуже допомагають. Цей вміст також має гарне розуміння:

/programming/6426253/tcp-tw-reuse-vs-tcp-tw-recycle-which-to-use-or-both

Але не конкретна інформація про те, чому повторне використання безпечніше, ніж переробляти. Основна відповідь полягає в тому, що tcp_tw_reuse дозволить користуватися тим самим сокетом, якщо в TIME_WAIT вже є той самий параметр TCP, і він знаходиться в стані, коли подальший трафік не очікується (я вважаю, що його було надіслано, коли було відправлено FIN ). tcp_tw_recycle, з іншого боку, просто повторно використовувати розетки, які знаходяться в TIME_WAIT, з тими ж параметрами незалежно від стану, що може сплутати потужні брандмауери, які можуть очікувати різних пакетів.

tcp_tw_reuse можна зробити вибірково в коді, встановивши опцію сокета SO_REUSEADDR, задокументовану man 7 socketтаким чином:

   SO_REUSEADDR
          Indicates that the rules used in validating addresses supplied in a bind(2) call should allow reuse of local addresses.  For  AF_INET
          sockets  this means that a socket may bind, except when there is an active listening socket bound to the address.  When the listening
          socket is bound to INADDR_ANY with a specific port then it is not possible to bind to this port for any local address.   Argument  is
          an integer boolean flag.

1
Ви впевнені, що SO_REUSEADDRце пов'язано з tcp_tw_reuse? Наскільки я знаю, це SO_REUSEADDRзастосовується лише тоді, коли ви цього хочете bind(), але tcp_tw_reuseвкаже ядро ​​повторно використовувати порт локального сокета у TIME_WAITстані, якщо йому потрібно створити нове вихідне з'єднання.
jpetazzo

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