Usar o Firewall do Azure para proteger clusters do Serviço Kubernetes do Azure (AKS)
Este artigo mostra como você pode proteger clusters do Serviço Kubernetes do Azure (AKS) usando o Firewall do Azure para proteger o tráfego de entrada e saída.
Fundo
O Serviço Kubernetes do Azure (AKS) oferece um cluster Kubernetes gerenciado no Azure. Para obter mais informações, consulte Serviço Kubernetes do Azure.
Apesar do AKS ser uma solução totalmente gerenciada, ele não oferece uma solução integrada para proteger o tráfego de entrada e saída entre o cluster e as redes externas. O Firewall do Azure oferece uma solução para isso.
Os clusters AKS são implantados em uma rede virtual. Esta rede pode ser gerida (criada pelo AKS) ou personalizada (pré-configurada pelo utilizador previamente). 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 AKS precisam acessar determinadas portas e FQDNs (nomes de domínio totalmente qualificados) que descrevem essas dependências de saída. Isso é necessário para várias funções, incluindo, mas não limitado a, nós que se comunicam com o servidor de API do Kubernetes. Eles baixam e instalam os principais componentes de cluster do Kubernetes e as atualizações de segurança do nó, ou extraem imagens de contêiner do sistema base do Microsoft Container Registry (MCR) e assim por diante. Essas dependências de saída são quase inteiramente definidas com FQDNs, que não têm endereços estáticos por trás. A falta de endereços estáticos significa que os Grupos de Segurança de Rede não podem ser usados para bloquear o tráfego de saída de um cluster AKS. Por esse motivo, por padrão, os clusters AKS têm acesso irrestrito à Internet de saída (saída). Esse nível de acesso à rede permite que nós e serviços executados acessem recursos externos conforme necessário.
No entanto, em um ambiente de produção, as comunicações com um cluster Kubernetes devem ser protegidas para evitar a exfiltração de dados e outras vulnerabilidades. Todo o tráfego de entrada e saída da rede deve ser monitorado e controlado com base em um conjunto de regras de segurança. Se você quiser fazer isso, terá que restringir o tráfego de saída, mas um número limitado de portas e endereços deve permanecer acessível para manter as tarefas de manutenção de cluster saudáveis e satisfazer as dependências de saída mencionadas anteriormente.
A solução mais simples usa um dispositivo de firewall que pode controlar o tráfego de saída com base em nomes de domínio. Um firewall normalmente estabelece 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, oferecendo um controle de tráfego de saída refinado, mas, ao mesmo tempo, permite que você forneça acesso aos FQDNs que abrangem as dependências de saída de um cluster AKS (algo que os NSGs não podem fazer). Da mesma forma, você pode controlar o tráfego de entrada e melhorar a segurança habilitando a filtragem baseada em inteligência de ameaças em um Firewall do Azure implantado em uma rede de perímetro compartilhada. Essa filtragem pode fornecer alertas e negar tráfego de e para endereços IP e domínios mal-intencionados conhecidos.
Veja o vídeo a seguir para obter uma visão geral rápida sobre como isso funciona na prática em um ambiente de exemplo:
Você pode baixar 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 o tráfego de entrada e saída. Os guias a seguir percorrem cada etapa do script com mais detalhes para que você possa configurar uma configuração personalizada.
O diagrama a seguir mostra o ambiente de exemplo do vídeo que o script e o guia configuram:
Há uma diferença entre o script e o guia a seguir. O script usa identidades gerenciadas, mas 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 através de 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
Crie uma rede virtual com duas sub-redes separadas, uma para o cluster e outra para o firewall. Opcionalmente, você também pode criar um para entrada de serviço interno.
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 AKS e o Firewall do Azure. Cada um tem a sua própria sub-rede. Comecemos pela rede 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 um UDR
As regras de entrada e saída do Firewall do Azure devem ser configuradas. 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 pequeno subconjunto de destinos, talvez você precise de mais IPs de front-end de 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, consulte aqui
Crie um recurso IP público de SKU padrão que é 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 cli de visualização 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.
Nota
A configuração do endereço IP público para o Firewall do Azure pode levar alguns minutos. Para aproveitar o FQDN em regras de rede, precisamos de proxy DNS habilitado, quando habilitado, o firewall escutará na porta 53 e encaminhará solicitações DNS para o servidor DNS especificado anteriormente. Isso permitirá que o firewall traduza 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 êxito, salve o endereço IP do frontend 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)
# set fw as vnet dns server so dns queries are visible in fw logs
az network vnet update -g $RG --name $VNET_NAME --dns-servers $FWPRIVATE_IP
Nota
Se você usar acesso seguro ao servidor de API 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 automaticamente o tráfego entre sub-redes do Azure, redes virtuais e redes locais. Se você quiser alterar qualquer roteamento padrão do Azure, faça isso criando uma tabela de rotas.
Crie uma tabela de rotas vazia para 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 si.
# 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
Consulte a documentação da tabela de rotas de rede virtual sobre como você pode substituir as rotas padrão do sistema do Azure ou adicionar mais rotas à tabela de rotas de uma sub-rede.
Adicionando 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.
Você pode usar as três regras de rede a seguir para configurar seu firewall. Talvez seja necessário adaptar essas regras com base em sua implantação. A primeira regra permite o acesso à porta 9000 via TCP. A segunda regra permite o acesso às portas 1194 e 123 via UDP. Ambas as regras permitem apenas o tráfego destinado ao CIDR da Região do Azure que estamos a utilizar, neste caso o Leste dos EUA.
Finalmente, adicionamos uma terceira regra de rede abrindo a porta 123 a um FQDN do servidor de tempo da Internet (por exemplo:ntp.ubuntu.com
) via UDP. Adicionar um FQDN como uma regra de rede é um dos recursos específicos do Firewall do Azure, e você precisa adaptá-lo ao usar suas próprias opções.
Depois de definir as regras de rede, também adicionaremos uma regra de aplicativo usando o AzureKubernetesService
que cobre os FQDNs necessários acessíveis através das portas TCP 443 e 80. Além disso, talvez seja necessário configurar mais regras de rede e aplicativos com base em sua implantação. Para obter mais informações, consulte Rede de saída e regras FQDN para clusters do Serviço Kubernetes do Azure (AKS).
Adicionar regras de rede 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 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
# set fw application rule to allow kubernettes to reach storage and image resources
az network firewall application-rule create -g $RG -f $FWNAME --collection-name 'aksfwarweb' -n 'storage' --source-addresses '10.42.1.0/24' --protocols 'https=443' --target-fqdns '*.blob.storage.azure.net' '*.blob.core.windows.net' --action allow --priority 101
az network firewall application-rule create -g $RG -f $FWNAME --collection-name 'aksfwarweb' -n 'website' --source-addresses '10.42.1.0/24' --protocols 'https=443' --target-fqdns 'ghcr.io' '*.docker.io' '*.docker.com' '*.githubusercontent.com'
Consulte a documentação do Firewall do Azure para saber mais sobre o serviço 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 anteriormente. A associação pode ser feita emitindo um comando para a rede virtual que conté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 UDR de saída na rede existente
Agora, um cluster AKS pode ser implantado na rede virtual existente. Você também usa o tipo userDefinedRouting
de saída, esse recurso garante que qualquer tráfego de saída seja forçado através do firewall e que não existam outros caminhos de saída (por padrão, o tipo de saída do Balanceador de Carga pode ser usado).
A sub-rede de destino a ser implantada é definida com a variável de ambiente, $SUBNETID
. Não definimos a $SUBNETID
variável nas etapas anteriores. Para definir o valor para o ID da 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)
Você define o tipo de saída para usar o UDR que já existe na sub-rede. Essa configuração permite que o AKS ignore a instalação e o provisionamento de IP para o balanceador de carga.
Importante
Para obter mais informações sobre UDR de tipo de saída, incluindo limitações, consulte UDR de tipo de saída de saída.
Gorjeta
Recursos adicionais podem ser adicionados à implantação do cluster, como o Cluster Privado ou a alteração da SKU do sistema operacional.
O recurso AKS para intervalos de IP autorizados pelo servidor API pode ser adicionado 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.
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
Nota
Para criar e usar sua própria VNet e tabela de rotas com kubenet
plug-in de rede, você precisa usar uma identidade gerenciada atribuída pelo usuário. Para uma identidade gerenciada atribuída pelo sistema, não podemos obter a ID de identidade antes de criar cluster, o que causa um atraso na atribuição de função entrando em vigor.
Para criar e usar sua própria VNet e tabela de rotas com azure
plug-in de rede, há suporte para identidades gerenciadas atribuídas pelo sistema e pelo usuário.
Habilite 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 das ferramentas do desenvolvedor à lista de intervalos IP aprovados do cluster AKS para acessar o servidor de API a partir daí. Outra opção é configurar uma jumpbox com as ferramentas necessárias dentro de uma sub-rede separada na rede virtual do Firewall.
Adicione 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
para se conectar ao cluster 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, expomos um serviço público, mas você também pode optar por expor um serviço interno por meio do balanceador de carga interno.
Reveja o manifesto de início rápido AKS Store Demo para ver todos os recursos que serão criados.
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
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, certifique-se de criar uma regra DNAT apropriada no Firewall 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, uma regra DNAT deve ser gravada 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, pois é a porta no firewall a ser acessada. 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ê precisa especificar o endereço IP interno atribuído ao balanceador de carga criado pelo serviço Kubernetes. Recupere o endereço executando:
kubectl get services
O endereço IP necessário está 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 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 AKS. Neste exemplo, o IP público do Firewall era 203.0.113.32
.
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.
az group delete -g $RG
Próximos passos
- Saiba mais sobre o Serviço Kubernetes do Azure, consulte Conceitos principais do Kubernetes para o Serviço Kubernetes do Azure (AKS).