Conntrack: quando os health checks passam e o tráfego para
Uma firewall stateful decide o caminho de uma ligação uma vez, na criação, pelo que um fluxo de longa duração pode guardar uma decisão desatualizada enquanto cada probe novo passa.
Neste artigo 5 secções
- Uma firewall stateful toma a decisão de forwarding e NAT para uma ligação no seu primeiro pacote e guarda-a na state table durante toda a vida do fluxo. As alterações de encaminhamento e de política não são aplicadas a fluxos que já existem.
- Um stream contínuo como syslog sobre TCP, replicação de base de dados, um metrics forwarder ou um túnel pode manter uma ligação durante semanas. Se a rede mudar por baixo, esse fluxo guarda a decisão antiga enquanto os pings e as novas ligações recebem a nova, pelo que todas as verificações passam.
- Monitorize o que chega, não o que está ativo: contadores de bytes face ao volume esperado, ocupação da state table, e uma verificação de ponta a ponta de que os dados chegaram. Um fluxo congelado corrige-se apagando a sua entrada na state table, não reiniciando a firewall.
A decisão é tomada uma vez
O connection tracking existe para que uma firewall avalie a política uma vez por fluxo em vez de uma vez por pacote. O primeiro pacote é comparado com as regras, o resultado de forwarding e NAT é escrito na state table, e cada pacote seguinte desse fluxo é um hash lookup. O conntrack do netfilter, a state table do pf no OPNsense e a connection table no Cisco Firepower funcionam todos assim. A entrada vive até o fluxo fechar ou o seu idle timeout expirar, e para uma ligação TCP established esse timeout mede-se em dias.
A consequência passa facilmente despercebida: uma alteração ao encaminhamento, a uma regra NAT ou a uma interface afeta o fluxo seguinte, não os fluxos que já estão na tabela.
Duas formas de isto deixar cair tráfego em silêncio
O caminho desatualizado. Uma rota muda, uma interface move-se, um NAT pool é editado. As novas ligações seguem o novo caminho. Um stream de longa duração mantém a sua interface de egress ou o seu NAT binding originais, pelo que os seus pacotes saem pelo caminho antigo, para um next hop que já não os encaminha ou sem a tradução que a outra ponta agora espera. A stack TCP do emissor retransmite pacientemente numa ligação que ainda considera established, o recetor não vê nada, e nenhum processo de nenhum dos lados falhou.
A tabela cheia. O nf_conntrack_max é atingido, normalmente por causa de um scanner, de um cliente atrás de NAT com milhares de fluxos curtos, ou de timeouts longos numa máquina ocupada. O kernel regista uma linha e começa a descartar o primeiro pacote das novas ligações enquanto os fluxos existentes continuam. Um health check que reutiliza uma ligação aberta continua a passar. Os utilizadores que abrem ligações novas recebem timeouts.
Nenhuma das duas aparece na monitorização de processos. O daemon está ativo, o listener está ligado à porta, a regra está presente.
Porque é que os health checks passam
Um ping, um probe TCP connect e o path simulator de uma firewall criam cada um um novo fluxo ou avaliam a política de raiz, pelo que cada um recebe a decisão atual e correta. A leitura verde é verdadeira sobre o objeto errado. A pergunta a fazer à firewall não é o que faria com um pacote novo, mas o que está a fazer com os fluxos que já tem.
# the live flows from one source, with their state and NAT binding
conntrack -L -s <source>
# how full the table is
sysctl net.netfilter.nf_conntrack_count net.netfilter.nf_conntrack_max
# the kernel's own report of a full table
journalctl -k | grep -i 'nf_conntrack: table full'Um fluxo anterior à última alteração de encaminhamento que mostra um egress ou uma tradução que nenhuma regra atual produziria é a entrada a observar.
O que monitorizar
Chegada, não vivacidade. Linhas por minuto a entrar na base de dados do collector, mensagens por minuto no recetor de syslog, uma posição de replicação que avança. Uma linha plana é o alarme, diga o estado do processo o que disser.
Contadores face à expectativa. O contador de bytes na regra que transporta um stream cresce aproximadamente ao ritmo do stream. Uma regra que devia estar ocupada e está quase plana significa que os pacotes estão a corresponder a outra regra ou não estão a chegar de todo.
Ocupação da state table. Alerte sobre o nf_conntrack_count como fração do nf_conntrack_max muito antes de encher, e sobre a mensagem de tabela cheia do kernel, que de outra forma fica no log sem ser lida.
Verificações sintéticas com a forma do tráfego real. Um probe que mantém uma ligação de longa duração e empurra um registo através dela a intervalos, verificado na outra ponta, testa aquilo que se avaria. Um ping novo testa aquilo que não se avaria.
Depois de cada alteração de encaminhamento ou NAT, liste os fluxos mais antigos do que a alteração e decida deliberadamente se os limpa.
A correção é um bisturi
Apague o estado da origem afetada. O pacote seguinte cria uma entrada nova com a decisão atual e o stream retoma.
conntrack -D -s <source>Um reboot ou um flush completo também funciona, e leva consigo todas as outras ligações ativas. Para uma tabela cheia, a correção é aumentar o nf_conntrack_max juntamente com o tamanho do hash, encurtar o timeout established onde não são precisos dias, e encontrar o cliente que está a criar os fluxos.
Respostas diretas
Porque é que a firewall diz allow mas não passa tráfego?+
O path simulator calcula o que um pacote novo receberia. Um fluxo existente está vinculado à decisão tomada quando foi criado, e o simulator não lê a state table. Liste os fluxos ativos dessa origem e compare o seu egress e a sua tradução com o que as regras atuais produziriam.
Porque é que o ping funciona e o stream da aplicação não?+
O ping cria fluxos de curta duração que expiram em segundos, pelo que cada um recebe uma decisão nova. O stream mantém um único fluxo de longa duração e guarda a decisão com que nasceu.
Como encontro uma ligação presa na interface errada?+
conntrack -L filtrado por origem no netfilter, a vista da state table no pf ou no Firepower. Procure fluxos mais antigos do que a última alteração de rede cujo egress ou NAT binding nenhuma regra atual lhes daria.
Como corrijo sem reiniciar a firewall?+
Apague as entradas de estado dessa origem com conntrack -D. O pacote seguinte é avaliado de raiz. Tudo o resto na tabela fica intocado.
Um stream ficou em silêncio enquanto todas as verificações estão verdes?
Fale com um engenheiro que lê a state table, não o simulator.
Fale com um engenheiroChegou ao fim.
Ponha a leitura em prática
O que executa?
Fale-nos da carga de trabalho, do tráfego e dos requisitos de recuperação. Comece pelo configurador de servidores ou discuta os detalhes com um engenheiro.
Escrito pelos engenheiros que constroem e operam a infraestrutura que descreve.Fale com um engenheiro
