Каковы последствия установки tcp_tw_recycle / reuse в 1?

10

Я установил оба параметра tcp_tw_recycle / reuse на 1 в моем файле конфигурации.

Каковы последствия этого?

Если tcp-сокет используется повторно, это создает угрозу безопасности? то есть 2 разных соединения, оба потенциально могут отправлять данные?

Подходит ли это для кратковременных соединений с небольшой вероятностью переподключения?

codecompleting
источник
Очевидный вопрос: что вы ожидаете получить от этого изменения?
Роберт Мунтяну
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пакет будет автоматически отброшен, и соединение не будет установлено (вы увидите ошибку, похожую на «время ожидания соединения»). Если вы хотите погрузиться в код ядра, определение tcp_timewait_state_process может быть хорошей отправной точкой.

Теперь метки времени никогда не должны возвращаться во времени; если:

  • хост перезагружается (но к тому времени, когда он возвращается, TIME_WAITсокет, вероятно, истек, так что это не проблема);
  • IP-адрес быстро повторно используется чем-то другим ( TIME_WAITсоединения останутся немного, но другие соединения, вероятно, будут сбиты, TCP RSTи это освободит некоторое пространство);
  • Трансляция сетевых адресов (или брандмауэр Smarty-Tants) участвует в середине соединения.

В последнем случае вы можете иметь несколько хостов за одним и тем же IP-адресом, и, следовательно, разные последовательности временных меток (или указанные временные метки рандомизируются при каждом соединении межсетевым экраном). В этом случае некоторые хосты не смогут случайным образом подключиться, поскольку они сопоставлены с портом, для которого TIME_WAITсегмент сервера имеет более новую временную метку. Вот почему в документах говорится, что «устройства NAT или балансировщики нагрузки могут начать отбрасывать кадры из-за настроек».

Некоторые люди рекомендуют оставить в tcp_tw_recycleпокое, но включить tcp_tw_reuseи опуститьtcp_timewait_len . Я согласен :-)

jpetazzo
источник
отличное объяснение
янки
6

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

В частности:

Простой результат этого отсутствия документации состоит в том, что мы находим многочисленные руководства по настройке, советующие установить обе эти настройки на 1, чтобы уменьшить количество записей в состоянии TIME-WAIT. Однако, как указано на странице руководства tcp (7), опция net.ipv4.tcp_tw_recycle довольно проблематична для общедоступных серверов, поскольку она не будет обрабатывать соединения от двух разных компьютеров за одним и тем же устройством NAT, что является проблемой, которую трудно решить. обнаружить и ждать, чтобы укусить вас:

Я использовал их достаточно успешно, чтобы обеспечить как можно более низкую задержку, соединение haproxy от клиентов к кластеру MySql NDB. Это было в частном облаке, и никакие соединения от любого к любому не имели никакого вида 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.
SpamapS
источник
1
Вы уверены, что SO_REUSEADDRэто связано с tcp_tw_reuse? Насколько я знаю, SO_REUSEADDRприменяется только тогда, когда вы хотите bind(), в то время tcp_tw_reuseкак ядро ​​будет указывать повторно использовать порт локального сокета в TIME_WAITсостоянии, если ему необходимо создать новое исходящее соединение.
jpetazzo
Нет, я не уверен. :-P
SpamapS