O kill switch ativa: o que acontece às sessões TCP abertas?
Um pacote bloqueado não é uma ligação fechada. Decida se uma sessão deve sobreviver à interrupção e depois teste o bloqueio e a recuperação como duas propriedades separadas.
O túnel cai, o kill switch ativa e um download que estava a três quartos congela ou falha de imediato. Estes dois resultados vêm de escolhas de aplicação diferentes, não de níveis de proteção diferentes. Um pacote descartado deixa a ligação à espera, enquanto um pacote rejeitado a fecha e avisa a aplicação. Decidir que comportamento quer é uma questão de desenho, e testá-lo é um exercício separado.
Descartar, rejeitar e reiniciar são coisas diferentes
Uma regra de firewall que descarta o tráfego deita fora o pacote e não devolve nada, por isso o emissor continua a retransmitir pelos seus próprios temporizadores. Uma regra que rejeita com um TCP reset fecha a ligação de imediato e a aplicação vê um erro. A maioria dos kill switches descarta, porque uma rejeição revelaria a política e porque descartar se assemelha ao comportamento de uma rede morta.
Bloquear também não é o mesmo que fechar o socket. A aplicação ainda mantém um descritor num estado estabelecido, e só faltam os pacotes. É por isso que uma página pode ficar num indicador de carregamento durante minutos enquanto o sistema operativo insiste que a ligação existe. Leia a política de aplicação documentada em vez de a inferir da mensagem da aplicação, já que ambos os comportamentos parecem uma rede em baixo.
O que a aplicação faz enquanto a interrupção dura
O TCP retransmite com atrasos crescentes, e o orçamento de tentativas predefinido do Linux expira por volta de um quarto de hora, não em segundos. Até lá o socket não está nem utilmente aberto nem fechado. As aplicações com os seus próprios keepalives ou tempos limite de pedido desistem muitas vezes mais cedo, e é por isso que dois programas na mesma máquina se comportam de forma diferente durante uma falha.
Quando o túnel regressa, o socket local não mudou, mas o caminho pode ter mudado. Um novo endereço de origem público produz um quádruplo diferente no servidor, por isso uma firewall com estado do outro lado já não corresponde à sessão. A ligação está morta mesmo que o cliente nunca tenha visto um erro.
Decida se a recuperação é necessária
Escolha entre dois contratos. Ou a sessão tem de sobreviver a uma interrupção curta, o que exige endereçamento estável e um servidor que guarde o seu estado, ou a aplicação tem de se voltar a ligar de forma limpa, o que exige lógica de repetição segura de repetir. Qualquer coisa pelo meio produz o pior resultado: um cliente que reenvia o que o servidor já registou, ou um que relata sucesso para uma sessão que ninguém consegue ver.
O endereçamento estável é a parte que as pessoas esquecem, porque uma reconexão que aterra num endereço público diferente invalida o estado do lado do servidor mesmo quando o socket do cliente parece saudável. Anote qual dos dois contratos se aplica a cada aplicação, já que raramente coincidem todos.
Verifique o bloqueio e a recuperação separadamente
Trate a proteção contra fugas e a sobrevivência da sessão como duas propriedades, porque passar uma não diz nada sobre a outra. Uma sessão que sobrevive não é prova de que o tráfego direto foi bloqueado, e uma sessão que morre não é prova de que todas as rotas diretas o foram.
ss -tnp state established '( dport = :443 )'
sudo conntrack -L -p tcp --dport 443
sudo tcpdump -ni any 'tcp port 443 and tcp[tcpflags] & tcp-syn != 0'
Use uma operação de teste inofensiva ao observar a recuperação, para que um envio duplicado não se torne o incidente. Registe o modo de falha que realmente viu: o que a aplicação mostrava, se o socket sobreviveu e quando recuperou sozinho.
Escreva o comportamento esperado ao lado da regra de aplicação e ponha a data. A próxima pessoa que alterar essa regra precisa de saber qual dos dois contratos a implementação prometeu.