Каковы последствия установки для tcp_tw_recycle/reuse значения 1?
Я установил оба параметра tcp_tw_recycle/reuse на 1 в моем файле конфигурации.
Каковы последствия этого?
Если tcp-сокет используется повторно, это создает угрозу безопасности? то есть 2 разных соединения, оба потенциально могут отправлять данные?
Подходит ли это для кратковременных соединений с небольшим шансом переподключения?
3 ответа
По умолчанию, когда оба 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
, Я согласен:-)
Я только что это укусил меня, так что, возможно, кто-то может извлечь выгоду из моей боли и страданий. Во-первых, вовлеченная ссылка с большим количеством информации: 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, иногда здесь и там, а иногда в течение длительных периодов. Опять случайно.
Короткий рассказ здесь, в моем недавнем, болезненном опыте: оставьте их в покое / отключено на общедоступных серверах, независимо от роли!
От '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.
Там не так много помощи. У этого вопроса также есть хорошее понимание:
https://stackoverflow.com/questions/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.