12 min. de leitura
Em 18 de novembro de 2025, às 11h20 UTC (todos os horários neste blog são UTC), a rede da Cloudflare começou a apresentar falhas significativas no fornecimento de tráfego de rede principal. Isso foi mostrado aos usuários da internet que tentavam acessar os sites de nossos clientes como uma página de erro, indicando uma falha na rede da Cloudflare.
O problema não foi causado, direta ou indiretamente, por um ataque cibernético ou atividade maliciosa de qualquer natureza. Ele foi desencadeado por uma alteração nas permissões de um dos nossos sistemas de banco de dados, que fez com que o banco de dados enviasse várias entradas para um “arquivo de recursos” usado pelo nosso sistema do Bot Management. Esse arquivo de recursos, por sua vez, dobrou de tamanho. O arquivo de recursos, maior que o esperado, foi então propagado para todas as máquinas que compõem nossa rede.
O software executado nessas máquinas para rotear o tráfego em nossa rede lê esse arquivo de recursos para manter nosso sistema do Bot Management atualizado com as ameaças em constante mudança. O software tinha um limite no tamanho do arquivo de recursos que era inferior ao seu tamanho duplicado. Isso fez com que o software falhasse.
Depois de suspeitarmos inicialmente que os sintomas que estávamos observando eram causados por um ataque de DDoS em hiperescala, identificamos corretamente o problema principal e conseguimos interromper a propagação do arquivo de recursos maior do que o esperado e substituí-lo por uma versão anterior do arquivo. O tráfego principal estava fluindo normalmente às 14h30. Trabalhamos nas horas seguintes para mitigar o aumento da carga em várias partes de nossa rede à medida que o tráfego voltava a ficar on-line. Às 17h06, todos os sistemas da Cloudflare funcionavam normalmente.
Lamentamos o impacto causado aos nossos clientes e à internet em geral. Dada a importância da Cloudflare no ecossistema da internet, qualquer interrupção de qualquer um de nossos sistemas é inaceitável. O fato de ter havido um período em que nossa rede não conseguiu rotear o tráfego é profundamente lamentável para todos os membros de nossa equipe. Sabemos que decepcionamos vocês hoje.
Esta publicação é um relato detalhado do que aconteceu exatamente e de quais sistemas e processos falharam. É também o começo, embora não o fim, do que planejamos fazer para garantir que uma interrupção como esta não volte a acontecer.
O gráfico abaixo mostra o volume de códigos de status HTTP de erro 5xx fornecidos pela rede da Cloudflare. Normalmente, esse valor deveria ser muito baixo, e era assim até o início da interrupção.
O volume anterior a 11h20 é a linha de base esperada de erros 5xx observados em nossa rede. O pico e as flutuações subsequentes mostram que nosso sistema está falhando devido ao carregamento do arquivo de recursos incorreto. O que é notável é que o nosso sistema se recuperou durante um período. Este foi um comportamento muito incomum para um erro interno.
A explicação era de que o arquivo estava sendo gerado a cada cinco minutos por uma consulta executada em um cluster de banco de dados da ClickHouse, o qual estava sendo atualizado gradualmente para melhorar o gerenciamento de permissões. Dados incorretos eram gerados somente se a consulta fosse executada em uma parte do cluster que tivesse sido atualizada. Como resultado, a cada cinco minutos, havia a chance de um conjunto de arquivos de configuração, bom ou ruim, ser gerado e rapidamente propagado pela rede.
Essa flutuação tornou obscuro o que estava acontecendo, já que o sistema inteiro se recuperava e falhava novamente, porque arquivos de configuração, às vezes bons, às vezes ruins, eram distribuídos para a nossa rede. Inicialmente, isso nos levou a acreditar que isso poderia ser causado por um ataque. Ao final, cada nó do ClickHouse gerava o arquivo de configuração incorreto e a flutuação se estabilizou no estado de falha.
Os erros continuaram até que o problema subjacente fosse identificado e resolvido, a partir das 14h30. Resolvemos o problema interrompendo a geração e propagação do arquivo de recursos defeituoso e inserindo manualmente um arquivo funcional conhecido na fila de distribuição de arquivo de recursos. E, em seguida, forçamos a reinicialização do nosso proxy principal.
A cauda longa remanescente no gráfico acima refere-se à nossa equipe reiniciando os serviços restantes que entraram em um estado inadequado, com o volume de código de erro 5xx retornando ao normal às 17h06.
Os seguintes serviços foram afetados:
Serviço/produto | Descrição do impacto |
|---|
Serviços de CDN e segurança principais | Códigos de status HTTP 5xx. A captura de tela na parte superior deste post mostra uma página de erro típica exibida aos usuários finais. |
Turnstile | Falha ao carregar o Turnstile. |
Workers KV | O Workers KV retornou um nível significativamente elevado de erros HTTP 5xx, pois as solicitações ao gateway "front-end" do KV falharam devido a falha do proxy principal |
Painel | Embora o painel estivesse operacional na maior parte do tempo, a maioria dos usuários não conseguiu fazer login devido à indisponibilidade do Turnstile na página de login. |
Segurança de e-mail | Embora o processamento e a distribuição de e-mails não tenham sido afetados, observamos uma perda temporária de acesso a uma fonte de reputação de IP, o que reduziu a precisão da detecção de spam e impediu o acionamento de algumas detecções de idade de domínio recente. Não foi observado nenhum impacto crítico para os clientes. Também vimos falhas em algumas ações de movimentação automática. Todas as mensagens afetadas foram revisadas e corrigidas. |
Access | As falhas de autenticação foram generalizadas para a maioria dos usuários, começando no início do incidente e continuando até que o rollback fosse iniciado às 13h05. As sessões existentes do Access não foram afetadas.
Todas as tentativas de autenticação com falha resultaram em uma página de erro, o que significa que nenhum desses usuários chegou ao aplicativo de destino enquanto a autenticação falhava. Os logins bem-sucedidos durante este período foram registrados corretamente durante este incidente.
Qualquer tentativa de atualização da configuração do Access naquele momento teria falhado completamente ou se propagado muito lentamente. Todas as atualizações de configuração foram recuperadas. |
Além de retornar erros HTTP 5xx, observamos aumentos significativos na latência das respostas da nossa CDN durante o período de impacto. Isso ocorreu devido ao alto consumo de CPU pelos nossos sistemas de depuração e observabilidade, que aprimoram automaticamente o processo de detecção de erros não detectados com informações adicionais de depuração.
Como a Cloudflare processa as solicitações e o que deu errado hoje
Cada solicitação para a Cloudflare segue um caminho bem definido através da nossa rede. Pode ser proveniente de um navegador carregando uma página da web, um aplicativo móvel chamando uma API ou tráfego automatizado de outro serviço. Essas solicitações terminam primeiro em nossa camada HTTP e TLS, depois seguem para o nosso sistema proxy principal (que chamamos de FL, abreviação de "Frontline") e, finalmente, passam pelo Pingora, que realiza pesquisas de cache ou busca dados na origem, se necessário.
Anteriormente, compartilhamos mais detalhes sobre como o proxy principal funciona aqui.
À medida que uma solicitação passa pelo proxy principal, executamos os vários produtos de segurança e desempenho disponíveis em nossa rede. O proxy aplica a configuração e as definições exclusivas de cada cliente, desde a aplicação das regras do WAF e a proteção contra DDoS até o roteamento do tráfego para a plataforma para desenvolvedores e o R2. Ele realiza isso por meio de um conjunto de módulos específicos de domínio que aplicam as regras de configuração e política ao tráfego que transita pelo nosso proxy.
Um desses módulos, o Bot Management, foi a causa da interrupção de hoje.
O Bot Management da Cloudflare inclui, entre outros sistemas, um modelo de aprendizado de máquina que usamos para gerar pontuações de bots para cada solicitação que percorre nossa rede. Nossos clientes usam classificações de bots para controlar quais bots têm permissão para acessar seus sites ou não.
O modelo recebe como entrada um arquivo de configuração de "recurso". Nesse contexto, um recurso é uma característica individual usada pelo modelo de aprendizado de máquina para fazer uma previsão sobre se a solicitação foi automatizada ou não. O arquivo de configuração de recursos é uma coleção de recursos individuais.
Este arquivo de recursos é atualizado a cada poucos minutos e publicado em toda a nossa rede, permitindo-nos reagir a variações nos fluxos de tráfego na internet. Isso nos permite reagir a novos tipos de bots e novos ataques de bots. Portanto, é crucial que a implementação seja frequente e rápida, pois os agentes mal-intencionados alteram suas táticas com agilidade.
Uma mudança no comportamento subjacente da consulta ClickHouse (explicado abaixo) que gera este arquivo resultou em um grande número de linhas "feature" duplicadas Isso alterou o tamanho do arquivo de configuração de recursos, que anteriormente tinha tamanho fixo, fazendo com que o módulo de bots acionasse um erro.
Como resultado, o sistema proxy principal que lida com o processamento de tráfego para nossos clientes retornou códigos de erro HTTP 5xx para qualquer tráfego que dependesse do módulo de bots. Isso também afetou o Workers KV e o Access, que dependem do proxy principal.
Sem relação com este incidente, estávamos e estamos atualmente migrando nosso tráfego de clientes para uma nova versão do nosso serviço de proxy, conhecido internamente como FL2. Ambas as versões foram afetadas pelo problema, embora o impacto observado tenha sido diferente.
Clientes implantados no novo mecanismo de proxy FL2 observaram erros HTTP 5xx. Os clientes que utilizam nosso antigo mecanismo de proxy, conhecido como FL, não observaram erros, mas as pontuações de bots não foram geradas corretamente, resultando em todo o tráfego recebendo uma pontuação de bots igual a zero. Os clientes que tinham regras implementadas para bloquear bots observaram um grande número de falsos positivos. Os clientes que não estavam utilizando a nossa pontuação de bots em suas regras não notaram nenhum impacto.
Outro sintoma aparente que observamos nos fez suspeitar de um possível ataque: a página de status da Cloudflare ficou fora do ar. Essa página é hospedada completamente fora da infraestrutura da Cloudflare, sem nenhuma dependência da plataforma. Embora tenha se revelado uma coincidência, isso levou alguns membros da equipe, que diagnosticavam o problema, a acreditar que um invasor poderia estar visando tanto nossos sistemas quanto nossa página de status. Naquele momento, os visitantes da página de status se deparavam com a seguinte mensagem de erro:
Na sala de chat interna sobre incidentes, estávamos preocupados que isso pudesse ser a continuação da recente onda de ataques de DDoS da Aisuru de alto volume:
A alteração no comportamento das consultas
Mencionei acima que uma alteração no comportamento da consulta subjacente resultou em um grande número de linhas duplicadas no arquivo de recursos. O sistema de banco de dados em questão utiliza o software ClickHouse.
Para fins de contexto, é útil saber como as consultas distribuídas do ClickHouse funcionam. Um cluster do ClickHouse consiste em vários fragmentos. Para consultar dados de todos os fragmentos, temos as chamadas tabelas distribuídas (alimentadas pelo mecanismo de tabela Distributed) em um banco de dados chamado default. O mecanismo Distributed consulta as tabelas subjacentes em um banco de dados r0. As tabelas subjacentes são onde os dados são armazenados em cada fragmento de um cluster do ClickHouse.
As consultas para as tabelas distribuídas são executadas por meio de uma conta de sistema compartilhada. Como parte dos esforços para melhorar a segurança e a confiabilidade de nossas consultas distribuídas, estamos trabalhando para que elas sejam executadas sob as contas de usuário iniciais.
Antes de hoje, os usuários do ClickHouse viam apenas as tabelas no banco de dados default ao consultar os metadados das tabelas do sistema do ClickHouse, como system.tables ou system.columns.
Como os usuários já têm acesso implícito às tabelas subjacentes em r0, fizemos uma alteração às 11h05 para tornar esse acesso explícito, para que os usuários também possam ver os metadados dessas tabelas. Ao garantir que todas as subconsultas distribuídas possam ser executadas sob o usuário inicial, os limites de consulta e as concessões de acesso podem ser avaliados de maneira mais precisa, evitando que uma subconsulta inadequada de um usuário afete outros.
A alteração explicada acima permitiu que todos os usuários acessassem metadados precisos sobre as tabelas às quais têm acesso. Infelizmente, no passado foram feitas suposições de que a lista de colunas retornada por uma consulta como esta incluiria apenas o banco de dados “default”:
SELECT
name,
type
FROM system.columns
WHERE
table = 'http_requests_features'
order by name;
Observe como a consulta não filtra o nome do banco de dados. Com a nossa implementação gradual das concessões explícitas para os usuários de um determinado cluster do ClickHouse, após a alteração às 11h05, a consulta acima começou a retornar “duplicatas” de colunas, porque estas eram para tabelas subjacentes armazenadas no banco de dados r0.
Infelizmente, este foi o tipo de consulta realizada pela lógica de geração do arquivo de recursos do Bot Management para construir cada “recurso” de entrada para o arquivo mencionado no início desta seção.
A consulta acima retornou uma tabela de colunas como a exibida (exemplo simplificado).
No entanto, como parte das permissões adicionais que foram concedidas ao usuário, a resposta agora continha todos os metadados do esquema r0, efetivamente mais que dobrando as linhas na resposta e, em última instância, afetando o número de linhas (ou seja, recursos) na saída do arquivo final.
Cada módulo em execução em nosso serviço de proxy possui uma série de limites para evitar o consumo irrestrito de memória e pré-alocar memória como uma otimização de desempenho. Nesse caso específico, o sistema do Bot Management tem um limite para o número de recursos de aprendizado de máquina que podem ser utilizados em tempo de execução. Atualmente, esse limite está definido em 200, bem acima do nosso uso atual de cerca de 60 recursos. Novamente, o limite existe porque, por motivos de desempenho, nós pré-alocamos memória para os recursos.
Quando o arquivo corrompido com mais de 200 recursos foi propagado para nossos servidores, esse limite foi atingido, resultando em um colapso do sistema. O código FL2 Rust que realiza a verificação e foi a origem do erro não tratado é exibido abaixo:
Isso resultou no seguinte colapso, que por sua vez resultou em um erro 5xx:
thread fl2_worker_thread panicked: called Result::unwrap() on an Err value
Outro impacto durante o incidente
Outros sistemas que dependem de nosso proxy principal foram afetados durante o incidente. Isso incluiu o Workers KV e o Cloudflare Access. A equipe conseguiu reduzir o impacto nesses sistemas às 13h04, quando uma correção foi aplicada no Workers KV para contornar o proxy principal. Posteriormente, todos os sistemas downstream que dependem do Workers KV (como o próprio Access) observaram uma taxa de erros reduzida.
O painel da Cloudflare também foi afetado devido ao uso interno do Workers KV e à implantação do Cloudflare Turnstile como parte do nosso fluxo de login.
O Turnstile foi afetado por essa interrupção, resultando na impossibilidade de clientes sem uma sessão ativa no painel de controle acessarem o sistema. Isso se refletiu em uma disponibilidade reduzida durante dois períodos: das 11h30 às 13h10 e entre 14h40 e 15h30, conforme mostrado no gráfico abaixo.
568 / 5.000O primeiro período, das 11h30 às 13h10, foi devido ao impacto no Workers KV, do qual algumas funções do plano de controle e do painel dependem. O sistema foi restaurado às 13h10, quando o Workers KV contornou o sistema proxy principal.O segundo período de impacto no painel ocorreu após a restauração dos dados de configuração do recurso. Um acúmulo de tentativas de login começou a sobrecarregar o painel. Esse acúmulo, em combinação com as tentativas de reenvio, resultou em latência elevada, reduzindo a disponibilidade do painel. O ajuste da simultaneidade no plano de controle restabeleceu a disponibilidade por volta das 15h30.
Etapas de correção e acompanhamento
Agora que nossos sistemas estão on-line novamente e funcionando normalmente, já começamos a trabalhar em como fortalecê-los contra falhas como esta no futuro. Em particular, estamos:
Reforçando a segurança da ingestão de arquivos de configuração gerados pela Cloudflare da mesma forma que faríamos com entradas geradas por usuários
Habilitando mais interruptores globais para recursos
Eliminando a possibilidade de que despejos de memória ou outros relatórios de erro sobrecarreguem os recursos do sistema
Revisando os modos de falha para identificar condições de erro em todos os módulos principais do proxy.
Hoje foi a pior interrupção da Cloudflare desde 2019. Tivemos interrupções que tornaram nosso painel indisponível. Algumas que fizeram com que novos recursos não ficassem disponíveis por um período de tempo. Mas, nos últimos 6 anos ou mais, não tivemos outra interrupção que tenha feito com que a maior parte do tráfego principal parasse de fluir através da nossa rede.
Uma interrupção como a de hoje é inaceitável. Arquitetamos nossos sistemas para serem altamente resilientes a falhas, para garantir que o tráfego continue sempre fluindo. No passado, as interrupções sempre nos levaram a construir sistemas novos e mais resilientes.
Em nome de toda a equipe da Cloudflare, gostaria de pedir desculpas pelo transtorno que causamos à internet hoje.
Horário (UTC) | Status | Descrição |
|---|
11:05 | Normal. | Alteração de controle de acesso ao banco de dados implantada. |
11:28 | O impacto começa. | A implantação atinge os ambientes dos clientes. Os primeiros erros foram observados no tráfego HTTP dos clientes. |
11:32 - 13:05 | A equipe investigou os níveis elevados de tráfego e erros no serviço Workers KV.
| O sintoma inicial pareceu ser uma taxa de resposta degradada do Workers KV, causando impacto downstream em outros serviços da Cloudflare.
Mitigações, como manipulação de tráfego e limitação de contas, foram tentadas para trazer o serviço Workers KV de volta aos níveis operacionais normais.
O primeiro teste automatizado detectou o problema às 11h31 e a investigação manual começou às 11h32. A chamada de incidente foi criada às 11h35. |
13:05 | Implementado o bypass do Workers KV e Cloudflare Access. Impacto reduzido. | Durante a investigação, utilizamos bypasses internos para o Workers KV e o Cloudflare Access, de modo que eles retornassem a uma versão anterior do nosso proxy principal. Embora o problema também estivesse presente em versões anteriores do nosso proxy, o impacto era menor, como descrito abaixo. |
13:37 | O trabalho concentrou-se na reversão do arquivo de configuração do Bot Management para uma versão válida conhecida mais recente. | Estávamos confiantes de que o arquivo de configuração do Bot Management foi o gatilho para o incidente. As equipes trabalharam em maneiras de reparar o serviço em vários fluxos de trabalho, sendo o fluxo de trabalho mais rápido a restauração de uma versão anterior do arquivo. |
14:24 | A criação e propagação de novos arquivos de configuração do Bot Management foram interrompidas. | Identificamos que o módulo do Bot Management era a origem dos erros 500 e que estes foram causados por um arquivo de configuração inválido. Interrompemos a implantação automática de novos arquivos de configuração do Bot Management. |
14:24 | Teste do novo arquivo concluído. | Observamos uma recuperação bem-sucedida utilizando a versão antiga do arquivo de configuração e, em seguida, focamos em acelerar a correção globalmente. |
14h30 | Impacto principal resolvido. Os serviços afetados downstream começaram a observar menos erros. | Um arquivo de configuração do Bot Management correto foi implementado globalmente e a maioria dos serviços começou a operar corretamente. |
17:06 | Todos os serviços foram resolvidos. O impacto termina. | Todos os serviços downstream foram reiniciados e todas as operações foram totalmente restauradas. |