Usar o Firewall do Azure para proteger clusters do AKS (Serviço de Kubernetes do Azure)

Este artigo mostra como você pode proteger clusters do AKS (Serviço de Kubernetes do Azure) usando o Firewall do Azure para proteger o tráfego de saída e de entrada.

Tela de fundo

O Serviço do Kubernetes do Azure (AKS) oferece um cluster do Kubernetes gerenciado no Azure. Para obter mais informações, confira Serviço de Kubernetes do Azure.

Apesar de o AKS ser uma solução totalmente gerenciada, ele não oferece uma solução interna para proteger o tráfego de entrada e de saída entre o cluster e as redes externas. O Firewall do Azure oferece uma solução para isso.

Os clusters do AKS são implantados em uma rede virtual. Essa rede pode ser gerenciada (criada pelo AKS) ou personalizada (pré-configurada pelo usuário com antecedência). Em ambos os casos, o cluster tem dependências de saída em serviços fora dessa rede virtual (o serviço não tem dependências de entrada). Para fins operacionais e de gerenciamento, os nós em um cluster do AKS precisam acessar certas portas e nomes de domínio totalmente qualificados (FQDNs) específicos que detalham essas dependências de saída. Isso é necessário para várias funções, incluindo, sem limitações, os nós que se comunicam com o servidor de API do Kubernetes. Eles baixam e instalam os principais componentes do cluster do Kubernetes e atualizações de segurança de nó, ou efetuam pull de imagens de contêiner do sistema base do MCR (Registro de Contêiner da Microsoft) e assim por diante. As dependências de saída do AKS são quase que totalmente definidas com FQDNs, que não têm endereços estáticos por trás deles. A falta de endereços estáticos significa que Grupos de Segurança de Rede não podem ser usados para bloquear o tráfego de saída de um cluster do AKS. Dessa maneira, por padrão, os clusters do AKS têm acesso irrestrito à Internet de saída. Esse nível de acesso à rede permite que os nós e os serviços que você executa acessem recursos externos, conforme necessário.

No entanto, em um ambiente de produção, as comunicações com um cluster do Kubernetes devem ser protegidas para evitar a exfiltração de dados, bem como outras vulnerabilidades. Todo o tráfego de rede de entrada e de saída deve ser monitorado e controlado com base em um conjunto de regras de segurança. Para fazer isso, você precisa restringir o tráfego de saída, mas um número limitado de portas e endereços deve permanecer acessível para preservar tarefas de manutenção de cluster íntegras e atender às dependências de saída mencionadas anteriormente.

A solução mais simples é usar um dispositivo de firewall que possa controlar o tráfego de saída com base nos nomes de domínio. Normalmente, um firewall forma uma barreira entre uma rede confiável e uma rede não confiável, como a Internet. O Firewall do Azure, por exemplo, pode restringir o tráfego HTTP e HTTPS de saída com base no FQDN do destino, proporcionando um controle refinado do tráfego de saída, mas ao mesmo tempo permite que você forneça acesso aos FQDNs que abrangem as dependências de saída de um cluster do AKS (algo que os NSGs não podem fazer). Da mesma forma, você pode controlar o tráfego de entrada e aumentar a segurança habilitando a filtragem baseada em inteligência contra ameaças em um Firewall do Azure implantado em uma rede de perímetro compartilhado. Essa filtragem pode gerar alertas e negar o tráfego proveniente e destinado a endereços IP e domínios mal-intencionados conhecidos.

Confira o vídeo a seguir para ter uma visão geral rápida sobre como isso funciona na prática em um ambiente de exemplo:

Você pode fazer download de um arquivo zip do Centro de Download da Microsoft que contém um arquivo de script bash e um arquivo yaml para configurar automaticamente o ambiente de exemplo usado no vídeo. Ele configura o Firewall do Azure para proteger tanto o tráfego de entrada quanto o de saída. Os guias a seguir percorrem cada etapa do script com mais detalhes para que você possa definir uma configuração personalizada.

O diagrama a seguir mostra o ambiente de exemplo do vídeo que o script e o guia configuram:

Diagrama mostrando o cluster do AKS com o Firewall do Azure para filtragem de entrada e de saída.

Há uma diferença entre o script e o guia a seguir. O script usa identidades gerenciadas e o guia usa uma entidade de serviço. Isso mostra duas maneiras diferentes de criar uma identidade para gerenciar e criar recursos de cluster.

Restringir o tráfego de saída usando o Firewall do Azure

Definir configuração por meio de variáveis de ambiente

Defina um conjunto de variáveis de ambiente a ser usado em criações de recursos.

PREFIX="aks-egress"
RG="${PREFIX}-rg"
LOC="eastus"
PLUGIN=azure
AKSNAME="${PREFIX}"
VNET_NAME="${PREFIX}-vnet"
AKSSUBNET_NAME="aks-subnet"
# DO NOT CHANGE FWSUBNET_NAME - This is currently a requirement for Azure Firewall.
FWSUBNET_NAME="AzureFirewallSubnet"
FWNAME="${PREFIX}-fw"
FWPUBLICIP_NAME="${PREFIX}-fwpublicip"
FWIPCONFIG_NAME="${PREFIX}-fwconfig"
FWROUTE_TABLE_NAME="${PREFIX}-fwrt"
FWROUTE_NAME="${PREFIX}-fwrn"
FWROUTE_NAME_INTERNET="${PREFIX}-fwinternet"

Criar uma rede virtual com várias sub-redes

Crie uma rede virtual com duas sub-redes separadas: uma para o cluster e a outra para o firewall. Opcionalmente, você também pode criar uma para entrada de serviço interno.

Esvaziar a topologia de rede

Crie um grupo de recursos para armazenar todos os recursos.

# Create Resource Group

az group create --name $RG --location $LOC

Crie uma rede virtual com duas sub-redes para hospedar o cluster do AKS e o Firewall do Azure. Cada um tem sua própria sub-rede. Vamos começar com a rede do AKS.

# Dedicated virtual network with AKS subnet

az network vnet create \
    --resource-group $RG \
    --name $VNET_NAME \
    --location $LOC \
    --address-prefixes 10.42.0.0/16 \
    --subnet-name $AKSSUBNET_NAME \
    --subnet-prefix 10.42.1.0/24

# Dedicated subnet for Azure Firewall (Firewall name cannot be changed)

az network vnet subnet create \
    --resource-group $RG \
    --vnet-name $VNET_NAME \
    --name $FWSUBNET_NAME \
    --address-prefix 10.42.2.0/24

Criar e configurar um Firewall do Azure com uma UDR

As regras de entrada e saída do Firewall do Azure devem ser configuradas. A principal finalidade do firewall é permitir que as organizações configurem as regras de tráfego de entrada e saída granulares para dentro e fora do cluster do AKS.

Firewall e UDR

Importante

Se o cluster ou o aplicativo criar um grande número de conexões de saída direcionadas para o mesmo subconjunto de destinos ou um subconjunto pequeno, você poderá exigir mais IPs de front-end de firewall para evitar o limite máximo das portas por IP de front-end. Para obter mais informações sobre como criar um firewall do Azure com vários IPs, consulte aqui

Crie um recurso de IP público de SKU padrão que será usado como o endereço de front-end do Firewall do Azure.

az network public-ip create -g $RG -n $FWPUBLICIP_NAME -l $LOC --sku "Standard"

Registre a extensão da CLI de versão prévia para criar um Firewall do Azure.

# Install Azure Firewall preview CLI extension

az extension add --name azure-firewall

# Deploy Azure Firewall

az network firewall create -g $RG -n $FWNAME -l $LOC --enable-dns-proxy true

O endereço IP criado anteriormente agora pode ser atribuído ao front-end do firewall.

Observação

A configuração do endereço IP público para o Firewall do Azure pode levar alguns minutos. Para aproveitar o FQDN nas regras de rede, precisamos do proxy de DNS habilitado. Quando habilitado, o firewall escutará na porta 53 e encaminhará as solicitações de DNS para o servidor DNS especificado anteriormente. Isso permitirá que o firewall converta esse FQDN automaticamente.

# Configure Firewall IP Config

az network firewall ip-config create -g $RG -f $FWNAME -n $FWIPCONFIG_NAME --public-ip-address $FWPUBLICIP_NAME --vnet-name $VNET_NAME

Quando o comando anterior tiver sido bem-sucedido, salve o endereço IP de front-end do firewall para configuração posterior.

# Capture Firewall IP Address for Later Use

FWPUBLIC_IP=$(az network public-ip show -g $RG -n $FWPUBLICIP_NAME --query "ipAddress" -o tsv)
FWPRIVATE_IP=$(az network firewall show -g $RG -n $FWNAME --query "ipConfigurations[0].privateIPAddress" -o tsv)

Observação

Se você usar o acesso seguro ao servidor de API do AKS com intervalos de endereços IP autorizados, precisará adicionar o IP público do firewall ao intervalo de IP autorizado.

Criar um UDR com um salto para o Firewall do Azure

O Azure roteia o tráfego automaticamente entre redes virtuais, redes locais e sub-redes do Azure. Se você desejar alterar qualquer roteamento padrão do Azure, poderá criar uma tabela de rotas para fazer isso.

Crie uma tabela de rotas vazia a ser associada a uma determinada sub-rede. A tabela de rotas definirá o próximo salto como o Firewall do Azure criado anteriormente. Cada sub-rede pode ter zero ou uma tabela de rotas associada a ela.

# Create UDR and add a route for Azure Firewall

az network route-table create -g $RG -l $LOC --name $FWROUTE_TABLE_NAME
az network route-table route create -g $RG --name $FWROUTE_NAME --route-table-name $FWROUTE_TABLE_NAME --address-prefix 0.0.0.0/0 --next-hop-type VirtualAppliance --next-hop-ip-address $FWPRIVATE_IP
az network route-table route create -g $RG --name $FWROUTE_NAME_INTERNET --route-table-name $FWROUTE_TABLE_NAME --address-prefix $FWPUBLIC_IP/32 --next-hop-type Internet

Confira a documentação da tabela de rotas de rede virtual sobre como é possível substituir as rotas do sistema padrão do Azure ou adicionar outras rotas a uma tabela de rotas de uma sub-rede.

Adicionar regras de firewall

Observação

Para aplicativos fora dos namespaces kube-system ou gatekeeper-system que precisam se comunicar com o servidor de API, é necessária uma regra de rede adicional para permitir a comunicação TCP com a porta 443 para o IP do servidor de API, além de adicionar a regra de aplicativo para fqdn-tag AzureKubernetesService.

Você pode usar as três regras de rede a seguir para configurar o firewall. Talvez seja necessário adaptar essas regras com base na sua implantação. A primeira regra permite o acesso à porta 9000 por meio do TCP. A segunda regra permite o acesso às portas 1194 e 123 por meio do UDP. Essas duas regras permitem apenas o tráfego destinado ao CIDR da região do Azure que estamos usando, neste caso, Leste dos EUA.

Finalmente, adicionaremos uma terceira regra de rede que abre a porta 123 a um servidor de tempo de uso da Internet com FQDN (por exemplo:ntp.ubuntu.com) via UDP. A adição de um FQDN como regra de rede é uma dos recursos específicos do Firewall do Azure, e você precisará adaptá-lo ao usar suas próprias opções.

Depois de definir as regras de rede, adicionaremos também uma regra de aplicativo usando o AzureKubernetesService que abrange os FQDNs necessários acessíveis por meio da porta TCP 443 e da porta 80. Além disso, talvez seja necessário configurar mais regras de rede e aplicativo com base na implantação. Para obter mais informações, confira Regras de rede de saída e FQDN para clusters do Serviço de Kubernetes do Azure (AKS)

Adicionar Regras de Rede de FW

az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'apiudp' --protocols 'UDP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 1194 --action allow --priority 100
az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'apitcp' --protocols 'TCP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 9000
az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'time' --protocols 'UDP' --source-addresses '*' --destination-fqdns 'ntp.ubuntu.com' --destination-ports 123

Adicionar Regras de Aplicativo de FW

az network firewall application-rule create -g $RG -f $FWNAME --collection-name 'aksfwar' -n 'fqdn' --source-addresses '*' --protocols 'http=80' 'https=443' --fqdn-tags "AzureKubernetesService" --action allow --priority 100

Confira a documentação do Firewall do Azure para saber mais sobre o serviço do Firewall do Azure.

Associe a tabela de rotas ao AKS

Para associar o cluster ao firewall, a sub-rede dedicada para a sub-rede do cluster deve fazer referência à tabela de rotas criada anteriormente. A associação pode ser feita emitindo um comando para a rede virtual que mantém o cluster e o firewall para atualizar a tabela de rotas da sub-rede do cluster.

# Associate route table with next hop to Firewall to the AKS subnet

az network vnet subnet update -g $RG --vnet-name $VNET_NAME --name $AKSSUBNET_NAME --route-table $FWROUTE_TABLE_NAME

Implantar o AKS com o tipo de saída do UDR na rede existente

Agora, um cluster do AKS pode ser implantado na rede virtual existente. Você também usa o tipo de saída userDefinedRouting. Esse recurso garante que qualquer tráfego de saída seja forçado a passar pelo firewall e que não haja nenhum outro caminho de saída (por padrão, é possível usar o tipo de saída Balanceador de Carga).

aks-deploy

A sub-rede de destino a ser implantada é definida com a variável de ambiente, $SUBNETID. Não definimos a variável $SUBNETID nas etapas anteriores. Para definir o valor da ID de sub-rede, você pode usar o seguinte comando:

SUBNETID=$(az network vnet subnet show -g $RG --vnet-name $VNET_NAME --name $AKSSUBNET_NAME --query id -o tsv)

Defina o tipo de saída para usar o UDR que já existe na sub-rede. Essa configuração permite que o AKS ignore a configuração e o provisionamento de IP para o balanceador de carga.

Importante

Para obter mais informações sobre a UDR do tipo de saída, incluindo limitações, consulte UDR do tipo de saída.

Dica

Recursos adicionais podem ser adicionados à implantação de cluster, como Cluster privado ou alterando a OS SKU.

O recurso do AKS para intervalos de IP autorizados do servidor de API pode ser adicionado para limitar o acesso do servidor de API somente ao ponto de extremidade público do firewall. O recurso de intervalos de IP autorizados é indicado no diagrama como opcional. Ao habilitar o recurso de intervalo de IP autorizado para limitar o acesso do servidor de API, suas ferramentas de desenvolvedor deverão usar um Jumpbox da rede virtual do firewall ou você deverá adicionar todos os pontos de extremidade do desenvolvedor ao intervalo de IP autorizado.

az aks create -g $RG -n $AKSNAME -l $LOC \
  --node-count 3 \
  --network-plugin azure \
  --outbound-type userDefinedRouting \
  --vnet-subnet-id $SUBNETID \
  --api-server-authorized-ip-ranges $FWPUBLIC_IP

Observação

Para criar e usar sua própria VNet e tabela de rotas com o plug-in de rede kubenet, é necessário usar uma identidade gerenciada atribuída pelo usuário. Para uma identidade gerenciada atribuída pelo sistema, não é possível obter a ID de identidade antes de criar o cluster, o que causa um atraso na atribuição de função entrando em vigor.

Há suporte para identidades gerenciadas atribuídas pelo sistema e pelo usuário para criar e usar sua própria VNet e a tabela de rotas com o plug-in de rede azure.

Habilitar o acesso do desenvolvedor ao servidor de API

Se você usou intervalos de IP autorizados para o cluster na etapa anterior, deverá adicionar os endereços IP de suas ferramentas de desenvolvedor à lista de intervalos de IP aprovados do cluster do AKS para acessar o servidor de API a partir daí. Outra opção é configurar um Jumpbox com as ferramentas necessárias dentro de uma sub-rede separada na rede virtual do firewall.

Adicionar outro endereço IP aos intervalos aprovados com o seguinte comando

# Retrieve your IP address
CURRENT_IP=$(dig @resolver1.opendns.com ANY myip.opendns.com +short)

# Add to AKS approved list
az aks update -g $RG -n $AKSNAME --api-server-authorized-ip-ranges $CURRENT_IP/32

Use o comando az aks get-credentials para configurar kubectl e se conectar ao seu cluster do Kubernetes recém-criado.

az aks get-credentials -g $RG -n $AKSNAME

Restringir o tráfego de entrada usando o Firewall do Azure

Agora você pode começar a expor serviços e implantar aplicativos nesse cluster. Neste exemplo, vamos expor um serviço público, mas você também pode optar por expor um serviço interno por meio do balanceador de carga interno.

DNAT de serviço público

  1. Examine o guia de início rápido da Demonstração do AKS Store manifesto para ver todos os recursos que serão criados.

  2. Implemente o serviço usando o comando kubectl apply.

    kubectl apply -f https://raw.githubusercontent.com/Azure-Samples/aks-store-demo/main/aks-store-quickstart.yaml
    

Adicionar uma regra DNAT ao Firewall do Azure

Importante

Ao usar o Firewall do Azure para restringir o tráfego de saída e criar uma rota definida pelo usuário (UDR) para forçar todo o tráfego de saída, crie uma regra DNAT apropriada no firewall para permitir corretamente o tráfego de entrada. Usar o Firewall do Azure com uma UDR interrompe a configuração de entrada devido ao roteamento assimétrico. (O problema ocorre se a sub-rede do AKS tiver uma rota padrão para o endereço IP privado do firewall e você estiver usando um balanceador de carga de entrada ou serviço do tipo do Kubernetes: LoadBalancer). Nesse caso, o tráfego de entrada do balanceador de carga é recebido por meio de seu endereço IP público, mas o caminho de retorno passa pelo endereço IP privado do firewall. Como o firewall tem monitoramento de estado, ele descarta o pacote de retorno porque o firewall não está ciente de uma sessão estabelecida. Para saber como integrar o Firewall do Azure com o balanceador de carga de serviço ou de entrada, confira Integrar o Firewall do Azure com o Azure Standard Load Balancer.

Para configurar a conectividade de entrada, uma regra DNAT deve ser gravada no Firewall do Azure. Para testar a conectividade com o seu cluster, uma regra é definida para o endereço IP público de front-end do firewall para rotear para o IP interno exposto pelo serviço interno.

O endereço de destino pode ser personalizado, pois ele é a porta no firewall a ser acessado. O endereço traduzido deve ser o endereço IP do balanceador de carga interno. A porta traduzida deve ser a porta exposta para o serviço de Kubernetes.

Será necessário especificar o endereço IP interno atribuído ao balanceador de carga criado pelo serviço de Kubernetes. Recupere o endereço executando:

kubectl get services

O endereço IP necessário é listado na coluna EXTERNAL-IP semelhante à seguinte.

NAME               TYPE           CLUSTER-IP      EXTERNAL-IP       PORT(S)                AGE
kubernetes         ClusterIP      10.41.0.1       <none>            443/TCP                10h
store-front        LoadBalancer   10.41.185.82    203.0.113.254     80:32718/TCP           9m
order-service      ClusterIP      10.0.104.144    <none>            3000/TCP               11s
product-service    ClusterIP      10.0.237.60     <none>            3002/TCP               10s
rabbitmq           ClusterIP      10.0.161.128    <none>            5672/TCP,15672/TCP     11s

Obtenha o IP do serviço, executando:

SERVICE_IP=$(kubectl get svc store-front -o jsonpath='{.status.loadBalancer.ingress[*].ip}')

Adicione a regra de NAT, executando:

az network firewall nat-rule create --collection-name exampleset --destination-addresses $FWPUBLIC_IP --destination-ports 80 --firewall-name $FWNAME --name inboundrule --protocols Any --resource-group $RG --source-addresses '*' --translated-port 80 --action Dnat --priority 100 --translated-address $SERVICE_IP

Validar a conectividade

Navegue até o endereço IP de front-end do Firewall do Azure em um navegador para validar a conectividade.

Você deve ver o aplicativo da loja do AKS. Neste exemplo, o IP público do firewall era 203.0.113.32.

Captura de tela mostrando o aplicativo Azure Store Front aberto em um navegador local.

Nesta página, você pode exibir produtos, adicioná-los ao carrinho e fazer um pedido.

Limpar os recursos

Para limpar os recursos do Azure, exclua o grupo de recursos do AKS.

az group delete -g $RG

Próximas etapas