Relatório sobre o incidente de outubro no AdGuard para Windows: Post Mortem
Recentemente, alguns usuários do AdGuard para Windows vêm enfrentando problemas com o aplicativo. Após o lançamento da versão 7.22, descobrimos que a atualização causava falhas ocasionais no carregamento de páginas nos navegadores. Embora o problema tenha sido rapidamente mitigado no Chrome, ele persistiu por mais tempo no Firefox, já que o bug era raro e difícil de reproduzir, resultando de uma combinação incomum de fatores que não foi identificada durante os testes.
No momento desta publicação, já lançamos um hotfix — AdGuard para Windows v7.22.1 — que resolve completamente o problema. Certifique-se de que seu aplicativo está atualizado para a versão mais recente para garantir uma experiência estável. Se você usa o AdGuard em outras plataformas, não é necessário fazer nada — tudo deve estar funcionando normalmente.
Pedimos sinceras desculpas pelo transtorno e esperamos que este incidente não afete sua experiência geral com o AdGuard. Foi um caso isolado que não voltará a ocorrer. Além de corrigir o problema técnico, também revisamos nossos processos internos e já implementamos várias melhorias para evitar situações semelhantes no futuro.
Abaixo está a linha do tempo dos eventos que levaram ao incidente; em seguida, forneceremos mais detalhes técnicos e listaremos as medidas que estamos tomando para evitar que algo assim aconteça novamente.
Linha do tempo dos eventos
2 de outubro
Lançamos o AdGuard para Windows v7.22.
4 de outubro
Um usuário abriu um issue no GitHub relatando problemas de carregamento de páginas e, eventualmente, um erro Timed out após atualizar para a versão 7.22.
6 de outubro
Nossa equipe de QA começou a investigar o problema, mas não conseguiu reproduzi-lo. O problema foi escalado para os desenvolvedores no mesmo dia, e as discussões internas tiveram início.
16 de outubro
À medida que mais usuários entraram na discussão no GitHub, aumentaram os relatos e votos positivos. Infelizmente, nesta fase, a equipe de QA não seguiu as diretrizes internas de escalonamento para questões desse nível. Encontramos grande dificuldade para reproduzir o bug, em parte devido à natureza inconsistente dos relatos. Isso levou a equipe a presumir que ele havia sido introduzido algumas versões antes e, portanto, não exigia um hotfix imediato. Como resultado, ele foi adiado para a próxima versão programada e, embora a tarefa estivesse marcada como P1: Critical, ela não foi devidamente escalada, o que levou à perda de tempo valioso.
30 de outubro
Após 24 dias, o problema voltou a aparecer internamente, revelando a real extensão do impacto nos usuários. Depois de conseguirmos reproduzir o problema, pudemos estimar o dano geral de forma mais precisa. O trabalho no hotfix (v7.22.1) começou imediatamente. No entanto, grande parte do tempo e esforço foi dedicada a reproduzir o problema de forma consistente e entender sua causa principal. Diversas hipóteses foram testadas e descartadas durante o processo.
Durante a investigação, também descobrimos um bug do Firefox relacionado a conexões QUIC, que tornava o carregamento de páginas ainda mais lento e dificultava a depuração. Além disso, foi identificado um problema relacionado à ausência de filtragem de conexões QUIC quando o AdGuard era executado junto com o AdGuard VPN no modo de compatibilidade com o Wintun desativado.
1º de novembro
Identificamos parcialmente a causa do problema e encontramos uma forma de reproduzi-lo. Uma correção foi implementada no DnsLibs, nosso mecanismo de filtragem DNS, e uma versão nightly foi lançada para testes.
5 de novembro
Determinamos a causa principal — um bug no componente de detecção de loops de roteamento do CoreLibs, o mecanismo de filtragem do AdGuard. O problema foi corrigido rapidamente e uma segunda versão nightly foi lançada.
6 de novembro
Os testes das versões nightly mostraram que as correções iniciais resolveram a maior parte dos problemas com conexões TCP, mas ainda restavam alguns problemas relacionados ao UDP. Para minimizar o impacto nos usuários, decidimos lançar as correções em duas fases. Primeiro, uma terceira versão nightly abordou esses problemas adicionais, incluindo correções finais nas bibliotecas e atualizações nas instruções do driver. Em seguida, preparamos e testamos cuidadosamente o patch v7.22.1, que foi lançado no mesmo dia.
Detalhes técnicos
O bug
O bug no AdGuard para Windows v7.22 causava travamentos ocasionais e imprevisíveis ao carregar certas páginas no Firefox. Ele não afetou usuários do Chrome da mesma forma. O problema começou depois que o CoreLibs v1.19 introduziu proteção contra routing loops, um mecanismo projetado para impedir que o tráfego retorne para si mesmo.
O bug tinha duas causas principais. Primeiro, um erro de programação excluiu uma porta da verificação de routing loop, o que fez com que algumas conexões filtradas legítimas, como requisições do navegador, pudessem ser bloqueadas. Isso era acionado por algumas requisições de serviço originadas do próprio AdGuard, como solicitações OCSP. Após essas requisições, a próxima conexão do navegador era interrompida.
Segundo, a verificação estava sendo aplicada no lugar errado, sobre conexões já estabelecidas, resultando em bloqueios desnecessários.
Por que precisamos de proteção contra routing loops?
Um routing loop ocorre quando o tráfego retorna à aplicação de origem. Esses loops podem causar lentidão nas conexões e alto uso da CPU. Normalmente, esse tipo de situação não ocorre, mas, devido à interação com outros softwares, loops podem acontecer. Para evitá-los, o AdGuard rastreia conexões de saída pelo endereço de origem e encerra qualquer uma que retorne ao mesmo endereço.
Por que isso afetou pouco o Chrome?
Porque apenas a conexão imediatamente após uma requisição de serviço era interrompida. Os usuários do Chrome tinham menos probabilidade de perceber o problema, já que o navegador tenta repetir automaticamente a mesma requisição de rede depois que uma conexão é reiniciada.
Usuários do Firefox, porém, foram afetados diretamente — o navegador não inclui tentativas automáticas de repetição após erros de rede, o que tornava o problema bem mais perceptível.
E o AdGuard para Linux e Android?
O problema não foi detectado durante a fase CLI da versão 1.19, embora novas funcionalidades sejam sempre introduzidas primeiro no AdGuard CLI, para que problemas graves sejam encontrados e corrigidos antes da integração com aplicativos baseados em interface gráfica. Neste caso, o problema acontecia apenas no modo automático do Linux e principalmente no Firefox. Como pouquíssimos usuários se enquadram nessas condições, nenhum relato foi recebido.
O problema também não apareceu no AdGuard para Android v4.12, que usa o mesmo CoreLibs 1.19, porque os endereços de entrada e saída das conexões eram diferentes, impedindo que as mesmas condições que acionavam o bug ocorressem.
O diagnóstico
Diagnosticar o problema foi particularmente difícil. O AdGuard abre relativamente poucas conexões de serviço, e as repetidas tentativas de reprodução muitas vezes usavam solicitações OCSP armazenadas em cache, impedindo o aparecimento do bug. Além disso, o problema afetava apenas uma única conexão downstream por vez. Usuários do Chrome quase não percebiam o problema porque o navegador repete automaticamente conexões falhas, enquanto usuários do Firefox eram diretamente impactados, já que ele não tenta reconectar após um erro de rede.
Um bug relacionado no Firefox descoberto no processo
Durante a investigação desse bug difícil de encontrar, percebemos que metade dos relatos tinha outros sintomas, e os problemas descritos começaram a aparecer também em versões anteriores do AdGuard. Foi assim que descobrimos um bug no Firefox para Windows que afeta conexões HTTP/3.
Em resumo, o Firefox tenta conexões HTTP/3 imediatamente quando um site anuncia suporte, mesmo que a conexão ainda não esteja disponível. O AdGuard atualmente não filtra HTTP/3 por padrão, então o HTTP/3 é bloqueado para aplicativos com filtragem HTTPS ativada.
Normalmente, navegadores incluem um algoritmo como o Happy Eyeballs, que escolhe automaticamente o melhor protocolo, mas o Firefox para Windows tenta estabelecer uma conexão HTTP/3 assim que descobre que o site oferece HTTP/3 (por exemplo, a partir de um registro DNS do tipo HTTPS) e atribui requisições a essa conexão HTTP/3 que ainda não foi estabelecida — mesmo havendo uma conexão HTTP/2 ativa. Se o HTTP/3 não estiver disponível, isso resulta em pausas de 20–30 segundos no carregamento do site, após as quais as requisições são “realocadas” para a conexão HTTP/2 ativa.
Um relatório de bug sobre esse comportamento foi enviado. Como medida preventiva, o AdGuard passou a modificar registros DNS do tipo HTTPS para remover o parâmetro ALPN h3 quando o filtro HTTP/3 estiver desativado. Isso oculta do navegador o fato de que HTTP/3 está disponível em casos onde ele seria bloqueado pelo AdGuard de qualquer forma.
A correção
A correção foi aplicada em duas fases.
A primeira fase corrigiu a lógica de correspondência de conexões para incluir corretamente a porta, o que resolveu a maior parte do problema, embora alguns falsos positivos ainda persistissem devido ao reaproveitamento de portas pelo Windows em conexões recém-encerradas. Uma nightly build lançada na noite de 5 de novembro ajudou a maioria dos usuários.
No entanto, ainda era possível ver vestígios do problema nos logs do AdGuard. Descobrimos que o problema estava apenas parcialmente resolvido — corrigir o algoritmo de correspondência de conexões não era suficiente, porque o Windows pode reutilizar a porta de uma conexão de saída dentro de um segundo após o socket ser liberado. Isso causava outro tipo de falso positivo, quando conexões não relacionadas, mas com o mesmo endereço e porta, eram erroneamente identificadas como loops.
Não havia novos incidentes claros (todos relataram que tudo estava funcionando bem), mas muitos usuários ainda poderiam ser potencialmente afetados. Foi assim que chegamos à segunda fase: ela abordou esses casos restantes, resultando no hotfix final, v7.22.1, que resolveu completamente o problema.
Medidas de prevenção
Esse problema não foi identificado anteriormente principalmente devido à dificuldade de reproduzi-lo em condições normais de teste, combinada com atenção insuficiente ao feedback dos usuários.
Atualmente, estamos atualizando nossos processos de QA e desenvolvimento, com foco especial em combinar um monitoramento de processos mais rigoroso, automação aprimorada e testes e comunicação interna mais rigorosos. Com isso, esperamos evitar incidentes semelhantes no futuro e garantir a confiabilidade do AdGuard para todos os usuários.
Mudanças no fluxo de trabalho da equipe de QA
A equipe de QA passará a prestar mais atenção ao número de comentários e votos positivos nos Issues do GitHub. Para minimizar o fator humano, esse monitoramento não dependerá apenas de revisão manual — será introduzida automação para acompanhar a atividade e o número de upvotes em issues públicas. Se essa abordagem se mostrar eficaz, ela poderá ser ampliada e aplicada a todas as equipes de QA em todos os projetos da AdGuard.
Será realizado um briefing adicional com base nas nossas Diretrizes de Triagem (Triage Guidelines), e uma prática obrigatória será introduzida para avaliação interna de issues no Jira. Esse processo exigirá uma justificativa baseada em diretrizes estruturadas, garantindo consistência e transparência nas decisões de priorização.
A equipe também preparará uma lista de perguntas de diagnóstico para usuários, o que facilitará a identificação e a análise de problemas relacionados ao filtro com base no feedback fornecido.
Por fim, serão implementados vários novos testes automatizados para evitar que problemas semelhantes ocorram no futuro. Um script de teste de benchmark está sendo desenvolvido para avaliar a velocidade de filtragem de páginas em diferentes navegadores. Depois que uma linha de base de desempenho for definida, todos os lançamentos subsequentes serão comparados com ela. Atualmente, os testes automatizados são usados apenas no Google Chrome, mas planejamos estendê-los também ao Firefox. Além disso, serão criados testes para medir o tempo de carregamento de um conjunto definido de páginas “problemáticas” nesses navegadores. Essa lista será baseada em sites problemáticos conhecidos e continuará a ser expandida, começando por aqueles identificados durante a investigação deste problema — por exemplo, discord.com.
Mudanças no fluxo de trabalho da equipe de desenvolvimento
As equipes de desenvolvimento dedicarão mais atenção à criação de novos testes — incluindo testes de integração — para novas funcionalidades sempre que possível, a fim de reduzir a probabilidade de erros em versões futuras. Será dada maior ênfase à documentação técnica detalhada de novos recursos e à garantia de que todas as equipes envolvidas estejam devidamente informadas sobre a necessidade de testar novas funcionalidades quanto a possíveis problemas e casos extremos.
Ao integrar novas versões do CoreLibs aos produtos, as equipes agora aguardarão aprovação explícita da equipe do CoreLibs antes de prosseguir. No momento, esse processo de integração é realizado de forma um pouco “isolada”, o que aumenta o risco de problemas passarem despercebidos.
Conclusão
Gostaríamos de pedir desculpas mais uma vez a todos os usuários afetados por este incidente e agradecer sinceramente a todos que forneceram feedback e nos ajudaram a lidar com essa situação desafiadora. Daqui para frente, também seremos mais rápidos e transparentes na comunicação com nossos usuários sobre quaisquer problemas críticos que possam ter impacto significativo.