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

Saiba como usar as regras de rede de saída e FQDN para clusters 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 (Nome de Domínio Totalmente Qualificado) do Serviço Kubernetes do Azure (AzureKubernetesService) que restringe o tráfego de saída do cluster AKS. Este artigo mostra como você pode configurar suas regras de tráfego do Cluster AKS por meio do firewall do Azure.

Nota

A tag FQDN contém todos os FQDNs listados em Rede de saída e regras FQDN para clusters 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 esgotamento da porta SNAT.

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

Topologia bloqueada

  • A entrada pública é forçada a fluir através de filtros de firewall
    • Os nós do agente AKS são isolados em uma sub-rede dedicada
    • O Firewall do Azure é implantado em sua própria sub-rede
    • Uma regra DNAT converte o IP público do firewall no IP frontend do balanceador de carga
  • As solicitações de saída começam 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 AKS seguem um UDR que foi colocado na sub-rede na qual o cluster AKS foi implantado
    • O Firewall do Azure sai da rede virtual de um frontend IP público
    • O acesso à Internet pública ou a outros serviços do Azure flui de e para o endereço IP frontend do firewall
    • O acesso ao plano de controle AKS pode ser protegido por intervalos de IP autorizados pelo servidor API, incluindo o endereço IP frontend público do firewall
  • Tráfego interno

Configurar variáveis de ambiente

Defina um conjunto de variáveis de ambiente a serem usadas 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 de serviço interno.

Topologia de rede vazia

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

    az group create --name $RG --location $LOC
    
  2. Crie uma rede virtual com duas sub-redes para hospedar o cluster AKS e o Firewall do Azure usando os az network vnet create comandos and 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 dentro e fora do cluster AKS.

Importante

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

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

Firewall e UDR

  1. Crie um recurso IP público SKU padrão usando o az network public-ip create comando. Este recurso será usado como o endereço de front-end do Firewall do Azure.

    az network public-ip create --resource-group $RG -n $FWPUBLICIP_NAME --location $LOC --sku "Standard"
    
  2. Registre a extensão da CLI do Firewall do Azure para criar um Firewall do Azure usando o az extension add comando.

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

    az network firewall create --resource-group $RG --name $FWNAME --location $LOC --enable-dns-proxy true
    

Configurar o 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.

Nota

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

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

    az network firewall ip-config create --resource-group $RG --firewall-name $FWNAME --name $FWIPCONFIG_NAME --public-ip-address $FWPUBLICIP_NAME --vnet-name $VNET_NAME
    
  2. Quando o comando anterior for bem-sucedido, salve o endereço IP frontend do firewall para configuração posterior.

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

Criar uma rota com um salto para o Firewall do Azure

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

Importante

O tipo de saída de UDR (userDefinedRouting) requer uma rota para 0.0.0.0/0 e um destino de próximo salto de 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 para SNAT (Tradução de Endereço de Rede de Origem), simplesmente adicionar essa rota não fornecerá conectividade de saída com a Internet. O AKS valida que você não cria uma rota 0.0.0.0/0 apontando para a Internet, mas sim para um gateway, NVA, etc. Ao usar um tipo de UDR de saída, 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 loadbalancer. 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 para o Azure Load Balancer.

  1. Crie uma tabela de rotas vazia para ser associada a uma determinada sub-rede usando o az network route-table create comando. 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 si.

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

    az network route-table route create --resource-group $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 --resource-group $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, consulte a documentação da tabela de rotas de rede virtual.

Adicionar regras de firewall

Nota

Para aplicativos fora dos namespaces kube-system ou gatekeeper-system que precisam falar 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 .

Esta seção aborda três regras de rede e uma regra de aplicativo que você pode usar para configurar no firewall. Talvez seja necessário adaptar essas regras com base em 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 você estiver implantando no Microsoft Azure operado pela 21Vianet, consulte as regras de rede necessá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 é Leste dos EUA.
  • A terceira regra de rede abre a porta 123 para ntp.ubuntu.com FQDN 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 GitHub Container Registry (ghcr.io) e do Docker Hub (docker.io).
  1. Crie as regras de rede usando o az network firewall network-rule create comando.

    az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'apiudp' --protocols 'UDP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 1194 --action allow --priority 100
    
    az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'apitcp' --protocols 'TCP' --source-addresses '*' --destination-addresses "AzureCloud.$LOC" --destination-ports 9000
    
    az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'time' --protocols 'UDP' --source-addresses '*' --destination-fqdns 'ntp.ubuntu.com' --destination-ports 123
    
    az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'ghcr' --protocols 'TCP' --source-addresses '*' --destination-fqdns ghcr.io pkg-containers.githubusercontent.com --destination-ports '443'
    
    az network firewall network-rule create --resource-group $RG --firewall-name $FWNAME --collection-name 'aksfwnr' --name 'docker' --protocols 'TCP' --source-addresses '*' --destination-fqdns docker.io registry-1.docker.io production.cloudflare.docker.com --destination-ports '443'
    
  2. Crie a regra de aplicativo usando o az network firewall application-rule create comando.

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

Para saber mais sobre o Firewall do Azure, consulte a documentação do Firewall do Azure.

Associar 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 az network vnet subnet update comando para associar a tabela de rotas ao AKS.

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

Implantar um cluster AKS que siga suas regras de saída

Agora, você pode implantar um cluster 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 nenhum outro caminho de saída exista. O loadBalancer tipo de saída também pode ser usado.

AKS-Implantar

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

SUBNETID=$(az network vnet subnet show --resource-group $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 instalação e o provisionamento de IP para o balanceador de carga.

Gorjeta

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

Você pode adicionar o recurso AKS para intervalos de IP autorizados pelo servidor API para limitar o acesso do servidor 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 uma jumpbox da rede virtual do firewall ou você deve adicionar todos os pontos de extremidade do desenvolvedor ao intervalo de IP autorizado.


Nota

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

Para roteamento definido pelo usuário, a identidade atribuída ao sistema suporta apenas o plug-in de rede CNI.

Crie um cluster AKS usando uma identidade gerenciada atribuída ao sistema com o plug-in de rede CNI usando o az aks create comando.

az aks create --resource-group $RG --name $AKSNAME --location $LOC \
    --node-count 3 \
    --network-plugin azure \
    --outbound-type userDefinedRouting \
    --vnet-subnet-id $SUBNETID \
    --api-server-authorized-ip-ranges $FWPUBLIC_IP \
    --generate-ssh-keys

Habilite o acesso do desenvolvedor ao servidor de API

Se você usou intervalos de IP autorizados para seu cluster na etapa anterior, precisará adicionar seus endereços IP de ferramentas de desenvolvedor à lista de clusters AKS de intervalos IP aprovados para acessar o servidor de API a partir daí. Você também pode configurar uma 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 seguinte comando:

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

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

    az aks get-credentials --resource-group $RG --name $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 do Serviço Público

  1. Reveja o manifesto de início rápido AKS Store Demo para ver todos os recursos que serão criados.

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

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

Permitir tráfego de entrada através da Firewall do Azure

Importante

Ao usar o Firewall do Azure para restringir o tráfego de saída e criar um 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 um UDR interrompe a configuração de entrada devido ao roteamento assimétrico. O problema ocorre se a sub-rede AKS tiver uma rota padrão que vá para o endereço IP privado do firewall, mas você estiver usando um balanceador de carga público - ingress ou serviço Kubernetes do tipo loadBalancer. Nesse caso, o tráfego do balanceador de carga de entrada é 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 monitoração de estado, ele descarta o pacote que retorna porque o firewall não está ciente de uma sessão estabelecida. Para saber como integrar o Firewall do Azure ao seu balanceador de carga de entrada ou serviço, consulte Integrar o Firewall do Azure ao Balanceador de Carga Padrão do Azure.

Para configurar a conectividade de entrada, você precisa escrever uma regra DNAT no Firewall do Azure. Para testar a conectividade com o cluster, é definida uma regra para que o endereço IP público front-end do firewall seja encaminhado 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 Kubernetes. Você também precisa especificar o endereço IP interno atribuído ao balanceador de carga criado pelo serviço Kubernetes.

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

    kubectl get services
    

    O endereço IP será listado EXTERNAL-IP na coluna, conforme mostrado na saída de exemplo 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 kubectl get svc store-front comando.

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

    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 AKS. Neste exemplo, o IP público do firewall era 52.253.228.132.

Captura de ecrã a mostrar a Aplicação Frontal da Loja Azure aberta num browser local.

Nesta página, pode ver produtos, adicioná-los ao carrinho e, em seguida, fazer uma encomenda.

Clean up resources (Limpar recursos)

Para limpar os recursos do Azure, exclua o grupo de recursos AKS usando o az group delete comando.

az group delete --name $RG

Próximos passos

Neste artigo, você aprendeu como 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 do Tipo userDefinedRoute de saída.