Este é o quarto blog de uma série de blogs que abordam vários aspectos do que foi necessário para construir e operar nosso serviço SaaS :
No blog anterior , fornecemos insights sobre o desafio de usar técnicas criptográficas para proteger nossa plataforma (infraestrutura, aplicativos e dados). Este blog abordará técnicas que usamos para proteger a plataforma contra ataques direcionados da rede — tanto da Internet quanto de dentro dela. Como os aplicativos não estão mais restritos a nenhum local físico, os firewalls tradicionais baseados em perímetro e as soluções de segurança baseadas em assinatura não são mais eficazes. Descreveremos as deficiências da nossa implementação inicial de segurança de confiança zero e por que + como a ampliamos com técnicas algorítmicas e de aprendizado de máquina para proteger adequadamente nossa infraestrutura distribuída + clusters de aplicativos.
Nossa plataforma executa um grande número de aplicativos em várias equipes que operam seus próprios clusters no Edge, em nossa rede global e nas nuvens públicas AWS e Azure. Embora a maioria das cargas de trabalho sejam orquestradas por microsserviços usando o Kubernetes, temos alguns monólitos de grande escala (por exemplo, Elasticsearch) que gerenciamos usando o Terraform. A Figura 1 demonstra a natureza distribuída da nossa plataforma. Por exemplo, em cada um dos nossos mais de 18 PoPs de rede global (com algumas dezenas a pouco mais de cem servidores físicos), executamos milhares de pods de aplicativos. No entanto, no limite, temos implantações de clientes individuais hoje com mais de 3.000 locais ativos (cada um com de um a sete computadores) executando algumas dezenas de pods de aplicativos.
A plataforma é totalmente multilocatária, com cada nó executando cargas de trabalho de diferentes clientes (e os nossos). Como alguns desses aplicativos são expostos à Internet pública, precisamos garantir que toda a comunicação de/para os aplicativos seja protegida. Conforme descrevemos nos dois blogs anteriores, construímos um sistema robusto de identidade, autenticação e autorização, juntamente com nosso próprio caminho de dados de rede L3-L7+ (VoltMesh), que é usado para alimentar nossa malha de serviços e gateway de API . Conforme mostrado na Figura 2, isso nos permitiu fornecer segurança em nível de transporte em clusters de aplicativos (mTLS), de usuários (TLS/mTLS) e funcionários (mTLS), bem como controle de acesso baseado em autenticação+autorização.
Embora essa implementação de confiança zero ofereça muitos benefícios, ela não resolveu automaticamente vários problemas de segurança:
Nos últimos 2,5 anos de desenvolvimento nesta plataforma, também percebemos que, muitas vezes, nossos desenvolvedores incorporam aplicativos de código aberto, os colocam em contêineres e pedem para nossa equipe de DevOps implantá-los na plataforma. No entanto, muitas vezes não há detalhes sobre as interações no nível da API dentro desses aplicativos, que são necessários para que nossa equipe de segurança crie políticas para colocar a comunicação na lista de permissões. Este é um grande obstáculo para nossa implementação de segurança de confiança zero, pois exige políticas de lista de permissões que permitem apenas APIs usadas pelos aplicativos e bloqueiam todo o outro tráfego. Sempre que fazíamos exceções a esse requisito, alguns aplicativos ficavam com segmentação muito básica no nível da rede, aumentando assim a superfície de ataque.
Como resultado, precisávamos ampliar nossa solução de segurança de confiança zero existente com recursos de segurança adicionais para lidar com os problemas listados acima. Identificamos uma lista de recursos de segurança adicionais que precisávamos incorporar à plataforma:
Decidimos usar uma combinação de técnicas tradicionais baseadas em assinaturas, algoritmos estatísticos e abordagens mais dinâmicas de aprendizado de máquina para resolver esses problemas. Isso exigiu que fizéssemos alterações em nosso backend SaaS, bem como adicionássemos novos recursos em nosso caminho de dados de rede.
Para bloquear a plataforma, permitimos apenas conexões de rede com base na lista de permissões de APIs para cada aplicativo. Isso requer que nossa equipe de segurança coordene com os desenvolvedores e garanta que nosso mecanismo de política programável seja alimentado com as informações corretas da API. Rapidamente percebemos que era impossível para nossos desenvolvedores fornecer essas informações para aplicativos que não foram criados usando nossa estrutura de serviço.
Como nosso proxy de malha de serviço está no caminho de rede de cada acesso ao aplicativo, decidimos aprender APIs e recursos estáticos que são expostos pelo aplicativo fazendo análises de tempo de execução de cada acesso que passa pelo proxy. O desafio dessa abordagem é identificar os endpoints da API inspecionando URLs e separando os componentes que são gerados dinamicamente. Por exemplo, para uma API “api/user/<user_id>/vehicle/”, o proxy verá acessos como:
Pode haver milhões de solicitações desse tipo, o que as torna muito difíceis de decifrar. Como resultado, a identificação de componentes dinâmicos nessas solicitações relacionadas é feita usando aprendizado profundo e análise de gráficos. Representamos todo o conjunto de componentes de URL como um gráfico e, em seguida, realizamos o agrupamento de gráficos para encontrar subgráficos com propriedades semelhantes usando conjuntos de recursos que capturam propriedades específicas de componentes gerados dinamicamente, como:
Como resultado, os componentes dinâmicos são classificados e a saída do sistema se parece com:
Usando esse aprendizado de máquina de APIs, podemos gerar de forma fácil e automática uma política que pode ser aplicada pelo nosso proxy de malha de serviço. Com base nos endpoints de API descobertos, também aprendemos outras propriedades, como quais aplicativos usam quais APIs para se comunicar com outros aplicativos, o comportamento típico dessas APIs, etc. Isso nos permite criar um gráfico de serviço que ajuda nossa equipe de segurança a visualizar a interação entre serviços para análise forense, descoberta e microssegmentação em nível de API.
Antes de começarmos a adicionar os dois recursos restantes (detecção de anomalias e criação de perfil de comportamento), decidimos ver se as soluções existentes poderiam nos ajudar. Embora existam muitos firewalls de perímetro e produtos de firewall de aplicativos da web no mercado, a maioria dessas soluções é voltada para a proteção de aplicativos voltados para a Internet. Eles fazem certas suposições de que o tráfego atendido é tráfego da web e fornecem proteção direcionada para HTML, javascript, sql, CMS, etc. — tornando relativamente mais fácil escrever assinaturas e regras para detectar vulnerabilidades e explorações conhecidas.
Embora esse recurso seja importante para nosso tráfego da web, também precisamos atender a uma quantidade crescente de tráfego de API e máquina a máquina em nosso ambiente. Para resolver isso, nossa equipe de segurança teria que escrever regras específicas para aplicativos que não se enquadrassem nas regras típicas da web conhecidas (como OWASP CRS). Normalmente, os administradores de segurança sabem pouco sobre os aplicativos e, com a natureza dinâmica do ambiente, fica ainda mais difícil controlar os tipos de aplicativos e a estrutura para escrever regras específicas para cada aplicativo. Como resultado, embora nossa equipe de plataforma forneça esse recurso em nosso caminho de dados de rede, ele não é usado com frequência por nossa equipe de segurança.
Outro problema para o qual temos uma quantidade significativa de dados em nossa rede é que os ataques a aplicativos estão se tornando muito mais sofisticados ao longo do tempo. O invasor passa dias realizando reconhecimento para determinar os detalhes das APIs, do aplicativo, da infraestrutura subjacente e do tipo de sistema operacional, observando assinaturas HTTP/TCP, etc. As abordagens tradicionais baseadas em assinaturas e regras são de uso muito limitado nessas situações e decidimos continuar com nossa abordagem baseada em IA para aprender automaticamente o comportamento do usuário e impor o comportamento bom e o ruim.
A maioria dos aplicativos tem determinados fluxos de trabalho (sequência de APIs) e contexto (dados dentro das APIs) para os quais diferentes casos de uso/implantações são projetados e normalmente seguidos pelos usuários dos aplicativos. Exploramos essas propriedades e treinamos nossos algoritmos de aprendizado de máquina para modelar padrões comportamentais “válidos” em uma interação típica do usuário com o aplicativo.
Nosso datapath coleta amostras de solicitações/respostas para cada API, juntamente com os dados associados, e os envia para nosso mecanismo de aprendizado central, conforme mostrado na Figura 3. Este mecanismo gera e atualiza continuamente o modelo de padrões comportamentais válidos que são então usados pelo mecanismo de inferência em execução no caminho de dados para alertar/bloquear comportamentos suspeitos.
O mecanismo de aprendizado analisa muitas métricas, como a sequência de APIs, lacunas entre solicitações, solicitações repetidas para as mesmas APIs, falhas de autenticação, etc. Essas métricas são analisadas para cada usuário e de forma agregada para classificar o comportamento bom do ruim. Também realizamos agrupamentos de comportamento para identificar várias sequências diferentes de “bom comportamento”. Vamos dar um exemplo para ilustrar isso:
A sequência de APIs a seguir será sinalizada pelo sistema como comportamento suspeito/ruim que será automaticamente mitigado pelo sistema ou gerará um alerta para um administrador intervir
À medida que colocamos esse sistema em produção há mais de um ano, refinamos continuamente o modelo com base no uso e no feedback dos clientes. Conseguimos identificar com sucesso os seguintes tipos de ataques:
Dito isso, também percebemos que há alguns problemas com essa abordagem: ela não consegue descobrir ataques lentos e de baixa intensidade (força bruta, negação de serviço de aplicativo, scanner), para os quais precisamos aplicar técnicas de detecção de anomalias.
Às vezes, vemos ataques altamente sofisticados que usam grandes botnets distribuídas que passam despercebidos pela nossa técnica de análise comportamental. Exemplos de tais ataques são:
Como nosso caminho de dados de rede coleta informações de cada nó em nossa rede global, fica relativamente fácil realizar análises nas métricas agregadas de um aplicativo específico, como taxa de solicitação, taxa de erro, rendimento de resposta, etc. Essa análise nos permite detectar ataques distribuídos e mitigá-los (em cada nó) identificando os usuários que podem fazer parte dessas botnets. Vamos dar um exemplo em que estamos tentando detectar anomalias em diferentes janelas de tempo (últimos 5 minutos, 30 minutos, 4 horas, 24 horas) observando as taxas de solicitação e, se a taxa de solicitação for alta em uma determinada janela de tempo, a seguinte análise mais profunda dos logs de acesso será realizada pelo sistema:
Embora a detecção de anomalias sempre tenha sido uma técnica importante para detecção e prevenção de intrusão (IDS/IPS) em dispositivos de firewall, esses dispositivos não conseguem mitigar ataques globais na camada de aplicativo. Com nossa capacidade de executar marcação e aprendizado de API em nossa plataforma global, agora podemos suprimir ataques na fonte em nossa rede distribuída.
Embora estivéssemos extremamente satisfeitos com nossa implementação de confiança zero baseada em malha de serviço e gateway de API, percebemos que ela não era abrangente para proteger clusters de aplicativos distribuídos contra vulnerabilidades e ataques maliciosos. Tivemos que aumentá-lo com aprendizado de máquina para análise de comportamento + detecção de anomalias, juntamente com técnicas tradicionais baseadas em assinatura e regras para fornecer uma melhor solução de segurança.
Vimos três ganhos significativos com a adição de inferências distribuídas em nosso caminho de dados de rede L3-L7+, juntamente com o núcleo de aprendizagem em execução em nosso SaaS centralizado:
A segurança de redes e aplicativos é uma área em constante evolução e parece que ainda temos um longo acúmulo de novos recursos para adicionar. Voltaremos em um futuro próximo para compartilhar insights adicionais sobre os algoritmos e técnicas incrementais que implementamos.
Esta série de blogs abordará vários aspectos do que foi necessário para construir e operar nosso serviço SaaS distribuído globalmente com muitos clusters de aplicativos em nuvens públicas, nossos PoPs de rede privada e sites de ponta. O próximo será “Observabilidade em nossa plataforma globalmente distribuída” (em breve)…