Limitar o tráfego de rede com o Firewall do Azure no AKS (Serviço de Kubernetes do Azure)

Saiba como usar a rede de saída e as regras do FQDN para os clusters do AKS para controlar o tráfego de saída usando o Firewall do Azure no AKS. Para simplificar essa configuração, o Firewall do Azure fornece uma marca FQDN (AzureKubernetesServiceNome de Domínio Totalmente Qualificado) do Serviço de Kubernetes do Azure que restringe o tráfego de saída do cluster do AKS. Este artigo mostra como você pode configurar as regras de tráfego do Cluster do AKS por meio do firewall do Azure.

Observação

A marca FQDN contém todos os FQDNs listados em Rede de saída e regras do FQDN para os clusters do AKS e é atualizada automaticamente.

Para cenários de produção, recomendamos ter um mínimo de 20 IPs de front-end no Firewall do Azure para evitar problemas de exaustão da porta SNAT.

As informações a seguir fornecem um exemplo da arquitetura de implantação:

Topologia bloqueada

  • A entrada pública é forçada a fluir através dos filtros de firewall
    • Os nós do agente do AKS são isolados em uma sub-rede dedicada
    • O Firewall do Azure é implantado em sua própria sub-rede
    • Uma regra DNAT traduz o IP público do firewall no IP do front-end do balanceador de carga
  • As solicitações de saída partem dos nós do agente para o IP interno do Firewall do Azure usando uma rota definida pelo usuário (UDR)
    • As solicitações dos nós do agente do AKS seguem uma UDR que foi colocada em uma sub-rede na qual o cluster do AKS foi implantado
    • O Firewall do Azure sai da rede virtual de um front-end de IP público
    • Acesso à Internet pública ou outros fluxos de serviços do Azure fluem de e para o endereço IP de front-end do firewall
    • O acesso ao plano de controle do AKS pode ser protegido por intervalos de IP autorizados pelo servidor de API, incluindo o endereço IP de front-end público do firewall
  • Tráfego interno

Configurar 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

Provisione uma rede virtual com duas sub-redes separadas: uma para o cluster e outra para o firewall. Opcionalmente, você pode criar um para entrada no serviço interno.

Esvaziar a topologia de rede

  1. Crie um grupo de recursos usando o comando az group create.

    az group create --name $RG --location $LOC
    
  2. Crie uma rede virtual com duas sub-redes para hospedar o cluster do AKS e o Firewall do Azure usando os comandos az network vnet create e az network vnet subnet create.

    # 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 can't 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

Você precisa configurar as regras de entrada e saída do Firewall do Azure. O principal objetivo do firewall é permitir que as organizações configurem regras granulares de entrada e saída de tráfego para dentro e para fora do cluster do AKS.

Importante

Se seu cluster ou aplicativo criar um grande número de conexões de saída direcionadas para o mesmo ou para um pequeno subconjunto de destinos, talvez seja necessário mais IPs de front-end do firewall para evitar maximizar as portas por IP de front-end.

Para obter mais informações sobre como criar um Firewall do Azure com vários IPs, confira Criar um Firewall do Azure com vários endereços IP públicos usando o Bicep.

Firewall e UDR

  1. Crie um recurso de IP público de SKU padrão usando o comando az network public-ip create. Este recurso 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"
    
  2. Registre a extensão CLI do Firewall do Azure para criar um Firewall do Azure usando o comando az extension add.

    az extension add --name azure-firewall
    
  3. Crie um Firewall do Azure e habilite o proxy DNS usando o comando az network firewall create e definindo --enable-dns-proxy como true.

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

A configuração do endereço IP público para o Firewall do Azure pode levar alguns minutos. Quando estiver pronto, o endereço IP criado anteriormente pode ser atribuído ao front-end do firewall.

Observação

Para aproveitar o FQDN nas regras de rede, precisamos do proxy DNS ativado. Quando o proxy DNS está habilitado, o firewall escuta na porta 53 e encaminha solicitações de DNS para o servidor DNS especificado acima. Isso permite que o firewall converta o FQDN automaticamente.

  1. Crie uma configuração de IP do Firewall do Azure usando o comando az network firewall ip-config create.

    az network firewall ip-config create -g $RG -f $FWNAME -n $FWIPCONFIG_NAME --public-ip-address $FWPUBLICIP_NAME --vnet-name $VNET_NAME
    
  2. Assim que o comando anterior for bem-sucedido, salve o endereço IP do front-end do firewall para configuração posterior.

    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 uma rota 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ê quiser alterar qualquer um dos roteamentos padrão do Azure, você pode criar uma tabela de rotas.

Importante

O tipo de UDR de saída(userDefinedRouting) requer uma rota para 0.0.0.0/0 e um destino de próximo salto do NVA na tabela de rotas. A tabela de rotas já tem um padrão 0.0.0.0/0 para a Internet. Sem um endereço IP público para o Azure usar na Conversão de Endereços de Rede de Origem (SNAT), simplesmente adicionar essa rota não fornecerá conectividade com a Internet de saída. O AKS valida se você não criou uma rota 0.0.0.0/0 apontando para a Internet, mas sim para um gateway, NVA, etc. Ao usar um tipo de saída de UDR, um endereço IP público do balanceador de carga para solicitações de entrada não é criado, a menos que você configure um serviço do tipo balanceador de carga. O AKS nunca cria um endereço IP público para solicitações de saída se você definir um tipo de UDR de saída. Para obter mais informações, consulte Regras de Saída do Azure Load Balancer.

  1. Crie uma tabela de rota vazia para ser associada a uma determinada sub-rede usando o comando az network route-table create. A tabela de rotas definirá o próximo salto como o Firewall do Azure criado acima. Cada sub-rede pode ter zero ou uma tabela de rotas associada a ela.

    az network route-table create -g $RG -l $LOC --name $FWROUTE_TABLE_NAME
    
  2. Crie rotas na tabela de rotas para as sub-redes usando o comando az network route-table route create.

    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
    

Para obter informações sobre como substituir as rotas padrão do sistema do Azure ou adicionar rotas adicionais à tabela de rotas de uma sub-rede, confira a documentação da tabela de rotas da rede virtual.

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 uma regra de aplicativo para fqdn-tag AzureKubernetesService.

Esta seção aborda três regras de rede e uma regra de aplicativo que você pode usar para configurar no seu firewall. Talvez seja necessário adaptar essas regras com base na sua implantação.

  • A primeira regra de rede permite o acesso à porta 9000 via TCP.
  • A segunda regra de rede permite o acesso às portas 1194 e 123 via UDP. Se estiver implantando no Microsoft Azure operado pela 21Vianet, confira as regras de rede obrigatórias do Azure operado pela 21Vianet. Ambas as regras permitirão apenas o tráfego destinado ao CIDR da Região do Azure neste artigo, que é a região Leste dos EUA.
  • A terceira regra de rede abre a porta 123 para o FQDN ntp.ubuntu.com via UDP. Adicionar um FQDN como uma regra de rede é um dos recursos específicos do Firewall do Azure, portanto, você precisará adaptá-lo ao usar suas próprias opções.
  • A quarta e quinta regras de rede permitem o acesso a contêineres pull do Registro de Contêiner do GitHub (ghcr.io) e do Hub do Docker (docker.io).
  1. Crie as regras de rede usando o comando az network firewall network-rule create.

    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
    
    az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'ghcr' --protocols 'TCP' --source-addresses '*' --destination-fqdns ghcr.io pkg-containers.githubusercontent.com --destination-ports '443'
    
    az network firewall network-rule create -g $RG -f $FWNAME --collection-name 'aksfwnr' -n 'docker' --protocols 'TCP' --source-addresses '*' --destination-fqdns docker.io registry-1.docker.io production.cloudflare.docker.com --destination-ports '443'
    
  2. Crie a regra do aplicativo usando o comando az network firewall application-rule create.

    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
    

Para obter mais informações sobre o Firewall do Azure, consulte a documentaçã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 acima. Use o comando az network vnet subnet update para associar a tabela de rotas ao AKS.

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

Implantar um cluster do AKS que segue suas regras de saída

Agora, você pode implantar um cluster do AKS na rede virtual existente. Você usará o userDefinedRouting tipo de saída, que garante que qualquer tráfego de saída seja forçado através do firewall e que nenhum outro caminho de saída exista. O loadBalancer tipo de saída também pode ser usado.

aks-deploy

A sub-rede de destino a ser implantada é definida com a variável de ambiente, $SUBNETID. Defina o valor da ID da sub-rede usando o seguinte comando:

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

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

Dica

Você pode adicionar outros recursos à implantação do cluster, como clusters privados.

Você pode adicionar o recurso do AKS aos intervalos de IP autorizados pelo servidor de API para limitar o acesso do servidor de API apenas 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 ao servidor de API, suas ferramentas de desenvolvedor devem usar um jumpbox a partir da rede virtual do firewall ou você deve adicionar todos os pontos de extremidade do desenvolvedor ao intervalo de IP autorizado.


Observação

O AKS criará uma identidade kubelet atribuída pelo sistema no grupo de recursos de nó se você não especificar sua própria identidade gerenciada pelo kubelet.

Para o roteamento definido pelo usuário, a identidade atribuída pelo sistema suporta apenas o plugin da rede CNI.

Crie um cluster do AKS usando uma identidade gerenciada atribuída pelo sistema com o plugin da rede CNI usando o comando az aks create.

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

Habilitar o acesso do desenvolvedor ao servidor de API

Se você usou intervalos de IP autorizados para seu cluster na etapa anterior, precisará adicionar os endereços IP das ferramentas de desenvolvedor à lista de intervalos de IP aprovados do cluster do AKS para acessar o servidor de API a partir daí. Você também pode configurar um jumpbox com as ferramentas necessárias dentro de uma sub-rede separada na rede virtual do firewall.

  1. Recupere seu endereço IP usando o comando a seguir:

    CURRENT_IP=$(dig @resolver1.opendns.com ANY myip.opendns.com +short)
    
  2. Adicione o endereço IP aos intervalos aprovados usando o comando az aks update.

    az aks update -g $RG -n $AKSNAME --api-server-authorized-ip-ranges $CURRENT_IP/32
    
  3. Configure kubectl para se conectar ao seu cluster do AKS usando o comando az aks get-credentials.

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

Implantar um serviço público no AKS

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 querer expor um serviço interno usando um 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
    

Permitir tráfego de entrada por meio do Firewall do Azure

Importante

Quando você usa o Firewall do Azure para restringir o tráfego de saída e criar uma UDR para forçar todo o tráfego de saída, certifique-se de criar uma regra DNAT apropriada no Firewall do Azure 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 que vai para o endereço IP privado do firewall, mas você está usando um balanceador de carga público, serviço do Kubernetes ou entrada do tipo 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, você precisa escrever uma regra DNAT 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. 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. Você também precisa especificar o endereço IP interno atribuído ao balanceador de carga criado pelo serviço do Kubernetes.

  1. Obtenha o endereço IP interno atribuído ao balanceador de carga usando o comando kubectl get services.

    kubectl get services
    

    O endereço IP será listado na coluna EXTERNAL-IP, conforme mostrado no exemplo de saída a seguir:

    NAME              TYPE           CLUSTER-IP     EXTERNAL-IP   PORT(S)              AGE
    kubernetes        ClusterIP      10.0.0.1       <none>        443/TCP              9m10s
    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
    store-front       LoadBalancer   10.0.89.139    20.39.18.6    80:32271/TCP         10s
    
  2. Obtenha o IP do serviço usando o comando kubectl get svc voting-app.

    SERVICE_IP=$(kubectl get svc store-front -o jsonpath='{.status.loadBalancer.ingress[*].ip}')
    
  3. Adicione a regra NAT usando o comando az network firewall nat-rule create.

    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 52.253.228.132.

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 usando o comando az group delete.

az group delete -g $RG

Próximas etapas

Neste artigo, você aprendeu a proteger seu tráfego de saída usando o Firewall do Azure. Se necessário, você pode generalizar as etapas acima para encaminhar o tráfego para sua solução de saída preferida seguindo a documentação userDefinedRoute Tipo de Saída.