Protección de los clústeres de Azure Kubernetes Service (AKS) con Azure Policy

Puede aplicar y aplicar directivas de seguridad integradas en los clústeres de Azure Kubernetes Service (AKS) mediante Azure Policy. Azure Policy le ayuda a aplicar los estándares de la organización y a evaluar el cumplimiento a gran escala. Después de instalar el complemento de Azure Policy para AKS, puedes aplicar definiciones de directivas individuales o grupos de definiciones de directivas denominadas iniciativas (a veces denominadas conjuntos de directivas) a tu clúster. Para obtener una lista completa de las definiciones de directivas e iniciativas de AKS, consulte Definiciones integradas de Azure Policy para AKS.

En este artículo se muestra cómo aplicar definiciones de directiva al clúster y comprobar que se aplican las asignaciones.

Requisitos previos

Necesita los siguientes recursos instalados y configurados antes de comenzar:

Asignación de una definición o iniciativa de directiva integrada

Puede aplicar una definición o iniciativa de directiva en el portal de Azure mediante los pasos siguientes:

  1. Vaya al servicio Azure Policy en el portal de Azure denominado Directiva.
  2. En el panel izquierdo de la página de Azure Policy, seleccione Definitions (Definiciones).
  3. En Categorías, selecciona Kubernetes.
  4. Elija la definición o iniciativa de directiva que quiera aplicar. Para este ejemplo, selecciona los estándares de referencia de seguridad del módulo de clúster de Kubernetes para la iniciativa de cargas de trabajo basadas en Linux.
  5. Seleccione Asignar.
  6. Establece el valor de Ámbito en el grupo de recursos del clúster de AKS con el complemento de Azure Policy habilitado.
  7. Seleccione la página Parámetros y actualice el efecto de audit a deny para bloquear nuevas implementaciones que infringen la iniciativa de línea base. También puedes agregar espacios de nombres adicionales para excluirlos de la evaluación. En este ejemplo, conserve los valores predeterminados.
  8. Selecciona Revisar + crear>Crear para enviar la asignación de directivas.

Cree un directorio para la configuración de Terraform.

mkdir aks-use-azure-policy
cd aks-use-azure-policy

Creación de la configuración de Terraform

Cree un archivo llamado main.tf.

touch main.tf

Abra el main.tf archivo y agregue la siguiente configuración.

Configuración del proveedor de Terraform

La siguiente configuración:

  • Define la versión de Terraform.
  • Configura el proveedor de AzureRM.
  • Habilita las características del proveedor de Azure necesarias para la administración de recursos.
terraform {
 required_version = ">= 1.6.0"
 required_providers {
   azurerm = {
     source  = "hashicorp/azurerm"
     version = "~> 4.0"
   }
 }
}
provider "azurerm" {
 features {}
}

Definición de variables de entrada

Use las siguientes variables para proporcionar el nombre del grupo de recursos existente y el clúster de AKS durante la implementación.

variable "resource_group_name" {
 description = "Name of the resource group that contains the existing AKS cluster."
 type        = string
}
variable "aks_cluster_name" {
 description = "Name of the existing AKS cluster."
 type        = string
}

Hacer referencia al clúster de AKS existente

Los siguientes orígenes de datos recuperan información sobre el grupo de recursos existente y el clúster de AKS. Terraform usa estos datos para hacer referencia a la infraestructura que ya existe en Azure en lugar de crear nuevos recursos.

data "azurerm_resource_group" "aks" {
 name = var.resource_group_name
}
data "azurerm_kubernetes_cluster" "aks" {
 name                = var.aks_cluster_name
 resource_group_name = data.azurerm_resource_group.aks.name
}

Opcional: Crear y asignar una definición de directiva personalizada

La sección de definición de directiva personalizada es informativa y está fuera del ámbito de este artículo. Las directivas personalizadas permiten definir reglas para usar Azure. Por ejemplo, puedes aplicar los siguientes tipos de reglas:

  • Procedimientos de seguridad.
  • Gestión de costes.
  • Reglas específicas de la organización, como convenciones de nomenclatura o ubicaciones.

Antes de crear una directiva personalizada, compruebe la lista de patrones y ejemplos comunes para ver si ya incluye su caso.

Las definiciones de directivas personalizadas se escriben en JSON. Para más información sobre cómo crear una directiva personalizada, consulte Estructura de definición de Azure Policy y Creación de una definición de directiva personalizada.

Nota

Azure Policy usa una propiedad denominada templateInfo que puede usar para definir el tipo de origen de la plantilla de restricción. Al definir templateInfo en las definiciones de directiva, no se pueden usar las propiedades constraintTemplate ni constraint . No obstante, tienes que definir apiGroups y kinds. Para obtener más información, vea Descripción de los efectos de Azure Policy.

Después de crear la definición de directiva personalizada, consulte Asignación de una definición de directiva para ver un tutorial paso a paso para asignar la directiva al clúster.

Validar que Azure Policy está en ejecución

Confirme que las asignaciones de directiva se aplican al clúster mediante el siguiente kubectl get comando.

kubectl get constrainttemplates

Nota

Las asignaciones de directivas pueden tardar hasta 20 minutos en sincronizarse con cada clúster.

La salida debe ser similar a la siguiente salida de ejemplo:

NAME                                     AGE
k8sazureallowedcapabilities              23m
k8sazureallowedusersgroups               23m
k8sazureblockhostnamespace               23m
k8sazurecontainerallowedimages           23m
k8sazurecontainerallowedports            23m
k8sazurecontainerlimits                  23m
k8sazurecontainernoprivilege             23m
k8sazurecontainernoprivilegeescalation   23m
k8sazureenforceapparmor                  23m
k8sazurehostfilesystem                   23m
k8sazurehostnetworkingports              23m
k8sazurereadonlyrootfilesystem           23m
k8sazureserviceallowedports              23m

Validación del rechazo de un pod con privilegios

Compruebe qué ocurre al programar un pod con el contexto de seguridad de privileged: true. Este contexto de seguridad eleva los privilegios del pod. La iniciativa no permite los pods privilegiados, por lo que se deniega la solicitud, lo que provoca que se rechace la implementación.

  1. Cree un archivo denominado nginx-privileged.yaml y pegue el siguiente manifiesto de YAML.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-privileged
    spec:
      containers:
        - name: nginx-privileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
          securityContext:
            privileged: true
    
  2. Cree el pod con el comando kubectl apply y especifique el nombre de su manifiesto YAML.

    kubectl apply -f nginx-privileged.yaml
    

    Como era de esperar, el pod no se puede programar, como se muestra en la siguiente salida de ejemplo:

    Error from server ([denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}): error when creating "privileged.yaml": admission webhook "validation.gatekeeper.sh" denied the request: [denied by azurepolicy-container-no-privilege-00edd87bf80f443fa51d10910255adbc4013d590bec3d290b4f48725d4dfbdf9] Privileged container is not allowed: nginx-privileged, securityContext: {"privileged": true}
    

    El pod no llega a la fase de programación, por lo que no hay recursos que eliminar para continuar.

Prueba de la creación de un pod sin privilegios

En el ejemplo anterior, la imagen de contenedor intentó usar automáticamente la raíz para enlazar NGINX con el puerto 80. La iniciativa de directiva deniega esta solicitud, por lo que el pod no se inicia. Ahora, intenta ejecutar ese mismo pod NGINX sin acceso privilegiado.

  1. Cree un archivo denominado nginx-unprivileged.yaml y pegue el siguiente manifiesto YAML en él.

    apiVersion: v1
    kind: Pod
    metadata:
      name: nginx-unprivileged
    spec:
      containers:
        - name: nginx-unprivileged
          image: mcr.microsoft.com/oss/nginx/nginx:1.15.5-alpine
    
  2. Cree el pod mediante el comando kubectl apply y especifique el nombre de su archivo de manifiesto YAML.

    kubectl apply -f nginx-unprivileged.yaml
    
  3. Compruebe el estado del pod mediante el kubectl get pods comando .

    kubectl get pods
    

    Tu salida debe ser similar a la siguiente salida de ejemplo, que muestra que el pod se programó correctamente y tiene un estado de En ejecución:

    NAME                 READY   STATUS    RESTARTS   AGE
    nginx-unprivileged   1/1     Running   0          18s
    

    Este ejemplo muestra la iniciativa de referencia que afecta solo a los despliegues que infringen las directivas incluidas en la colección. Las implementaciones permitidas continúan funcionando.

  4. Elimine el pod NGINX sin privilegios con el comando kubectl delete y especifique el nombre del manifiesto YAML.

    kubectl delete -f nginx-unprivileged.yaml
    

Siga estos pasos para asignar una iniciativa de Azure Policy integrada al clúster de AKS mediante Terraform.

Recuperar la iniciativa integrada de Azure Policy

La siguiente fuente de datos recupera la iniciativa integrada de Azure Policy para los estándares de referencia de seguridad de los pods de Kubernetes.

data "azurerm_policy_set_definition" "aks_pod_security_baseline" {
 display_name = "Kubernetes cluster pod security baseline standards for Linux-based workloads"
}

Asignar la iniciativa de Azure Policy

El siguiente recurso asigna la iniciativa de Azure Policy integrada al grupo de recursos que contiene el clúster de AKS.

Establezca el efecto de la directiva en Deny para bloquear las cargas de trabajo que incumplan las reglas de directiva definidas.

resource "azurerm_resource_group_policy_assignment" "aks_pod_security_baseline" {
 name                 = "aks-pod-security-baseline"
 display_name         = "Kubernetes cluster pod security baseline standards for Linux-based workloads"
 resource_group_id    = data.azurerm_resource_group.aks.id
 policy_definition_id = data.azurerm_policy_set_definition.aks_pod_security_baseline.id
 parameters = jsonencode({
   effect = {
     value = "Deny"
   }
 })
}

Inicialización de la configuración de Terraform

Ejecute terraform init para inicializar el directorio de trabajo de Terraform y descargar los complementos de proveedor necesarios.

terraform init

Dar formato y validar la configuración

Ejecute terraform fmt para dar formato a la configuración de Terraform.

terraform fmt

Ejecute terraform validate para validar la sintaxis de configuración de Terraform.

terraform validate

Aplica la configuración de Terraform

Antes de implementar la configuración, proporcione valores para las variables siguientes:

  • resource_group_name
  • aks_cluster_name

Ejecute terraform apply para implementar la asignación de Azure Policy.

terraform apply

Cuando se le solicite, escriba yes para confirmar la implementación.

Comprobación de la instalación de Azure Policy

Una vez completada la implementación, compruebe que los componentes de Azure Policy se ejecutan en el clúster de AKS.

kubectl get pods -n kube-system

Compruebe que las plantillas de restricción Gatekeeper se instalaron correctamente.

kubectl get constrainttemplates

Pruebe la asignación de Azure Policy

Cree un archivo llamado privileged-pod.yaml.

apiVersion: v1
kind: Pod
metadata:
 name: privileged-pod
spec:
 containers:
 - name: nginx
   image: nginx
   securityContext:
     privileged: true

Aplique el manifiesto al clúster.

kubectl apply -f privileged-pod.yaml

La implementación falla porque la asignación de Azure Policy rechaza los contenedores con privilegios que incumplan los estándares de referencia de seguridad de pods configurados.

Deshabilitación de una directiva o iniciativa

Quite la iniciativa base en el portal de Azure siguiendo estos pasos:

  1. Vaya al panel Directiva en el portal de Azure.
  2. Seleccione Asignaciones.
  3. Selecciona los tres puntos (...) al final de la línea correspondiente a la iniciativa Estándares de referencia de seguridad de pods del clúster de Kubernetes para cargas de trabajo basadas en Linux.
  4. Seleccione Eliminar asignación.

Para quitar el complemento Azure Policy del clúster de AKS, consulte Eliminación del complemento.

Pasos siguientes

Para obtener más información sobre cómo funciona Azure Policy, consulta los siguientes artículos: