Extender las políticas de Kyverno: Creación de reglas personalizadas para mejorar la seguridad de Kubernetes

Extender las políticas de Kyverno: Creación de reglas personalizadas para mejorar la seguridad de Kubernetes

Kyverno ofrece un enfoque robusto y declarativo para hacer cumplir los estándares de seguridad y cumplimiento dentro de los clústeres de Kubernetes al permitir a los usuarios definir y hacer cumplir políticas personalizadas. Para una mirada en profundidad a la funcionalidad de Kyverno, incluidos los conceptos y beneficios principales, vea mi artículo detallado aquí. En esta guía, nos centraremos en extender las políticas de Kyverno, proporcionando un recorrido estructurado de su modelo de datos e ilustrando casos de uso para aprovechar al máximo Kyverno en un entorno de Kubernetes.

Comprendiendo el Modelo de Datos de Políticas de Kyverno

Las políticas de Kyverno consisten en varios componentes que definen cómo debe comportarse la política, qué recursos debe afectar y las reglas específicas que se aplican. Vamos a profundizar en las partes principales del modelo de políticas de Kyverno:

  1. Definición de Política: Esta es la configuración raíz donde defines los metadatos de la política, incluyendo nombre, tipo y alcance. Las políticas pueden crearse a nivel de espacio de nombres para áreas específicas o como reglas a nivel de clúster para hacer cumplir estándares uniformes en todo el clúster de Kubernetes.
  2. Reglas: Las políticas están compuestas por reglas que dictan qué condiciones debe hacer cumplir Kyverno. Cada regla puede incluir lógica para validación, mutación o generación según tus necesidades.
  3. Bloques de Coincidencia y Exclusión: Estas secciones permiten un control detallado sobre qué recursos se aplica la política. Puedes especificar recursos por sus tipos (por ejemplo, Pods, Despliegues), espacios de nombres, etiquetas e incluso nombres específicos. Esta flexibilidad es crucial para crear políticas dirigidas que impacten solo en los recursos que deseas gestionar.
    1. Bloque de coincidencia: Define las condiciones bajo las cuales la regla se aplica a recursos específicos.
    2. Bloque de exclusión: Se utiliza para omitir explícitamente recursos que coinciden con ciertas condiciones, asegurando que los recursos no afectados no se incluyan inadvertidamente.
  4. Acciones de Validación, Mutación y Generación: Cada regla puede tomar diferentes tipos de acciones:
    1. Validación: Asegura que los recursos cumplan con criterios específicos y bloquea el despliegue si no lo hacen.
    2. Mutación: Ajusta las configuraciones de recursos para alinearse con estándares predefinidos, lo cual es útil para la autorremediación.
    3. Generación: Crea o gestiona recursos adicionales basados en configuraciones de recursos existentes.

Ejemplo: Restringir Fuentes de Imágenes de Contenedores a Docker Hub

Un requisito común de seguridad es limitar las imágenes de contenedores a registros de confianza. El ejemplo a continuación demuestra una política que solo permite imágenes de Docker Hub.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: restrict-dockerhub-images
spec:
  rules:
    - name: only-dockerhub-images
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "Solo se permiten imágenes de Docker Hub."
        pattern:
          spec:
            containers:
              - image: "docker.io/*"

Esta política apunta a todos los recursos Pod en el clúster y hace cumplir una regla de validación que restringe la fuente de la imagen a docker.io. Si un Pod utiliza una imagen fuera de Docker Hub, Kyverno niega su despliegue, reforzando prácticas de aprovisionamiento seguro.

Casos de Uso Prácticos para Políticas de Kyverno

Las políticas de Kyverno pueden manejar una variedad de tareas de gestión de Kubernetes a través de validación, mutación y generación. Vamos a explorar ejemplos para cada tipo para ilustrar la versatilidad de Kyverno:

1. Políticas de Validación

Las políticas de validación en Kyverno aseguran que los recursos cumplan con configuraciones específicas o estándares de seguridad, deteniendo cualquier recurso no conforme de desplegarse.

Caso de Uso: Hacer Cumplir Límites de Recursos para Contenedores

Este ejemplo previene despliegues que carecen de límites de recursos, asegurando que todos los Pods especifiquen restricciones de CPU y memoria.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: enforce-resource-limits
spec:
  rules:
    - name: require-resource-limits
      match:
        resources:
          kinds:
            - Pod
      validate:
        message: "Se requieren límites de recursos (CPU y memoria) para todos los contenedores."
        pattern:
          spec:
            containers:
              - resources:
                  limits:
                    cpu: "?*"
                    memory: "?*"

Al hacer cumplir los límites de recursos, esta política ayuda a prevenir la contención de recursos en el clúster, fomentando un rendimiento estable y predecible.

2. Políticas de Mutación

Las políticas de mutación permiten a Kyverno ajustar automáticamente configuraciones en recursos para cumplir con requisitos de cumplimiento. Este enfoque es beneficioso para configuraciones consistentes sin intervención manual.

Caso de Uso: Agregar Etiquetas Predeterminadas a Pods

Esta política agrega una etiqueta predeterminada, environment: production, a todos los nuevos Pods que carecen de esta etiqueta, asegurando que los recursos se alineen con los estándares de etiquetado de toda la organización.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: add-default-label
spec:
  rules:
    - name: add-environment-label
      match:
        resources:
          kinds:
            - Pod
      mutate:
        patchStrategicMerge:
          metadata:
            labels:
              environment: "production"

Esta política de mutación es un ejemplo de cómo Kyverno puede estandarizar configuraciones de recursos a escala al agregar dinámicamente información faltante, reduciendo el error humano y asegurando la consistencia en el etiquetado.

3. Políticas de Generación

Las políticas de generación en Kyverno se utilizan para crear o actualizar recursos relacionados, mejorando la automatización de Kubernetes al responder a configuraciones o necesidades específicas en tiempo real.

Caso de Uso: Creación Automática de un ConfigMap para Cada Nuevo Espacio de Nombres

Este ejemplo de política genera un ConfigMap en cada nuevo espacio de nombres, estableciendo valores de configuración predeterminados para todos los recursos en ese espacio de nombres.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: generate-configmap
spec:
  rules:
    - name: add-default-configmap
      match:
        resources:
          kinds:
            - Namespace
      generate:
        kind: ConfigMap
        name: default-config
        namespace: "{{request.object.metadata.name}}"
        data:
          default-key: "default-value"

Esta política de generación se activa cada vez que se crea un nuevo espacio de nombres, aprovisionando automáticamente un ConfigMap con configuraciones predeterminadas. Este enfoque es especialmente útil en entornos multi-tenant, asegurando que los nuevos espacios de nombres tengan configuraciones esenciales en su lugar.

Conclusión

Extender las políticas de Kyverno permite a los administradores de Kubernetes establecer y hacer cumplir prácticas de seguridad y operativas personalizadas dentro de sus clústeres. Al aprovechar las capacidades de Kyverno en validación, mutación y generación, puedes automatizar el cumplimiento, agilizar las operaciones y reforzar los estándares de seguridad sin problemas.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.

Protegiendo sus servidores: Prevención de la divulgación de información con Istio Service Mesh

Protegiendo sus servidores: Prevención de la divulgación de información con Istio Service Mesh

En el panorama digital actual, donde las violaciones de datos y las amenazas cibernéticas se están volviendo cada vez más sofisticadas, garantizar la seguridad de sus servidores es primordial. Una de las preocupaciones críticas de seguridad que las organizaciones deben abordar es la «Divulgación de Información del Servidor». La Divulgación de Información del Servidor ocurre cuando información sensible sobre la configuración de un servidor, su pila tecnológica o estructura interna se expone inadvertidamente a partes no autorizadas. Los hackers pueden explotar esta vulnerabilidad para obtener información sobre posibles puntos débiles y lanzar ataques dirigidos. Tales violaciones pueden llevar al robo de datos, interrupción del servicio y daño a la reputación.

Divulgación de Información y Malla de Servicios Istio

Un ejemplo es el Encabezado HTTP del Servidor, que generalmente se incluye en la mayoría de las respuestas HTTP donde se encuentra el servidor que está proporcionando esta respuesta. Los valores pueden variar dependiendo de la pila, pero asuntos como Jetty, Tomcat o similares suelen verse. Pero también, si está utilizando una Malla de Servicios como Istio, verá el encabezado con un valor de istio-envoy, como puede ver aquí:

Divulgación de Información de Implementación del Servidor usando Malla de Servicios Istio

Como se comentó, esto es de tal importancia para varios niveles de seguridad, tales como:

  • Privacidad de Datos: La fuga de información del servidor puede exponer datos confidenciales, socavando la confianza del usuario y violando regulaciones de privacidad de datos como GDPR y HIPAA.
  • Reducción de la Superficie de Ataque: Al ocultar los detalles del servidor, minimiza la superficie de ataque disponible para posibles atacantes.
  • Seguridad por Oscuridad: Aunque no es un enfoque infalible, limitar la divulgación agrega una capa extra de seguridad, dificultando que los hackers recopilen información.

¿Cómo mitigar eso con la Malla de Servicios Istio?

Al usar Istio, podemos definir diferentes reglas para agregar y eliminar encabezados HTTP según nuestras necesidades, como puede ver en la siguiente documentación aquí: https://discuss.istio.io/t/remove-header-operation/1692 usando cláusulas simples para la definición de su VirtualService como puede ver aquí:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: k8snode-virtual-service
spec:
  hosts:
  - "example.com"
  gateways:
  - k8snode-gateway
  http:
    headers:
      response:
        remove:
          - "x-my-fault-source"
  - route:
    - destination:
        host: k8snode-service
        subset: version-1 

Desafortunadamente, esto no es útil para todos los encabezados HTTP, especialmente los «principales», por lo que los que no son personalizados agregados por sus cargas de trabajo, sino los que son principalmente utilizados y definidos en el estándar HTTP W3C https://www.w3.org/Protocols/

Entonces, en el caso del encabezado HTTP del Servidor es un poco más complejo de hacer, y necesita usar un EnvoyFilter, uno de los objetos más sofisticados que forma parte de la Malla de Servicios Istio. Basado en las palabras de la documentación oficial de Istio, un EnvoyFilter proporciona un mecanismo para personalizar la configuración de Envoy generada por Istio Pilot. Por lo tanto, puede usar EnvoyFilter para modificar valores para ciertos campos, agregar filtros específicos o incluso agregar nuevos oyentes, clústeres, etc.

Implementación de EnvoyFilter para Eliminar Encabezado

Así que ahora que sabemos que necesitamos crear un EnvoyFilter personalizado, veamos cuál necesitamos usar para eliminar el encabezado del Servidor y cómo se hace esto para obtener más conocimiento sobre este componente. Aquí puede ver el EnvoyFilter para ese trabajo:

---
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
  name: gateway-response-remove-headers
  namespace: istio-system
spec:
  workloadSelector:
    labels:
      istio: ingressgateway
  configPatches:
  - applyTo: NETWORK_FILTER
    match:
      context: GATEWAY
      listener:
        filterChain:
          filter:
            name: "envoy.filters.network.http_connection_manager"
    patch:
      operation: MERGE
      value:
        typed_config:
          "@type": "type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager"
          server_header_transformation: PASS_THROUGH
  - applyTo: ROUTE_CONFIGURATION
    match:
      context: GATEWAY
    patch:
      operation: MERGE
      value:
        response_headers_to_remove:
        - "server"

Así que centrémonos en las partes de la especificación del EnvoyFilter donde podemos obtener por un lado el usual workloadSelector, para saber dónde se aplicará este componente, que en este caso será el istio ingressgateway. Luego entramos en la sección configPatches, que son las secciones donde usamos la personalización que necesitamos hacer, y en nuestro caso, tenemos dos de ellas:

Ambas actúan en el contexto: GATEWAY y se aplican a dos objetos diferentes: NETWORK_FILTER Y ROUTE_CONFIGURATION. También puede usar filtros en sidecars para afectar su comportamiento. La primera parte lo que hace es incluir el filtro personalizado http_connection_manager que permite la manipulación del contexto HTTP, incluyendo para nuestro propósito principal también el encabezado HTTP, y luego tenemos la segunda parte que actúa en el ROUTE_CONFIGURATION eliminando el encabezado del servidor como podemos ver usando la opción response_header_to_remove

Conclusión

Como puede ver, esto no es fácil de implementar. Sin embargo, al mismo tiempo, es evidencia del poder y las capacidades de bajo nivel que tiene al usar una malla de servicios robusta como Istio para interactuar y modificar el comportamiento de cualquier pequeño detalle que desee para su beneficio y, en este caso, también para mejorar y aumentar la seguridad de sus cargas de trabajo desplegadas detrás del alcance de la Malla de Servicios.

En el panorama en constante evolución de las amenazas de ciberseguridad, proteger sus servidores contra la divulgación de información es crucial para proteger datos sensibles y mantener la integridad de su organización. Istio le permite fortalecer la seguridad de su servidor al proporcionar herramientas robustas para la gestión del tráfico, el cifrado y el control de acceso.

Recuerde, la clave para una seguridad adecuada del servidor es un enfoque proactivo que aborde las vulnerabilidades antes de que puedan ser explotadas. Tome la iniciativa de implementar Istio y eleve la protección de su servidor.

📚 Want to dive deeper into Kubernetes? This article is part of our comprehensive Kubernetes Architecture Patterns guide, where you’ll find all fundamental and advanced concepts explained step by step.