¿Cómo mataría un firewall una conexión TCP sin RST o FIN? [cerrado]

8

La situación es así:

http client ----> corporate firewall ----> http server

Debido a una actividad activa, el servidor y el cliente mantendrían abiertas las conexiones TCP y el cliente usaría un grupo de conexiones para las solicitudes HTTP.

El firewall tiene una regla para "matar" conexiones TCP de larga data después de 1 hora. El problema es que nuestro cliente HTTP no detectaría que la conexión TCP fue destruida y trató de reutilizar conexiones esencialmente inactivas que, por nuestro lado, parecían "colgadas" después de un período de tiempo. Se colgaría una solicitud, luego la siguiente funcionaría, presumiblemente porque se estableció una nueva conexión.

La pregunta aquí es cuál es el mecanismo con el que el firewall está matando las conexiones TCP de una manera que nuestro cliente HTTP no pudo detectarlas. Traté de reproducir este comportamiento localmente de varias maneras:

  1. Elimine las conexiones TCP en nuestro enrutador vyos, Wireshark en el lado del cliente capturó TCP FIN-ACK. Okay
  2. Eliminar la conexión TCP del lado del cliente en TCPView en Windows, Wireshark detectó TCP RST en el lado del cliente. Okay
  3. Bloquear el puerto después de la conexión establecida con el firewall del lado del cliente, resultó en una excepción de reinicio del socket. Okay

Tengo un volcado de Wireshark en el lado del servidor y traté de encontrar si el firewall envía un FIN o RST ip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)pero no apareció nada.

Además, la captura de Wireshark en el lado del cliente muestra el problema cuando se cierra la solicitud HTTP, seguida de una docena de retransmisiones TCP, que finalmente no van a ninguna parte.

El cliente HTTP es un cliente Java nativo y / o Jetty HTTP (probó ambos), ambos no pudieron detectar una conexión TCP inactiva. Me gustaría reproducir el comportamiento localmente, pero no puedo entender de qué manera dudosa el cortafuegos está matando las conexiones, por lo tanto, buscando posibles respuestas.

cen
fuente
8
Simplemente coloque el paquete en el servidor de seguridad, es decir, no lo reenvíe al destino y no establecen ninguna FIN, RST, etc
Steffen Ullrich
Debería editar su pregunta para incluir el modelo y la configuración del firewall (ofuscar las contraseñas y las direcciones públicas).
Ron Maupin
"El firewall tiene una regla para 'matar' las conexiones TCP de larga data después de 1 hora". Eso suena como una regla de firewall muy extraña.
reirab
@RonMaupin Ya lo haría si lo supiera o tuviera acceso
cen
Desafortunadamente, las preguntas sobre redes sobre las cuales no tiene control directo están explícitamente fuera de tema aquí.
Ron Maupin

Respuestas:

11

No mencionas el tipo de firewall, pero sospecho que la mayoría simplemente descarta los paquetes.

Tengo un volcado de Wireshark en el lado del servidor e intenté encontrar si el firewall envía un FIN o RST con ip.dst == serverip && (tcp.flags.reset == 1 || tcp.flags.fin == 1) pero nada apareció.

Lo que tendería a confirmar esto.

Ron Trunk
fuente
Lamentablemente, no conozco ninguna información sobre el firewall, ya que es una red interna. ¿Alguna sugerencia de cómo podría reproducir esto localmente (preferiblemente del lado del cliente)?
cen
1
Si su objetivo es crear un banco de pruebas, puede ejecutar un firewall de software en una PC o comprar un firewall de hardware económico. Bloquear la conexión parece ser algo simple de hacer.
Ron Trunk
5

Lo más probable es que el firewall haya descartado el paquete sin enviar un paquete RST, probablemente después de alcanzar un valor de tiempo de espera de sesión de algún tipo. Este es típicamente un comportamiento configurable.

Personalmente prefiero que se envíe ese paquete RST precisamente porque ayuda a los clientes a comportarse normalmente, pero he escuchado argumentos en el sentido de que esto no debería hacerse en firewalls externos para evitar proporcionar cualquier tipo de retroalimentación a los posibles atacantes.

He visto que esto causa bastantes problemas porque los clientes generalmente no manejan este tipo de escenario con mucha elegancia. Esencialmente, siguen intentando de nuevo a través de la sesión TCP original (que ahora está muerta) y nunca intentan restablecer una nueva. Finalmente, se activa un tiempo de espera del lado del cliente y el usuario recibe un mensaje de error desagradable. Configurar HTTP keepalive adecuadamente para la aplicación puede ayudar a solucionar esto.

Jeremy Gibbons
fuente
El envío de un FIN o RST requeriría que la implementación del firewall realice un seguimiento de los números de secuencia en la conexión (porque necesita completar esos datos en el paquete FIN / RST). Por el contrario, una política de "simplemente suéltelo" significaría que la implementación del firewall solo necesita almacenar las 4 tuplas y eliminarlas cuando transcurra el tiempo de 1 hora.
mere3ortal
Puedo entender el razonamiento de la red externa, pero interna, esto parece francamente malvado.
cen
Es malo hacer esto con estado. Solo deje caer por completo si nada debería estar escuchando en ese puerto para ese rango de IP.
Joshua
@Joshua, estuve completamente de acuerdo en que es malo, precisamente porque tuve que arreglar el desastre que esto causó. Aún así, sucede con equipos SecOps suficientemente paranoicos ...
Jeremy Gibbons, el
4

@Ron Trunk es exactamente correcto, casi con certeza la conexión abierta se cae de forma activa (se niega la regla insertada) o de forma pasiva (se elimina de las conexiones conocidas y no se permite volver a crear sin una sincronización). Uno de los comentarios sugirió probarlo usted mismo. Aquí hay una receta para hacerlo utilizando espacios de nombres de red de Linux. Se supone que el reenvío de IP está habilitado en el kernel de su host, usted es root y probablemente otras cosas.

# Create network namespacs
ip netns add one; ip netns add two; ip netns add three
# Create interfaces between namespaces
ip link add dev i12 type veth peer name i21
ip link add dev i32 type veth peer name i23
# Bring interfaces up and assign them to respective namespaces
ip link set dev i12 netns one up
ip link set dev i21 netns two up
ip link set dev i32 netns three up
ip link set dev i23 netns two up
# Assign IP addresses
ip netns exec one ip addr add 1.1.1.1/24 dev i12
ip netns exec two ip addr add 1.1.1.2/24 dev i21
ip netns exec three ip addr add 3.3.3.3/24 dev i32
ip netns exec two ip addr add 3.3.3.2/24 dev i23
# Add routes when necessary
ip netns exec one ip route add default via 1.1.1.2
ip netns exec three ip route add default via 3.3.3.2

Luego necesita tres ventanas / conchas / pantallas / terminales. Ejecute cada comando a continuación en un terminal distinto:

  • Comience a escuchar en el servidor: ip netns exec three socat TCP-LISTEN:5001 STDIO
  • Comience a transmitir en el cliente: ip netns exec one socat STDIO TCP:3.3.3.3:5001

Tenga en cuenta que después de ejecutar estos comandos, todo lo que escriba en una ventana se reflejará en la otra, y viceversa (después de presionar regresar). Si eso no es cierto, es posible que deba habilitar el reenvío de IP.

  • Instanciar la regla de rechazo: ip netns exec two iptables -I FORWARD -j DROP

Entonces, nada de lo que escriba se permitirá.

Puede simular un método de descarte menos activo con reglas de reenvío (no probadas) como:

ip netns exec two iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT
ip netns exec two iptables -A FORWARD -m tcp -p tcp -dport 5001 --tcp-flags ALL SYN -j ACCEPT
ip netns exec two iptables -A FORWARD -j DROP

Ver /unix/127081/conntrack-tcp-timeout-for-state-stablished-not-working y https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl .txt para obtener información sobre cómo ajustar los tiempos de espera, aunque no me queda claro que iptables admite de forma nativa una vida útil de conexión máxima; Creo que todos los tiempos de espera son tiempos de inactividad.

Limpiar con ip netns del one; ip netns del two; ip netns del three

Seth Robertson
fuente
Las configuraciones de host / servidor / VM están fuera de tema aquí.
Ron Maupin
@Ron Maupin: ¿Pero está creando un banco de pruebas de red para probar una teoría de ingeniería de redes fuera de tema?
Seth Robertson
Hay algunas cosas, como la configuración de los dispositivos de red (enrutador, conmutadores, etc.) o el uso de algo como Pacet Tracer o GNS3 para simular algo. La configuración de los hosts / servidores / VMS está fuera de tema aquí. Cómo funcionan esos y sus sistemas operativos no forma parte de la red. El OP debe incluir el modelo y la configuración del firewall para que podamos ver si podemos ayudar.
Ron Maupin
1

El cortafuegos puede enviar un paquete ICMP que indica que no se pudo alcanzar el objetivo. Para cualquier cosa que no sea TCP, esa es la única indicación de error posible, por ejemplo, enviar un paquete a un puerto UDP cerrado generará un mensaje de "destino inalcanzable" con el código de razón establecido en "puerto inalcanzable".

También es posible enviar mensajes de "puerto inalcanzable" como respuesta a los paquetes TCP, esto también termina la conexión, pero cualquiera que analice los volcados de paquetes notará que esto es inusual, porque la convención TCP es indicar puertos cerrados con un RST.

Se espera que el remitente asigne los paquetes de error ICMP recibidos de nuevo a la conexión de origen y los maneje adecuadamente, de modo que un paquete de error generado por el firewall también se pueda usar para terminar una conexión TCP. El paquete ICMP contiene una copia de los encabezados del paquete ofensivo para permitir esta asignación.

Simon Richter
fuente