Compartir vía


Uso de Azure Firewall para proteger los clústeres de Azure Kubernetes Service (AKS)

En este artículo se muestra cómo proteger los clústeres de Azure Kubernetes Service (AKS) mediante Azure Firewall para proteger el tráfico entrante y saliente.

Fondo

Azure Kubernetes Service (AKS) ofrece un clúster de Kubernetes administrado en Azure. Para más información, vea Azure Kubernetes Service.

A pesar de que AKS es una solución totalmente administrada, no ofrece una solución integrada para proteger el tráfico de entrada y salida entre el clúster y las redes externas. Azure Firewall ofrece una solución a esto.

Los clústeres de AKS se implementan en una red virtual. Esta red puede ser administrada (creada por AKS) o personalizada (configurada previamente por el usuario). En cualquier caso, el clúster tiene dependencias de salida en servicios externos a esa red virtual (el servicio no tiene dependencias de entrada). Para fines operativos y de administración, los nodos de un clúster de AKS deben tener acceso a determinados puertos y nombres de dominio completo (FQDN) que describen estas dependencias de salida. Esto es necesario para varias funciones, incluidos, entre otros, los nodos que se comunican con el servidor de API de Kubernetes. Descargan e instalan los componentes principales del clúster de Kubernetes y las actualizaciones de seguridad del nodo, o extraen imágenes de contenedor del sistema base de Microsoft Container Registry (MCR), etc. Estas dependencias de salida se definen casi por completo mediante FQDN, que no tienen direcciones estáticas tras ellos. La falta de direcciones estáticas significa que no se pueden usar grupos de seguridad de red para bloquear el tráfico saliente desde un clúster de AKS. Por esta razón, de forma predeterminada, los clústeres de AKS tienen acceso de salida a Internet ilimitado. Este nivel de acceso a la red permite que los nodos y servicios que ejecuta accedan a recursos externos según sea necesario.

Sin embargo, en un entorno de producción, las comunicaciones con un clúster de Kubernetes deben protegerse para evitar la filtración de datos junto con otras vulnerabilidades. Todo el tráfico de red entrante y saliente debe supervisarse y controlarse en función de un conjunto de reglas de seguridad. Si quiere hacerlo, deberá restringir el tráfico de salida, pero un número limitado de puertos y direcciones debe seguir siendo accesible para mantener las tareas de mantenimiento del clúster correctas y satisfacer las dependencias salientes mencionadas anteriormente.

La solución más sencilla usa un dispositivo de firewall que pueda controlar el tráfico de salida en función de los nombres de dominio. Normalmente, un firewall establece una barrera entre una red de confianza y una red que no es de confianza, como Internet. Por ejemplo, Azure Firewall puede restringir el tráfico HTTP y HTTPS saliente en función del FQDN del destino, lo que proporciona un control de tráfico de salida específico, pero al mismo tiempo permite proporcionar acceso a los FQDN que abarcan las dependencias salientes de un clúster de AKS (algo que los NSG no pueden hacer). Del mismo modo, puede controlar el tráfico de entrada y mejorar la seguridad si habilita el filtrado basado en inteligencia sobre amenazas en Azure Firewall implementado en una red perimetral compartida. Este filtrado puede proporcionar alertas y denegar el tráfico hacia y desde dominios y direcciones IP malintencionadas conocidas.

Vea el siguiente vídeo para obtener información general rápida sobre cómo funciona en la práctica en un entorno de ejemplo:

Puede descargar un archivo ZIP desde el Centro de descarga de Microsoft que contiene un archivo de script de Bash y un archivo yaml para configurar automáticamente el entorno de ejemplo usado en el vídeo. Configure Azure Firewall para proteger tanto el tráfico de entrada como de salida. Las siguientes guías le acompañarán en cada paso del script con más detalle para que pueda crear una configuración personalizada.

En el diagrama siguiente se muestra el entorno de ejemplo del vídeo que configura el script y la guía:

Diagrama que muestra el clúster AKS con Azure Firewall para el filtrado de entrada y salida.

Hay una diferencia entre el script y la siguiente guía. El script usa identidades administradas, pero la guía usa una entidad de servicio. Esto muestra dos maneras diferentes de crear una identidad para administrar y crear recursos de clúster.

Restricción del tráfico de salida mediante Azure Firewall

Configuración mediante variables de entorno

Defina el conjunto de variables de entorno que se usarán en la creación 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"

Creación de una red virtual con varias subredes

Cree una red virtual con dos subredes independientes, una para el clúster y otra para el firewall. Opcionalmente, también puede crear una para la entrada del servicio interno.

Topología de red vacía

Cree el grupo de recursos que contendrá todos los recursos.

# Create Resource Group

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

Cree una red virtual con dos subredes para hospedar el clúster de AKS y Azure Firewall. Cada uno tiene su propia subred. Comencemos con la red de 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

Creación y configuración de un firewall de Azure con una UDR

Deben configurarse las reglas de entrada y salida del firewall de Azure. El propósito principal del firewall es que las organizaciones puedan configurar reglas de tráfico de entrada y salida pormenorizadas hacia y desde el clúster de AKS.

Firewall y UDR

Importante

Si el clúster o la aplicación crea un gran número de conexiones de salida dirigidas al mismo subconjunto de destinos (o a uno más reducido), es posible que necesite más direcciones IP de front-end de firewall para evitar que se agoten los puertos por IP de front-end. Para obtener más información sobre cómo crear un firewall de Azure con varias direcciones IP, vea esto.

Cree un recurso de IP pública de SKU estándar que se usa como dirección de front-end de Azure Firewall.

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

Registre la extensión de la CLI en versión preliminar para crear un firewall de 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

La dirección IP creada anteriormente puede asignarse ahora al front-end del firewall.

Nota

La configuración de la dirección IP pública en el firewall de Azure puede tardar unos minutos. Para aprovechar el FQDN en las reglas de red, es necesario habilitar el proxy DNS; cuando lo esté, el firewall escuchará en el puerto 53 y reenviará las solicitudes DNS al servidor DNS especificado anteriormente. Esto permitirá al firewall traducir ese FQDN de forma automática.

# 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

Cuando el comando anterior se haya realizado correctamente, anote la dirección IP del servidor front-end del firewall para la configuración 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

Si utiliza el acceso seguro al servidor de la API de AKS con intervalos de direcciones IP autorizados, debe agregar la dirección IP pública del firewall en el intervalo de IP autorizado.

Creación de una UDR con un salto al firewall de Azure

Azure enruta automáticamente el tráfico entre redes locales, las redes virtuales y las subredes de Azure. Si desea cambiar algún enrutamiento predeterminado de Azure, debe crear una tabla de rutas.

Cree una tabla de rutas vacía para asociarla a una subred determinada. La tabla de rutas definirá el próximo salto como el firewall de Azure creado anteriormente. Cada subred puede tener cero o una ruta de tablas de ruta asociada.

# 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 en la documentación sobre las tablas de rutas de red virtual cómo invalidar las rutas del sistema predeterminadas de Azure o agregar rutas adicionales a la tabla de rutas de una subred.

Adición de reglas de firewall

Nota

Para las aplicaciones fuera de los espacios de nombres kube-system o gatekeeper-system que necesitan comunicarse con el servidor de la API, se requiere una regla de red adicional para permitir la comunicación TCP al puerto 443 para la dirección IP del servidor de la API, además de agregar una regla de aplicación para fqdn-tag AzureKubernetesService.

Puede usar las tres reglas de red siguientes para configurar el firewall. Puede que necesite adaptar estas reglas en función de su implementación. La primera regla permite el acceso al puerto 9000 a través de TCP. La segunda regla permite el acceso al puerto 1194 y 123 a través de UDP. Las dos reglas solo permitirán el tráfico destinado al CIDR de la región de Azure que se use, en este caso, Este de EE. UU.

Por último, agregamos una tercera regla de red que abre el puerto 123 a un FQDN del servidor de hora de Internet (por ejemplo:ntp.ubuntu.com) a través de UDP. Agregar un FQDN como una regla de red es una de las características específicas de Azure Firewall y tendrá que adaptarla cuando use opciones propias.

Después de establecer las reglas de red, también se agregará una regla de aplicación mediante AzureKubernetesService, que abarca los FQDN necesarios a los que se puede acceder a través del puerto TCP 443 y el puerto 80. Además, es posible que deba configurar reglas de red y de aplicación adicionales en función de la implementación. Para más información, consulte Reglas de FQDN y red de salida para clústeres de Azure Kubernetes Service (AKS).

Adición de reglas de red 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

Incorporación de reglas de aplicación 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' 

Para más información acerca del servicio Azure Firewall, consulte la documentación de Azure Firewall.

Asociación de la tabla de rutas a AKS

Para asociar el clúster al firewall, la subred dedicada del clúster debe hacer referencia a la tabla de rutas creada anteriormente. Para crear la asociación, se puede emitir un comando a la red virtual que contiene el clúster y el firewall para actualizar la tabla de rutas de la subred del clúster.

# 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

Implementación de AKS con el tipo de salida UDR a la red existente

Ahora, un clúster de AKS se puede implementar en una red virtual existente. También se usará el tipo de salida userDefinedRouting; esta característica garantiza que se fuerza el tráfico saliente a través del firewall y que no existen otras rutas de salida (de forma predeterminada, se podría usar el tipo de salida Load Balancer).

aks-deploy

La subred de destino en la que se va a realizar la implementación se define con la variable de entorno $SUBNETID. No definimos la variable $SUBNETID en los pasos anteriores. Para establecer el valor del id. de la subred, puede usar el comando siguiente:

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

Definirá el tipo de salida para usar el UDR que ya existe en la subred. Esta configuración permitirá a AKS omitir la configuración y el aprovisionamiento de IP para el equilibrador de carga.

Importante

Para obtener más información sobre el tipo de salida UDR, incluidas las limitaciones, vea UDR de tipo de salida.

Sugerencia

Se pueden agregar otras características a la implementación del clúster, como Clúster privado o cambiar el SKU de SO.

La característica de intervalos de IP autorizados del servidor de API de AKS se puede agregar para limitar el acceso del servidor de API solo al punto de conexión público del firewall. La característica de intervalos IP autorizados se indica en el diagrama como opcional. Al habilitar la característica de intervalos de IP autorizados para limitar el acceso del servidor de API, las herramientas de desarrollo deben usar una JumpBox desde la red virtual del firewall, o bien debe agregar todos los puntos de conexión de desarrollador al intervalo de direcciones 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 crear y usar su propia VNet y tabla de rutas con el complemento de red kubenet, necesita usar una identidad administrada asignada por el usuario. En el caso de una identidad administrada asignada por el sistema, no se puede obtener el identificador de identidad antes de crear un clúster, lo que causa un retraso para que la asignación de roles surta efecto.

Para crear y usar su propia red virtual y tabla de rutas con el complemento de red azure, se admiten identidades administradas asignadas por el sistema y asignadas por el usuario.

Habilitación del acceso de desarrollador al servidor de API

Si en el paso anterior ha usado intervalos IP autorizados para el clúster, tendrá que agregar las direcciones IP de las herramientas de desarrollador a la lista de intervalos IP autorizados del clúster de AKS para poder acceder al servidor de API desde ahí. Otra opción consiste en configurar una JumpBox con las herramientas necesarias en una subred independiente de la red virtual del firewall.

Agrege otra dirección IP a los intervalos autorizados con el siguiente 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 el comando az aks get-credentials para configurar kubectl para conectarse a su clúster de Kubernetes recién creado.

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

Restricción del tráfico de entrada mediante Azure Firewall

Ahora puede empezar a exponer servicios e implementar aplicaciones en este clúster. En este ejemplo, se expondrá un servicio público, pero también puede optar por exponer un servicio interno a través de un equilibrador de carga interno.

DNAT de servicio público

  1. Revise el inicio rápido Demostración de la Tienda de AKS para ver todos los recursos que se crearán.

  2. Implemente el servicio mediante el comando kubectl apply.

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

Adición de una regla de DNAT al firewall de Azure

Importante

Cuando use Azure Firewall para restringir el tráfico de salida y cree una ruta definida por el usuario (UDR) para forzar todo el tráfico de salida, asegúrese de crear una regla DNAT adecuada en el firewall para permitir correctamente el tráfico de entrada. El uso de Azure Firewall con una UDR interrumpe la configuración de entrada debido al enrutamiento asimétrico. (El problema se produce si la subred de AKS tiene una ruta predeterminada que va a la dirección IP privada del firewall, pero está usando un equilibrador de carga público, de entrada o de servicio de Kubernetes del tipo: LoadBalancer). En este caso, el tráfico entrante del equilibrador de carga se recibe a través de su dirección IP pública, pero la ruta de vuelta pasa a través de la dirección IP privada del firewall. Dado que el firewall es con estado, quita el paquete de vuelta porque el firewall no tiene conocimiento de una sesión establecida. Para aprender a integrar Azure Firewall con el equilibrador de carga de entrada o de servicio, consulte Integración de Azure Firewall con Azure Standard Load Balancer.

Para configurar la conectividad de entrada, se debe escribir una regla de DNAT en el firewall de Azure. Para probar la conectividad con el clúster, se define una regla para la dirección IP pública de front-end del firewall que se va a enrutar a la dirección IP interna expuesta por el servicio interno.

La dirección de destino se puede personalizar porque es el puerto del firewall al que se va a acceder. La dirección traducida debe ser la dirección IP del equilibrador de carga interno. El puerto traducido debe ser el puerto expuesto para el servicio Kubernetes.

Deberá especificar la dirección IP interna asignada al equilibrador de carga creado por el servicio Kubernetes. Para recuperar la dirección, ejecute:

kubectl get services

La dirección IP necesaria se mostrará en la columna EXTERNAL-IP y será similar a la siguiente.

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

Para obtener la IP del servicio, ejecute lo siguiente:

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

Para agregar la regla de NAT, ejecute lo siguiente:

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 conectividad

Vaya a la dirección IP de front-end del firewall de Azure en un explorador para validar la conectividad.

Debería ver la aplicación de la tienda de AKS. En este ejemplo, la dirección IP pública del firewall es 203.0.113.32.

Captura de pantalla que muestra la aplicación front-end de Azure Store abierta en un explorador local.

En esta página, puede ver los productos, agregarlos al carro y, a continuación, realizar un pedido.

Limpieza de recursos

Para limpiar los recursos de Azure, elimine el grupo de recursos de AKS.

az group delete -g $RG

Pasos siguientes