Como um firewall mataria uma conexão TCP sem RST ou FIN? [fechadas]

8

A situação é assim:

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

Devido a uma manutenção de atividade, o servidor e o cliente manteriam as conexões TCP abertas e o cliente usaria um conjunto de conexões para solicitações HTTP.

O firewall tem uma regra para "matar" conexões TCP de longa data após 1 hora. O problema é que nosso cliente HTTP não detectou que a conexão TCP foi destruída e tentou reutilizar conexões essencialmente mortas que, do nosso lado, pareciam o cliente "travado" após um período de tempo. Uma solicitação seria interrompida e a próxima funcionaria, provavelmente porque uma nova conexão foi estabelecida.

A questão aqui é qual é o mecanismo com o qual o firewall está matando as conexões TCP de uma maneira que nosso cliente HTTP não conseguiu detectá-las. Tentei reproduzir esse comportamento localmente de algumas maneiras:

  1. Mate as conexões TCP em nosso roteador vyos, o Wireshark no lado do cliente capturou o TCP FIN-ACK. Está bem
  2. Mate o lado do cliente da conexão TCP no TCPView no Windows, o Wireshark detectou o TCP RST no lado do cliente. Está bem
  3. A porta de bloqueio após a conexão estabelecida com o firewall do lado do cliente resultou na exceção de redefinição de soquete. Está bem

Eu tenho um dump do Wireshark no lado do servidor e tentei descobrir se o firewall envia um FIN ou RST com ip.dst==serverip && (tcp.flags.reset==1 || tcp.flags.fin==1)mas nada apareceu.

Além disso, a captura do Wireshark no lado do cliente mostra o problema quando a solicitação HTTP é encerrada, seguida por uma dúzia de retransmissões de TCP, não sendo levada a lugar algum.

O cliente HTTP é um cliente Java nativo e / ou Jetty HTTP (tentou ambos), ambos falharam ao detectar uma conexão TCP morta. Gostaria de reproduzir o comportamento localmente, mas não consigo descobrir de que maneira astuciosa o firewall está matando as conexões, procurando, portanto, possíveis respostas.

cen
fonte
8
Basta soltar o pacote no firewall, ou seja, não encaminhá-lo para o destino e não defina qualquer FIN, RST etc.
Steffen Ullrich
Você deve editar sua pergunta para incluir o modelo e a configuração do firewall (ofusque todas as senhas e endereços públicos).
Ron Maupin
"O firewall tem uma regra para 'matar' conexões TCP de longa data após 1 hora." Isso soa como uma regra de firewall seriamente bizarra.
reirab
@RonMaupin eu já faria se eu sabia que ou acesso teve
cen
Infelizmente, perguntas sobre redes sobre as quais você não tem controle direto estão explicitamente fora de tópico aqui.
Ron Maupin

Respostas:

11

Você não menciona o tipo de firewall, mas eu suspeito que simplesmente elimine os pacotes.

Eu tenho um dump do Wireshark no lado do servidor e tentei descobrir se o firewall envia um FIN ou RST com ip.dst == serverip && (tcp.flags.reset == 1 || tcp.flags.fin == 1), mas nada apareceu.

O que tenderia a confirmar isso.

Ron Trunk
fonte
Infelizmente, não conheço nenhuma informação sobre o firewall, pois é uma rede interna. Alguma sugestão de como eu poderia reproduzir isso localmente (preferencialmente do lado do cliente)?
cen
11
Se seu objetivo é criar um banco de testes, você pode executar um firewall de software em um PC ou comprar um firewall de hardware barato. Bloquear a conexão parece ser uma coisa simples de se fazer.
Ron Trunk
5

Provavelmente, o firewall acabou de descartar o pacote sem enviar um pacote RST, provavelmente após atingir algum tipo de tempo limite da sessão. Esse é geralmente um comportamento configurável.

Pessoalmente, prefiro que o pacote RST seja enviado precisamente porque ajuda os clientes a se comportarem normalmente, mas ouvi argumentos no sentido de que isso não deve ser feito em firewalls externos para evitar fornecer qualquer tipo de feedback aos possíveis invasores.

Eu já vi essa causa alguns problemas, porque os clientes normalmente não lidam com esse tipo de cenário com muita elegância. Essencialmente, eles continuam tentando novamente a sessão TCP original (que agora está morta) e nunca tentam restabelecer uma nova. Eventualmente, um tempo limite do lado do cliente é acionado e o usuário recebe uma mensagem de erro desagradável. Configurar o keepalive HTTP adequadamente para o aplicativo pode ajudar a corrigir isso.

Jeremy Gibbons
fonte
O envio de um FIN ou RST exigiria que a implementação do firewall acompanhasse os números de sequência na conexão (porque precisa preencher esses dados no pacote FIN / RST). Por outro lado, uma política "apenas largue" significa que a implementação do firewall só precisa armazenar as quatro tuplas e matá-las quando o tempo de 1 hora terminar.
mere3ortal
Eu posso entender o raciocínio da rede externa, mas para a interna, isso parece absolutamente ruim.
cen
É mau fazer isso com firmeza. Apenas caia completamente se nada estiver ouvindo nessa porta para esse intervalo de IPs.
28717 Joshua Joshua
@ Josué, concordei inteiramente que é mau, precisamente porque tive que consertar a bagunça que isso causou. Ainda assim, isso acontece com equipes SecOps suficientemente paranóicas ...
Jeremy Gibbons
4

O @Ron Trunk está exatamente correto, quase certamente a conexão aberta está sendo descartada ativamente (negar regra inserida) ou passivamente (removida de conexões conhecidas e não pode ser recriada sem uma sincronização). Um dos comentários sugeriu tentar você mesmo. Aqui está uma receita para fazer isso usando namespaces de rede linux. Ele assume que o encaminhamento de IP está ativado no kernel do seu host, você é root e provavelmente outras coisas.

# 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

Você precisa de três janelas / conchas / telas / terminais. Execute cada comando abaixo em um terminal distinto:

  • Comece a ouvir no servidor: ip netns exec three socat TCP-LISTEN:5001 STDIO
  • Comece a transmitir no cliente: ip netns exec one socat STDIO TCP:3.3.3.3:5001

Observe que, depois de executar esses comandos, tudo o que você digita em uma janela será refletido na outra e vice-versa (após pressionar Return). Se isso não for verdade, pode ser necessário ativar o encaminhamento de IP.

  • Instancie a regra de negação: ip netns exec two iptables -I FORWARD -j DROP

Então, nada que você digitar será permitido.

Você pode simular um método de descarte menos ativo com regras de encaminhamento (não testadas) 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

Consulte /unix/127081/conntrack-tcp-timeout-for-state-stablished-not-working e https://www.kernel.org/doc/Documentation/networking/nf_conntrack-sysctl .txt para obter informações sobre como ajustar os tempos limite - embora não esteja claro para mim que o iptables suporta nativamente uma vida útil máxima da conexão; Acredito que todos os tempos limite sejam inativos.

Limpe com ip netns del one; ip netns del two; ip netns del three

Seth Robertson
fonte
As configurações de host / servidor / VM estão fora de tópico aqui.
Ron Maupin
@Ron Maupin: Mas está criando uma plataforma de teste de rede para testar uma teoria de engenharia de rede fora do tópico?
Seth Robertson
Existem algumas coisas, como configurar os dispositivos de rede (roteador, comutadores etc.) ou usar algo como Pacet Tracer ou GNS3 para simular algo, sobre o assunto. A configuração dos hosts / servidores / VMS não é um tópico aqui. Como esses e seus sistemas operacionais funcionam não faz parte da rede. O OP precisa incluir o modelo e a configuração do firewall para que possamos ver se podemos ajudar.
Ron Maupin
1

O firewall pode enviar um pacote ICMP indicando que o destino estava inacessível. Para qualquer coisa, exceto TCP, essa é a única indicação de erro possível, por exemplo, enviar um pacote para uma porta UDP fechada gerará uma mensagem "destino inacessível" com o código de razão definido como "porta inacessível".

Também é possível enviar mensagens de "porta inacessível" como resposta aos pacotes TCP, isso também encerra a conexão, mas qualquer pessoa que analise despejos de pacotes notará que isso é incomum, pois a convenção TCP indica portas fechadas com um RST.

Espera-se que o remetente mapeie todos os pacotes de erros ICMP recebidos de volta para a conexão de origem e os manipule adequadamente, para que um pacote de erros gerado por firewall também possa ser usado para terminar uma conexão TCP. O pacote ICMP contém uma cópia dos cabeçalhos do pacote incorreto para permitir esse mapeamento.

Simon Richter
fonte