
O plugin de rede Calico fornece um conjunto abrangente de políticas de rede com uma sintaxe unificada para proteger hosts em hardware, máquinas virtuais e pods. Essas políticas podem ser aplicadas dentro de um namespace ou serem políticas de rede globais aplicáveis a (para proteger aplicativos que funcionam diretamente no host — o host pode ser um servidor ou uma máquina virtual) ou a (para proteger aplicativos que funcionam em contêineres ou máquinas virtuais implantadas no host). As políticas Calico permitem aplicar medidas de segurança para diferentes pontos de entrada de pacotes usando opções como preDNAT, unraracked e applyOnForward. Compreender como essas opções funcionam pode ajudar a aumentar a segurança e a performance do sistema como um todo. Este artigo explica a essência dessas opções de políticas Calico (preDNAT, unraracked e applyOnForward) aplicadas a endpoints de host, com foco no que acontece nos caminhos de processamento de pacotes (cadeias iptables).
Este artigo presume que você tem uma compreensão básica dos princípios de funcionamento das políticas de rede Kubernetes e Calico. Se não, recomendamos que você tente e usando Calico, antes de ler este artigo. Também esperamos que você tenha um entendimento básico de funcionamento em Linux.
Calico permite que você aplique um conjunto de regras de acesso por labels (a grupos de hosts e workloads/pods). Isso é muito útil se você estiver usando juntos sistemas heterogêneos — máquinas virtuais, sistemas diretamente em hardware ou infraestrutura kubernetes. Além disso, você pode proteger seu cluster (nós) com um conjunto de políticas declarativas e aplicar políticas de rede ao tráfego de entrada (por exemplo, através de serviços NodePorts ou IPs Externos).
Em um nível fundamental, quando o Calico conecta um pod à rede (veja o diagrama abaixo), ele o conecta ao host por meio de uma interface Ethernet virtual (veth). O tráfego enviado pelo pod chega ao host através dessa interface virtual e é tratado da mesma forma como se tivesse vindo de uma interface de rede física. Por padrão, o Calico nomeia essas interfaces como caliXXX. Como o tráfego é enviado pela interface virtual, ele passa pelo iptables, como se o pod estivesse a um hop de distância. Portanto, quando o tráfego chega/saí do pod, ele é encaminhado do ponto de vista do host.
Em um nó do Kubernetes onde o Calico está executando, você pode mapear a interface virtual (veth) ao workload da seguinte forma. No exemplo abaixo, você pode ver que veth#10 (calic1cbf1ca0f8) está conectado ao cnx-manager- * no namespace calico-monitoring.
[centos@ip-172-31-31-46 K8S]$ sudo ip a
...
10: calic1cbf1ca0f8@if4: mtu 1440 qdisc noqueue state UP group default
link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 5
inet6 fe80::ecee:eeff:feee:eeee/64 scope link
valid_lft forever preferred_lft forever
...
[centos@ip-172-31-31-46 K8S]$ calicoctl get wep --all-namespaces
...
calico-monitoring cnx-manager-8f778bd66-lz45m ip-172-31-31-46.ec2.internal 192.168.103.134/32
calic1cbf1ca0f8
... 
Considerando que o Calico cria uma interface veth para cada workload, como ele aplica políticas? Para isso, o Calico cria hooks em várias cadeias de processamento de pacotes usando o iptables.
No diagrama abaixo, as cadeias envolvidas no processamento de pacotes no iptables (ou sistema netfilter) estão mostradas. Quando um pacote chega através da interface de rede, ele passa primeiro pela cadeia PREROUTING. Em seguida, é tomada uma decisão de roteamento, e com base nisso, o pacote passa pela cadeia INPUT (destinado a processos do host) ou pela FORWARD (destinado a um pod ou outro nó na rede). De um processo local, o pacote passa pela cadeia OUTPUT e, em seguida, pela POSTROUTING antes de ser enviado pelo cabo.
Observe que o pod também é um objeto externo (conectado ao veth) do ponto de vista do processamento do iptables. Em resumo:
- O tráfego encaminhado (forwarded) (nat, roteável ou de / para pod) passa pelas cadeias PREROUTING - FORWARD - POSTROUTING.
- O tráfego para um processo de host local passa pela cadeia PREROUTING - INPUT.
- O tráfego de um processo de host local passa pela cadeia OUTPUT - POSTROUTING.

Calico oferece opções de políticas para aplicar políticas a todas as cadeias. Tendo isso em mente, vamos examinar as diferentes opções de configuração de políticas disponíveis no Calico. Os números na lista de opções abaixo correspondem aos números no diagrama acima.
- Política de endpoint de carga de trabalho (pod)
- Política de endpoint de host
- Opção ApplyOnForward
- Política PreDNAT
- Política Untracked
Comecemos examinando como as políticas são aplicadas aos endpoints de carga de trabalho (pods Kubernetes ou VMs OpenStack), e depois veremos as opções de políticas para os endpoints de host.
Endpoints de Carga de Trabalho
Política de Endpoint de Carga de Trabalho (1)
Esta é uma opção para proteger seus pods Kubernetes. O Calico oferece suporte ao Kubernetes NetworkPolicy, mas também fornece políticas adicionais — Calico NetworkPolicy e GlobalNetworkPolicy. O Calico cria uma cadeia para cada pod (carga de trabalho) e ganchos nas cadeias INPUT e OUTPUT para carga de trabalho na tabela de filtros da cadeia FORWARD.
Endpoints de Host
Política de Endpoint de Host (2)
Além do CNI (interface de rede de container), as políticas do Calico oferecem a capacidade de proteger diretamente o host. No Calico, você pode criar um endpoint de host especificando uma combinação da interface do host e, se necessário, números de portas. A aplicação de políticas para esta entidade é alcançada através da tabela de filtros nas cadeias INPUT e OUTPUT. Como mostrado no diagrama, (2) elas se aplicam a processos locais no nó/host. Ou seja, se você criou uma política que se aplica ao endpoint de host, ela não afetará o tráfego que vai/volta de seus pods. Mas, por meio dela, é possível garantir uma interface/sintaxe única para bloquear o tráfego para o seu host e pods com as políticas do Calico. Isso simplifica significativamente o processo de gerenciamento de políticas para uma rede heterogênea. A configuração de políticas de endpoint de host para fortalecer a proteção do cluster é outro caso importante de sua aplicação.
Política ApplyOnForward (3)
A opção ApplyOnForward está disponível na política de rede global do Calico para permitir a aplicação de políticas a todo o tráfego que passa pelo endpoint de host, incluindo o tráfego que será encaminhado pelo host. Esse tráfego inclui aquele que é direcionado a um pod local ou para qualquer outro lugar na rede. O Calico exige que essa opção esteja habilitada para políticas que utilizam PreDNAT e untracked, consulte as seções seguintes. Além disso, o ApplyOnForward pode ser usado para monitorar o tráfego do host em casos de uso de roteadores virtuais ou NATs de software.
Observe que se você precisar aplicar a mesma política de rede tanto para processos de host quanto para pods, não é necessário usar a opção ApplyOnForward. Basta criar um rótulo para os endpoints de host e os endpoints de workload (pod) necessários. O Calico é inteligente o suficiente para aplicar a política com base nos rótulos, independentemente do tipo de endpoint (hostendpoint ou workload).
Política PreDNAT (4)
No Kubernetes, as portas da entidade service podem ser expostas externamente usando a opção NodePorts ou, opcionalmente (ao usar Calico), por meio da declaração delas através das opções Cluster IPs ou External IPs. O Kube-proxy balanceia o tráfego de entrada associado ao service para os pods do respectivo service, utilizando DNAT. Dado isso, como você aplicaria políticas para o tráfego que chega através de NodePorts? Para que essas políticas sejam aplicadas antes que o tráfego seja processado pelo DNAT (que representa a correspondência host:porta e o respectivo service), o Calico fornece um parâmetro para globalNetworkPolicy chamado “preDNAT: true”.
Quando o pre-DNAT está ativado, essas políticas são realizadas em (4) no diagrama - na tabela mangle da cadeia PREROUTING - diretamente antes do DNAT. A ordem usual das políticas (order) não é mantida aqui, pois a aplicação dessas políticas ocorre muito antes no caminho de processamento do tráfego. No entanto, as políticas preDNAT respeitam a ordem de aplicação (order) entre si.
Ao criar políticas com pre-DNAT, é importante prestar atenção ao tráfego que você deseja processar e permitir que a maior parte seja rejeitada. O tráfego marcado como ‘allow’ na política pre-DNAT não será mais verificado pela política do hostendpoint, enquanto o tráfego que falhar na política pre-DNAT continuará seu caminho através das demais cadeias.
O Calico tornou obrigatório ativar a opção applyOnForward ao usar preDNAT, pois, por definição, o destino do tráfego ainda não foi selecionado. O tráfego pode ser direcionado para um processo de host, ou pode ser redirecionado para um pod ou para outro nó.
Política Untracked (5)
Redes e aplicativos podem ter grandes diferenças de comportamento. Em alguns casos extremos, os aplicativos podem gerar muitas conexões de curta duração. Isso pode levar à falta de memória do conntrack (componente principal da pilha de rede Linux). Tradicionalmente, para executar aplicativos desse tipo no Linux, você precisa configurar ou desabilitar manualmente o conntrack, ou escrever regras iptables para contornar o conntrack. A política untracked no Calico é uma opção mais simples e eficiente se você quiser lidar com conexões da forma mais rápida possível. Por exemplo, se você usar um массивный ou como uma medida adicional de proteção contra .
Leia este (ou ) para mais informações, incluindo testes de desempenho ao usar a política untracked.
Quando você define a opção “doNotTrack: true” na globalNetworkPolicy do Calico, ela se torna uma **política não rastreável** e é aplicada na fase mais inicial do pipeline de processamento de pacotes do Linux. Se observar o diagrama acima, as políticas untracked são aplicadas nas cadeias PREROUTING e OUTPUT na tabela raw, antes que o rastreamento de conexões (conntrack) seja iniciado. Quando um pacote é permitido pela política untracked, ele é marcado para desativar o rastreamento da conexão para esse pacote. Isso significa:
- A política untracked é aplicada a cada pacote. Não existe o conceito de conexão (ou fluxo). A ausência de conexões implica em várias consequências importantes:
- Se você quiser permitir tanto o tráfego de solicitações quanto o tráfego de respostas, você precisará de uma regra para tráfego de entrada e uma para tráfego de saída (uma vez que o Calico normalmente usa conntrack para marcar o tráfego de resposta como permitido).
- A política untracked não funciona para workloads do Kubernetes (pods), pois neste caso não há como rastrear uma conexão de saída de um pod.
- NAT não funciona corretamente com pacotes não rastreáveis (uma vez que o núcleo armazena a correspondência NAT em conntrack).
- Ao passar pela regra “permitir tudo” na política untracked, todos os pacotes serão marcados como não rastreáveis. Isso quase sempre não é o que você precisa, por isso é importante ser muito seletivo em relação aos pacotes permitidos pelas políticas untracked (e permitir que a maior parte do tráfego passe por políticas rastreadas normais).
- Políticas não rastreadas são aplicadas no início do pipeline de processamento de pacotes. Isso é muito importante entender ao criar políticas Calico. Você pode ter uma política para um pod com order:1 e uma política não rastreada com order:1000. Isso não fará diferença. A política não rastreada será aplicada antes da política para o pod. Políticas não rastreadas respeitam a ordem de execução apenas entre si.
Como um dos objetivos da política doNotTrack é forçar a aplicação da política na fase mais inicial do pipeline de processamento de pacotes do Linux, a Calico torna obrigatória a especificação da opção applyOnForward ao usar doNotTrack. Observando o diagrama de processamento de pacotes, note que a política não rastreada (5) é aplicada antes de qualquer decisão de roteamento. O tráfego pode ser direcionado para um processo no host, ou pode ser redirecionado para um pod ou para outro nó.
Resultados
Examinamos várias opções de políticas (endpoint de host, ApplyOnForward, preDNAT e Não Rastreado) na Calico e como elas são aplicadas no caminho de processamento de pacotes. Compreender a essência de seu funcionamento ajuda no desenvolvimento de políticas eficazes e seguras. Com a Calico, você pode usar políticas de rede globais, que são aplicadas a labels (grupos de nós e pods) e aplicar políticas com diferentes parâmetros. Isso permite que especialistas em segurança e design de redes protejam convenientemente "tudo" (tipos de endpoints), usando uma linguagem única de políticas com as políticas da Calico.
Agradecimento: Eu gostaria de agradecer e por suas revisões e por informações valiosas.
Fonte: habr.com
