2011-09-03 13 views
6

Tengo dos servidores de Linux (llamémoslos A y B), conectados al mismo conmutador (no administrado). Desactivé el firewall en ambos servidores (no hay reglas en todas las tablas y todas las políticas predeterminadas se establecen en ACEPTAR). Por lo tanto, nada debe impedir que un servidor envíe paquetes TCP/IP y otro servidor para recibirlos tal como están.¿Qué puede hacer que NO se envíe un indicador de restablecimiento de TCP/IP (RST)?

Ahora, en A ejecutamos la aplicación del servidor TCP, que escucha/acepta las conexiones entrantes, y luego enviamos una gran cantidad de datos en un bucle a los clientes conectados. No intenta leer desde el cliente y espera obtener el error EPIPE mientras escribe write() en el socket si/cuando el cliente se desconecta.

Siguiente, en B Ejecuto nc (netcat) como aplicación cliente, me conecto a la aplicación del servidor en A, comienzo a recibir datos, y unos segundos después presiono Ctrl-C para interrumpir esta conexión.

Lo que veo, es la aplicación de servidor en A simplemente cuelga en write(), no tiene EPIPE ni ningún otro error.

he rastreado los paquetes TCP/IP utilizando tcpdump, y esto es lo que veo:

  • después de interrumpir el netcat B, B envía a A FIN, que respondió correctamente con ACK al que FIN - por lo , ahora tenemos conexión TCP semiabierta, que está bien
  • siguiente, A intenta enviar datos siguientes al cliente con los paquetes ACK y PSH, ACK habituales, que también es esperado y correcto
  • PERO, B doesn No respondo de ninguna manera a estos paquetes (aunque espero que responda con el paquete RST porque recibe paquetes para la conexión TCP ya cerrada/no existente)
  • A no consiguió ACK, por lo que detener el envío de nuevos datos y empezar a volver a enviar los paquetes viejos (y en este punto siguiente llamada a escribir() se bloquea)

También he probado para funcionar en netcat A (por lo tanto, las aplicaciones de cliente y servidor se ejecutan en el mismo servidor físico), y de esta manera todo funciona como se esperaba: la aplicación de servidor obtuvo EPIPE inmediatamente después de que interrumpo netcat con Ctrl-C. Y tcpdump muestra que hay un paquete RST enviado como se esperaba.

Entonces, ¿qué puede causar que no se envíe RST en este caso?

Estoy usando Hardened Gentoo Linux, actualizado, kernel 2.6.39-hardened-r8, sin ninguna configuración específica relacionada con la red sysctl.

Puede o no ser importante tener en cuenta que hay una actividad de red significativa en estos servidores, alrededor de 5000 conexiones tcp enumeradas por netstat -alnp en cualquier momento, y creo que 1000 conexiones se abren y cierran cada segundo en promedio. Es habitual ver en el registro del núcleo algo como esto (pero el número de puerto es diferente de la utilizada por aplicación de servidor se discutió anteriormente):

TCP: Possible SYN flooding on port XXXXX. Sending cookies. 
    net_ratelimit: 19 callbacks suppressed 

Aquí es cómo sesión TCP por lo general se parece a: http://i54.tinypic.com/1zz10mx.jpg

+0

De la discusión en otro sitio: ** 1) ** después de la salida de netcat el netstat ya no lo enumera en el servidor B (aunque creo que debería aparecer en el estado FIN_WAIT_2), en el servidor A netstat todavía muestra esto conexión en estado CLOSE_WAIT, como se esperaba; ** 2) ** alguien piensa que esto puede suceder debido a SO_LINGER, pero no estoy de acuerdo porque netcat no activa SO_LINGER manualmente y cierra() antes de salir() por lo que no debería activarse automáticamente, además SO_LINGER no debería afectar ACK/RST responde en _incoming_ paquetes de todos modos. – Powerman

+0

Parece que el kernel antiguo (2.6.28-hardened-r9) funciona como se esperaba: envía paquetes RST. – Powerman

Respuesta

3

Este comportamiento es consecuencia de la función activada en mi núcleo endurecido:

Security options ---> 
    Grsecurity ---> 
     Network Protections ---> 
     [*] TCP/UDP blackhole and LAST_ACK DoS prevention 

CONFIG_GRKERNSEC_BLACKHOLE:

Si responde S aquí, ni res TCP Los paquetes de destino inalcanzable ICMP o de destino se enviarán en respuesta a paquetes enviados a puertos para los que no existe ningún proceso de escucha asociado.Esta característica es compatible tanto con IPV4 como con IPV6 y exime a la interfaz de bucle invertido de blackholing. Al habilitar esta característica, el host es más resistente a los ataques DoS y reduce la visibilidad de la red frente a los escáneres. La característica de agujero negro según se implementa es equivalente a la característica de agujero negro de FreeBSD, ya que previene las respuestas RST a todos los paquetes, no solo a los SYN.

Cuestiones relacionadas