Enxergando o interior do kernel: como o Nexusguard usa o eBPF para observabilidade e segurança de alta precisão

Nexusguard
-
8 minutos de leitura
Compartilhar com:

Uma visão prática de como o eBPF permite uma observabilidade precisa e de baixa sobrecarga em plataformas de segurança modernas

Introdução: Por que a observabilidade falha nos sistemas de segurança modernos

Quando algo dá errado na produção, raramente o problema é que não saibamos algo aconteceu. Picos de CPU, aumentos de latência, pacotes perdidos — os sistemas de monitoramento tradicionais são muito bons em nos dizer isso.

Eles são muito menos eficazes em responder à pergunta que mais importa durante um incidente:

O que exatamente aconteceu dentro do sistema, no momento em que aconteceu?

Para plataformas de segurança modernas, especialmente aquelas que operam em grande escala, dentro de ambientes em contêineres e sob condições de ataque, essa lacuna é crítica. Muitos comportamentos importantes ocorrem nas profundezas do kernel Linux ou ao longo dos caminhos de execução do aplicativo — áreas que são efetivamente invisíveis para ferramentas de espaço de usuário e métricas amostradas.

Na Nexusguard, uma das principais tecnologias em que confiamos para fechar essa lacuna é eBPF.

O que é eBPF?

O eBPF (Extended Berkeley Packet Filter) pode ser entendido como um máquina virtual em sandbox em execução dentro do kernel Linux.

Ele permite que os desenvolvedores carreguem dinamicamente pequenos programas em um kernel em execução, onde eles podem observar e reagir com segurança aos eventos do sistema — sem modificar o código-fonte do kernel, carregar módulos do kernel ou reiniciar o sistema.

Figura 1 - Visão geral conceitual do eBPF

Este diagrama ilustra onde os programas eBPF são executados dentro do kernel Linux, como eles são verificados e compilados pelo JIT e como os dados fluem com segurança de volta ao espaço do usuário por meio de mapas eBPF.

Três propriedades principais tornam o eBPF viável para sistemas de produção:

Segurança desde o design

Todos os programas eBPF devem passar por um verificador de kernel antes de serem executados. O verificador garante que os programas não possam travar o kernel, inserir loops infinitos ou acessar memória inválida. Essa é uma diferença fundamental em relação aos módulos tradicionais do kernel, em que um único bug pode derrubar todo o sistema.

Alto desempenho

Uma vez verificados, os programas eBPF são compilados em JIT em código de máquina nativo. Isso permite que eles sejam executados com uma sobrecarga muito baixa e sem a constante troca de contexto do kernel do usuário exigida por muitas ferramentas de rastreamento tradicionais.

Instrumentação com tempo de inatividade zero

Os programas eBPF podem ser carregados e descarregados dinamicamente, permitindo diagnósticos e observabilidade ao vivo sem interrupção do serviço.

Como o eBPF funciona na prática

Do ponto de vista da engenharia, um fluxo de trabalho típico do eBPF tem a seguinte aparência:

  1. Um programa eBPF é escrito (geralmente em C ou por meio de estruturas como BCC ou bpftrace).
  2. O programa é compilado em bytecode eBPF.
  3. O bytecode é carregado no kernel usando a chamada de sistema bpf ().
  4. O verificador do kernel realiza verificações de segurança.
  5. O programa é compilado em JIT em código de máquina nativo
  6. O programa é anexado a um evento específico.
  7. Quando o evento ocorre, o programa executa e registra os dados.

Os dados coletados geralmente são gravados em Mapas eBPF, que atuam como canal de comunicação entre programas eBPF no espaço do kernel e aplicativos no espaço do usuário.

Por que os mapas eBPF são importantes

Por padrão, os programas eBPF são apátridas. Cada execução é executada de forma independente e não consegue lembrar o que aconteceu anteriormente. Os mapas eBPF resolvem essa limitação.

Figura 2 - Mapas eBPF como uma ponte de comunicação

Os mapas eBPF atuam como a principal ponte de comunicação entre os programas eBPF do espaço do kernel e os consumidores do espaço do usuário, permitindo o compartilhamento de dados de estado, agregação e controle.

Os mapas eBPF são armazenamentos de valores-chave residentes no kernel que permitem:

  • Estado persistente em todos os eventos
  • Agregação e contagem
  • Compartilhamento seguro de dados entre programas eBPF
  • Acesso controlado a partir do espaço do usuário

Sem mapas, o eBPF seria limitado a observações transitórias. Com os mapas, ele se torna a base para sistemas reais de observabilidade e monitoramento.

Tabela 1 - Tipos de mapas eBPF

Tipo de Mapa Características Principais Casos de Uso Típicos
Tabela Hash Armazenamento chave-valor, consulta O(1), sem ordem Contadores, rastreamento de estados, armazenamento de configurações
Array (Arranjo) Tamanho fixo, acesso por índice, eficiente em memória Contadores globais, arrays de métricas, flags
Perf Event Array Baseado em ring-buffer, transferência eficiente do kernel para o usuário Análise de desempenho, exportação de eventos de rastreamento
Ring Buffer Produtor único, múltiplos consumidores, maior eficiência de memória Entrega de eventos de alto throughput (recomendado para novos designs)
LRU Hash Remove automaticamente as entradas menos recentemente usadas Implementações de cache, rastreamento de estado de sessões
LPM Trie Algoritmo de correspondência de prefixo mais longo Tabelas de roteamento IP, correspondência de regras de firewall
Filtro de Bloom Teste probabilístico de pertencimento, extremamente eficiente em espaço Deduplicação, verificações de existência
Fila / Pilha (Queue / Stack) Estruturas de dados FIFO (fila) / LIFO (pilha) Filas de eventos, buffer de mensagens
Sockmap / Sockhash Mapas conscientes de sockets para redirecionamento e aceleração Balanceamento de carga de rede, redirecionamento de tráfego

Conectando-se à realidade: gatilhos de eventos

Os programas eBPF são executados em resposta a eventos. Os três mecanismos de fixação mais usados são:

Sondas K

Sondas dinâmicas que se conectam a praticamente qualquer função do kernel. Eles oferecem grande flexibilidade, mas podem ser sensíveis às mudanças na versão do kernel.

U-sondas

Sondas de espaço de usuário que se conectam a funções dentro dos binários do aplicativo. Eles permitem uma inspeção profunda do comportamento do aplicativo sem modificar o código do aplicativo.

Pontos de rastreamento

Ganchos de kernel definidos estaticamente com interfaces estáveis e menor sobrecarga. Eles trocam flexibilidade por estabilidade a longo prazo.

Em sistemas do mundo real, esses mecanismos geralmente são combinados dependendo dos requisitos de desempenho, estabilidade e observabilidade.

Tabela 2 - Comparando os mecanismos de eBPF
Em sistemas de produção, esses mecanismos geralmente são combinados para equilibrar estabilidade, visibilidade e sobrecarga de desempenho.

Característica Kprobe Uprobe Tracepoint
Escopo Espaço do kernel Espaço do usuário Espaço do kernel
Tipo Rastreamento dinâmico Rastreamento dinâmico Rastreamento estático
Flexibilidade Extremamente alta (pode ser anexado a praticamente qualquer função do kernel) Extremamente alta (pode ser anexado a praticamente qualquer instrução ou função) Limitada (apenas tracepoints predefinidos)
Estabilidade Baixa (pode mudar entre versões do kernel) Baixa (pode mudar entre versões do aplicativo) Alta (ABI estável)
Sobrecarga de desempenho Relativamente alta Relativamente alta Baixa
Facilidade de uso Média Média Fácil (estruturas bem definidas)
Exemplo kprobe:vfs_read uprobe:/bin/bash:readline tracepoint:syscalls:sys_enter_open

De ferramentas genéricas a diagnósticos reais

O ecossistema eBPF inclui ferramentas poderosas, como:

  • ferramentas bcc (por exemplo, tcptop, execsnoop)
  • traço bpf, que permite que programas eBPF sejam escritos de forma semelhante a um script

Essas ferramentas possibilitam:

  • Observe o comportamento da rede em tempo real
  • Capture eventos de criação de processos que as ferramentas tradicionais perdem
  • Meça a latência de execução em nível de função sem modificar o código do aplicativo

Em um cenário de diagnóstico real, usamos o bpftrace para rastrear o tempo de execução de uma função específica dentro de um mecanismo WAF. Isso nos permitiu identificar gargalos de desempenho que teriam sido extremamente difíceis de isolar usando apenas registros ou amostras de métricas — tudo isso sem recompilar ou reimplantar o aplicativo.

Para ilustrar como o eBPF pode observar o comportamento do espaço do usuário sem alterações no código, considere o seguinte exemplo simplificado.

func randomSleep() {

       duration := time.Duration(rand.Intn(3000)) * time.Millisecond // 0-3000ms

       time.Sleep(duration)

}

O script bpftrace a seguir é anexado à função em tempo de execução e mede sua latência de execução, sem recompilar ou reiniciar o aplicativo.

#!/usr/bin/env bpftrace

/*

* bpftrace script: Monitor randomSleep function execution time

*

* Usage:

* sudo bpftrace monitor_timing.bt -p <PID>

*/

uprobe:./main:main.randomSleep

{

   @start[tid] = nsecs;

}

uretprobe:./main:main.randomSleep

{

   $duration_ms = (nsecs - @start[tid]) / 1000000; // Convert to milliseconds

   printf("randomSleep execution time: %llu ms\n", $duration_ms);

   

   // Statistics: total calls and average time

   @calls = count();

   @avg_time = avg($duration_ms);

   

   delete(@start[tid]);

}

BEGIN

{

   printf("Starting to monitor randomSleep function execution time...\n");

   printf("Press Ctrl+C to stop monitoring\n\n");

}

END

{

   printf("\n=== Statistics ===\n");

   printf("Total calls: ");

   print(@calls);

   printf("Average execution time: ");

   print(@avg_time);

   printf(" ms\n");

   printf("==================\n");

}

Figura 3 - Captura de tela real do terminal

Saída bpftrace ao vivo mostrando a latência de execução da função em tempo real, coletada de um processo em execução sem instrumentação do aplicativo.

Por que construímos um monitor eBPF na Nexusguard

À medida que nossa plataforma evoluiu, várias limitações ficaram claras com as abordagens tradicionais de monitoramento:

  • As ferramentas de coleta de métricas geralmente produziam grandes volumes de dados dos quais não precisávamos, ao mesmo tempo em que perdiam métricas importantes.
  • A execução baseada em amostragem introduziu imprecisões.
  • O monitoramento da lógica específica do negócio exigiu alterações intrusivas no código.
  • Suporte limitado e inconsistente para observabilidade em nível de contêiner e cgroup.

Para resolver isso, construímos um Monitor eBPF adaptado às necessidades operacionais da Nexusguard.

Figura 4 - Arquitetura eBPF do Nexusguard

Uma visão simplificada da arquitetura eBPF Monitor do Nexusguard, mostrando como os módulos eBPF residentes no kernel coletam dados orientados por eventos, compartilham estados por meio de mapas e exportam métricas estruturadas para sistemas de espaço de usuário.

Em alto nível:

  • Os módulos eBPF são executados dentro do kernel e coletam dados orientados por eventos.
  • A configuração é passada dinamicamente por meio de mapas eBPF.
  • Os dados coletados são exportados para o espaço do usuário, transformados em métricas e integrados aos canais de monitoramento existentes.
  • O sistema se adapta dinamicamente às reinicializações do contêiner e do processo sem exigir alterações no programa eBPF.

Segurança, controle de recursos e uso da produção

A execução de instrumentação dentro do kernel naturalmente levanta preocupações sobre segurança e sobrecarga.

O eBPF aborda essas preocupações por meio de:

  • Limites rígidos impostos pelo verificador
  • Tempo de execução limitado
  • Acesso controlado à memória
  • Comportamento previsível de tempo

Essas restrições permitem que a observabilidade profunda seja implantada com confiança em ambientes de produção.

O que isso significa para os clientes da Nexusguard

Ao aproveitar o eBPF como parte de nossa arquitetura de plataforma, o Nexusguard é capaz de:

  • Observe o comportamento onde ele realmente ocorre
  • Diagnostique problemas mais rapidamente e com menos suposições
  • Reduza a dependência de técnicas invasivas de depuração
  • Mantenha o desempenho mesmo sob cargas pesadas

Para os clientes, isso se traduz em maior confiabilidade, resposta mais rápida a incidentes e decisões de proteção mais precisas.

Pensamentos finais

À medida que os sistemas se tornam mais dinâmicos e os ataques mais sofisticados, a observabilidade deve se aproximar do próprio caminho de execução.

O eBPF nos dá essa capacidade.

No Nexusguard, não é um recurso independente, mas uma tecnologia fundamental que fortalece a forma como construímos, operamos e desenvolvemos nossa plataforma de segurança — de forma silenciosa, segura e precisa dentro do kernel.

Protect Your Infrastructure Today

Explore Nexusguard Edge Protection Solutions Today