¿Cuáles son las ramificaciones de establecer tcp_tw_recycle / reuse en 1?

10

Configuré tcp_tw_recycle / reuse en 1 en mi archivo de configuración.

¿Cuáles son las ramificaciones de hacer esto?

Si se reutiliza un zócalo tcp, ¿representa un riesgo para la seguridad? es decir, 2 conexiones diferentes, ¿ambas pueden enviar datos?

¿Es adecuado para conexiones de corta duración con pocas posibilidades de reconexión?

código completo
fuente
La pregunta obvia es, ¿qué esperas ganar con este cambio?
Robert Munteanu
1
@RobertMunteanu relacionado con: serverfault.com/questions/342501/…
codecompleting

Respuestas:

24

Por defecto, cuando ambos tcp_tw_reusey tcp_tw_recycleestán desactivadas, el núcleo se asegurará de que las tomas en TIME_WAITestado permanecerán en ese estado el tiempo suficiente - el tiempo suficiente para asegurarse de que los paquetes que pertenecen a las conexiones futuras no ser confundido con fines de paquetes de la conexión antigua.

Cuando habilita tcp_tw_reuse, los sockets en TIME_WAITestado se pueden usar antes de que caduquen, y el núcleo intentará asegurarse de que no haya colisión con respecto a los números de secuencia TCP. Si habilita tcp_timestamps(también conocido como PAWS, para Protección contra números de secuencia envueltos), se asegurará de que esas colisiones no puedan ocurrir. Sin embargo, necesita que las marcas de tiempo TCP estén habilitadas en ambos extremos (al menos, eso entiendo). Vea la definición de tcp_twsk_unique para los detalles sangrientos.

Cuando habilita tcp_tw_recycle, el núcleo se vuelve mucho más agresivo y hará suposiciones sobre las marcas de tiempo utilizadas por los hosts remotos. Rastreará la última marca de tiempo utilizada por cada host remoto que tenga una conexión en TIME_WAITestado) y permitirá reutilizar un socket si la marca de tiempo ha aumentado correctamente. Sin embargo, si la marca de tiempo utilizada por el host cambia (es decir, se deforma en el tiempo), el SYNpaquete se descartará silenciosamente y la conexión no se establecerá (verá un error similar al "tiempo de espera de conexión"). Si desea sumergirse en el código del kernel, la definición de tcp_timewait_state_process podría ser un buen punto de partida.

Ahora, las marcas de tiempo nunca deben retroceder en el tiempo; a no ser que:

  • el host se reinicia (pero luego, cuando vuelva a funcionar, el TIME_WAITsocket probablemente haya expirado, por lo que no será un problema);
  • la dirección IP se reutiliza rápidamente por otra cosa (las TIME_WAITconexiones se mantendrán un poco, pero otras conexiones probablemente se activarán TCP RSTy eso liberará algo de espacio);
  • la traducción de la dirección de red (o un firewall de smarty-pants) está involucrada en el medio de la conexión.

En el último caso, puede tener varios hosts detrás de la misma dirección IP y, por lo tanto, diferentes secuencias de marcas de tiempo (o dichas marcas de tiempo se asignan al azar en cada conexión por el firewall). En ese caso, algunos hosts no podrán conectarse aleatoriamente, porque están asignados a un puerto para el cual el TIME_WAITdepósito del servidor tiene una marca de tiempo más nueva. Es por eso que los documentos le dicen que "los dispositivos NAT o los equilibradores de carga pueden comenzar a soltar cuadros debido a la configuración".

Algunas personas recomiendan dejarlo tcp_tw_recyclesolo, pero habilitan tcp_tw_reusey bajantcp_timewait_len . Estoy de acuerdo :-)

jpetazzo
fuente
gran explicación
yanglei
6

Acabo de tener esta mordedura, así que quizás alguien podría beneficiarse de mi dolor y sufrimiento. Primero, un enlace involucrado con mucha información: http://vincent.bernat.im/en/blog/2014-tcp-time-wait-state-linux.html

En particular:

El mero resultado de esta falta de documentación es que encontramos numerosas guías de ajuste que aconsejan establecer ambas configuraciones en 1 para reducir el número de entradas en el estado TIME-WAIT. Sin embargo, como se indica en la página del manual tcp (7), la opción net.ipv4.tcp_tw_recycle es bastante problemática para los servidores públicos, ya que no manejará conexiones desde dos computadoras diferentes detrás del mismo dispositivo NAT, lo cual es un problema difícil de manejar. detectar y esperar para morderte:

Solía ​​tenerlos habilitados con bastante éxito para proporcionar la menor latencia posible, conectividad haproxy de los clientes a un clúster MySql NDB. Esto estaba en una nube privada, y ninguna conexión de ninguna a ninguna tenía ningún tipo de NAT en la mezcla. El caso de uso tenía sentido, reducir la latencia para clientes de radio que golpean NDB a través de haproxy tanto como sea humanamente posible. Lo hizo asi.

Lo hice nuevamente en un sistema de haproxy de cara al público, balanceando la carga del tráfico web, sin realmente estudiar el impacto (¿tonto, correcto?) Y descubrí después de mucha solución de problemas y persiguiendo fantasmas que:

  • Creará caos para los clientes que se conectan a través de un NAT.
  • Es casi imposible de identificar porque es completamente aleatorio, intermitente y los síntomas afectarán al cliente A, en momentos completamente diferentes (o no) que el cliente B, etc.

En el lado del cliente, verán períodos de tiempo en los que ya no recibirán respuestas a los paquetes SYN, a veces aquí y allá, y a veces por largos períodos. De nuevo, al azar.

La historia corta aquí, en mi reciente y dolorosa experiencia, es dejarlos solos / deshabilitados en servidores públicos, sin importar el rol.

Mac
fuente
4

De 'man 7 tcp' Verás esto:

   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.

No hay mucha ayuda allí. Esta pregunta también tiene una buena idea:

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

Pero no hay información específica sobre por qué la reutilización es más segura que el reciclaje. La respuesta básica es que tcp_tw_reuse permitirá utilizar el mismo socket si ya hay uno en TIME_WAIT con los mismos parámetros TCP y que se encuentra en un estado donde no se espera más tráfico (creo que es cuando se ha enviado un FIN ) tcp_tw_recycle, por otro lado, solo reutilizará los sockets que están en TIME_WAIT con los mismos parámetros, independientemente del estado, lo que puede confundir los firewalls con estado que podrían estar esperando paquetes diferentes.

tcp_tw_reuse se puede hacer selectivamente en el código configurando la opción de socket SO_REUSEADDR, documentada man 7 socketcomo tal:

   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
fuente
1
¿Estás seguro de que SO_REUSEADDRestá vinculado con tcp_tw_reuse? Hasta donde sé, SO_REUSEADDRsolo se aplica cuando lo desee bind(), mientras que le tcp_tw_reuseindicará al kernel que reutilice el puerto de un socket local en TIME_WAITestado si necesita crear una nueva conexión saliente.
jpetazzo
No, no estoy seguro. :-P
SpamapS