Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Nota. traducir: El autor del artículo, Reuven Harrison, tiene más de 20 años de experiencia en desarrollo de software y hoy es el CTO y cofundador de Tufin, una empresa que crea soluciones de gestión de políticas de seguridad. Si bien considera que las políticas de red de Kubernetes son una herramienta bastante poderosa para la segmentación de redes en un clúster, también cree que no son tan fáciles de implementar en la práctica. Este material (bastante voluminoso) pretende concienciar a los especialistas sobre este tema y ayudarles a crear las configuraciones necesarias.

Hoy en día, muchas empresas eligen cada vez más Kubernetes para ejecutar sus aplicaciones. El interés en este software es tan grande que algunos llaman a Kubernetes “el nuevo sistema operativo para el centro de datos”. Poco a poco, Kubernetes (o k8s) comienza a ser percibido como una parte crítica del negocio, que requiere la organización de procesos comerciales maduros, incluida la seguridad de la red.

Para los profesionales de la seguridad que están desconcertados al trabajar con Kubernetes, la verdadera revelación puede ser la política predeterminada de la plataforma: permitir todo.

Esta guía le ayudará a comprender la estructura interna de las políticas de red; Comprenda en qué se diferencian de las reglas de los cortafuegos habituales. También cubrirá algunos errores y brindará recomendaciones para ayudar a proteger las aplicaciones en Kubernetes.

Políticas de red de Kubernetes

El mecanismo de política de red de Kubernetes le permite gestionar la interacción de las aplicaciones implementadas en la plataforma en la capa de red (la tercera en el modelo OSI). Las políticas de red carecen de algunas de las características avanzadas de los firewalls modernos, como la aplicación de OSI Layer 7 y la detección de amenazas, pero brindan un nivel básico de seguridad de red que es un buen punto de partida.

Las políticas de red controlan las comunicaciones entre pods.

Las cargas de trabajo en Kubernetes se distribuyen en pods, que constan de uno o más contenedores implementados juntos. Kubernetes asigna a cada pod una dirección IP a la que se puede acceder desde otros pods. Las políticas de red de Kubernetes establecen derechos de acceso para grupos de pods de la misma manera que se utilizan los grupos de seguridad en la nube para controlar el acceso a instancias de máquinas virtuales.

Definición de políticas de red

Al igual que otros recursos de Kubernetes, las políticas de red se especifican en YAML. En el siguiente ejemplo, la aplicación balance el acceso a los postgres:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: balance
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

(Nota. traducir: esta captura de pantalla, como todas las similares posteriores, no se creó utilizando herramientas nativas de Kubernetes, sino utilizando la herramienta Tufin Orca, que fue desarrollada por la empresa del autor del artículo original y que se menciona al final del material).

Para definir su propia política de red, necesitará conocimientos básicos de YAML. Este lenguaje se basa en sangría (especificada por espacios en lugar de tabulaciones). Un elemento sangrado pertenece al elemento sangrado más cercano encima de él. Un nuevo elemento de lista comienza con un guión, todos los demás elementos tienen la forma valor clave.

Habiendo descrito la política en YAML, use kubectlpara crearlo en el cluster:

kubectl create -f policy.yaml

Especificación de política de red

La especificación de la política de red de Kubernetes incluye cuatro elementos:

  1. podSelector: define los pods afectados por esta política (objetivos); obligatorio;
  2. policyTypes: indica qué tipos de políticas se incluyen en esto: entrada y/o salida - opcional, pero recomiendo especificarlo explícitamente en todos los casos;
  3. ingress: define permitido entrante tráfico a los pods de destino: opcional;
  4. egress: define permitido extrovertido El tráfico de los pods de destino es opcional.

Ejemplo tomado del sitio web de Kubernetes (reemplacé role en app), muestra cómo se utilizan los cuatro elementos:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:    # <<<
    matchLabels:
      app: db
  policyTypes:    # <<<
  - Ingress
  - Egress
  ingress:        # <<<
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:         # <<<
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad
Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Tenga en cuenta que no es necesario incluir los cuatro elementos. solo es obligatorio podSelector, se pueden utilizar otros parámetros según se desee.

si omites policyTypes, la póliza se interpretará de la siguiente manera:

  • De forma predeterminada, se supone que define el lado de entrada. Si la política no lo establece explícitamente, el sistema asumirá que todo el tráfico está prohibido.
  • El comportamiento en el lado de salida estará determinado por la presencia o ausencia del parámetro de salida correspondiente.

Para evitar errores lo recomiendo. siempre hazlo explícito policyTypes.

Según la lógica anterior, si los parámetros ingress y / o egress Si se omite, la política denegará todo el tráfico (consulte "Regla de eliminación" a continuación).

La política predeterminada es Permitir

Si no se definen políticas, Kubernetes permite todo el tráfico de forma predeterminada. Todos los pods pueden intercambiar información libremente entre ellos. Esto puede parecer contradictorio desde una perspectiva de seguridad, pero recuerde que Kubernetes fue diseñado originalmente por desarrolladores para permitir la interoperabilidad de las aplicaciones. Las políticas de red se agregaron más tarde.

Espacios de nombres

Los espacios de nombres son el mecanismo de colaboración de Kubernetes. Están diseñados para aislar entornos lógicos entre sí, mientras que la comunicación entre espacios está permitida de forma predeterminada.

Como la mayoría de los componentes de Kubernetes, las políticas de red residen en un espacio de nombres específico. en el bloque metadata puede especificar a qué espacio pertenece la política:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: my-namespace  # <<<
spec:
...

Si el espacio de nombres no se especifica explícitamente en los metadatos, el sistema utilizará el espacio de nombres especificado en kubectl (de forma predeterminada namespace=default):

kubectl apply -n my-namespace -f namespace.yaml

yo recomiendo especificar el espacio de nombres explícitamente, a menos que esté escribiendo una política dirigida a varios espacios de nombres a la vez.

primario элемент podSelector en la política seleccionará pods del espacio de nombres al que pertenece la política (se le niega el acceso a pods de otro espacio de nombres).

De manera similar, podSelectores en bloques de entrada y salida solo puede seleccionar pods de su propio espacio de nombres, a menos, por supuesto, que los combine con namespaceSelector (Esto se discutirá en la sección "Filtrar por espacios de nombres y pods").

Reglas de nomenclatura de políticas

Los nombres de las políticas son únicos dentro del mismo espacio de nombres. No puede haber dos políticas con el mismo nombre en el mismo espacio, pero sí puede haber políticas con el mismo nombre en espacios diferentes. Esto resulta útil cuando desea volver a aplicar la misma política en varios espacios.

Me gusta especialmente uno de los métodos de denominación. Consiste en combinar el nombre del espacio de nombres con los pods de destino. Por ejemplo:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres  # <<<
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: admin
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Etiquetas

Puede adjuntar etiquetas personalizadas a objetos de Kubernetes, como pods y espacios de nombres. Etiquetas (etiquetas - etiquetas) son el equivalente a las etiquetas en la nube. Las políticas de red de Kubernetes utilizan etiquetas para seleccionar vainasa los que se aplican:

podSelector:
  matchLabels:
    role: db

… o espacios de nombresal que se aplican. Este ejemplo selecciona todos los pods en espacios de nombres con las etiquetas correspondientes:

namespaceSelector:
  matchLabels:
    project: myproject

Una precaución: al usar namespaceSelector asegúrese de que los espacios de nombres que seleccione contengan la etiqueta correcta. Tenga en cuenta que los espacios de nombres integrados, como default и kube-system, de forma predeterminada no contienen etiquetas.

Puedes agregar una etiqueta a un espacio como este:

kubectl label namespace default namespace=default

Al mismo tiempo, espacio de nombres en la sección. metadata debe hacer referencia al nombre real del espacio, no a la etiqueta:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default   # <<<
spec:
...

Origen y destino

Las políticas de firewall constan de reglas con orígenes y destinos. Las políticas de red de Kubernetes se definen para un objetivo (un conjunto de pods a los que se aplican) y luego establecen reglas para el tráfico de entrada y/o salida. En nuestro ejemplo, el objetivo de la política serán todos los pods en el espacio de nombres. default con etiqueta con llave app y significado db:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: test-network-policy
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: db   # <<<
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - ipBlock:
        cidr: 172.17.0.0/16
        except:
        - 172.17.1.0/24
    - namespaceSelector:
        matchLabels:
          project: myproject
    - podSelector:
        matchLabels:
          role: frontend
    ports:
    - protocol: TCP
      port: 6379
  egress:
  - to:
    - ipBlock:
        cidr: 10.0.0.0/24
    ports:
    - protocol: TCP
      port: 5978

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad
Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Subsección ingress En esta política, abre el tráfico entrante a los pods de destino. En otras palabras, el ingreso es el origen y el destino es el destino correspondiente. Asimismo, la salida es el destino y el destino es su origen.

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Esto equivale a dos reglas de firewall: Ingress → Target; Meta → Salida.

Salida y DNS (¡importante!)

Al limitar el tráfico saliente, prestar especial atención a DNS - Kubernetes utiliza este servicio para asignar servicios a direcciones IP. Por ejemplo, la siguiente política no funcionará porque no ha permitido la aplicación balance acceder a DNS:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  policyTypes:
  - Egress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Puede solucionarlo abriendo el acceso al servicio DNS:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  - to:               # <<<
    ports:            # <<<
    - protocol: UDP   # <<<
      port: 53        # <<<
  policyTypes:
  - Egress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

último elemento to está vacío y por lo tanto selecciona indirectamente todos los pods en todos los espacios de nombres, permitiendo balance enviar consultas DNS al servicio Kubernetes apropiado (normalmente ejecutándose en el espacio kube-system).

Este enfoque funciona, sin embargo demasiado permisivo e inseguro, porque permite que las consultas DNS se dirijan fuera del clúster.

Puedes mejorarlo en tres pasos sucesivos.

1. Permitir solo consultas DNS dentro agrupar añadiendo namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  - to:
    - namespaceSelector: {} # <<<
    ports:
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

2. Permitir consultas DNS solo dentro del espacio de nombres kube-system.

Para hacer esto necesitas agregar una etiqueta al espacio de nombres. kube-system: kubectl label namespace kube-system namespace=kube-system - y anótelo en la política usando namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  egress:
  - to:
    - podSelector:
        matchLabels:
          app: postgres
  - to:
    - namespaceSelector:         # <<<
        matchLabels:             # <<<
          namespace: kube-system # <<<
    ports:
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

3. Las personas paranoicas pueden ir aún más lejos y limitar las consultas de DNS a un servicio DNS específico en kube-system. La sección "Filtrar por espacios de nombres Y pods" le indicará cómo lograrlo.

Otra opción es resolver DNS a nivel de espacio de nombres. En este caso no será necesario abrirlo para cada servicio:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.dns
  namespace: default
spec:
  podSelector: {} # <<<
  egress:
  - to:
    - namespaceSelector: {}
    ports:
    - protocol: UDP
      port: 53
  policyTypes:
  - Egress

nulo podSelector selecciona todos los pods en el espacio de nombres.

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Primer partido y orden de las reglas

En los firewalls convencionales, la acción (Permitir o Denegar) en un paquete está determinada por la primera regla que satisface. En Kubernetes, el orden de las políticas no importa.

De forma predeterminada, cuando no se establecen políticas, se permiten las comunicaciones entre pods y pueden intercambiar información libremente. Una vez que comienza a formular políticas, cada pod afectado por al menos una de ellas queda aislado según la disyunción (OR lógico) de todas las políticas que lo seleccionaron. Los pods que no se ven afectados por ninguna política permanecen abiertos.

Puede cambiar este comportamiento utilizando una regla de eliminación.

Regla de eliminación ("Denegar")

Las políticas de firewall normalmente niegan cualquier tráfico que no esté permitido explícitamente.

No hay acción de denegación en Kubernetes, sin embargo, se puede lograr un efecto similar con una política regular (permisiva) seleccionando un grupo vacío de pods de origen (ingreso):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Esta política selecciona todos los pods en el espacio de nombres y deja la entrada sin definir, denegando todo el tráfico entrante.

De manera similar, puedes restringir todo el tráfico saliente desde un espacio de nombres:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: deny-all-egress
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Tenga en cuenta que cualquier política adicional que permita el tráfico a pods en el espacio de nombres tendrá prioridad sobre esta regla (similar a agregar una regla de permiso antes de una regla de denegación en una configuración de firewall).

Permitir todo (Cualquiera-Cualquiera-Cualquiera-Permitir)

Para crear una política Permitir todo, debe complementar la política Denegar anterior con un elemento vacío ingress:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
  namespace: default
spec:
  podSelector: {}
  ingress: # <<<
  - {}     # <<<
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Permite el acceso desde todos los pods en todos los espacios de nombres (y todas las IP) a cualquier pod en el espacio de nombres default. Este comportamiento está habilitado de forma predeterminada, por lo que normalmente no es necesario definirlo más. Sin embargo, a veces es posible que necesites desactivar temporalmente algunos permisos específicos para diagnosticar el problema.

La regla se puede limitar para permitir el acceso sólo a un conjunto específico de vainas (app:balance) en el espacio de nombres default:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all-to-balance
  namespace: default
spec:
  podSelector:
    matchLabels:
      app: balance
  ingress: 
  - {}
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

La siguiente política permite todo el tráfico de entrada y salida, incluido el acceso a cualquier IP fuera del clúster:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: allow-all
spec:
  podSelector: {}
  ingress:
  - {}
  egress:
  - {}
  policyTypes:
  - Ingress
  - Egress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad
Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Combinando múltiples políticas

Las políticas se combinan mediante OR lógico en tres niveles; Los permisos de cada pod se establecen de acuerdo con la disyunción de todas las políticas que lo afectan:

1. En los campos from и to Se pueden definir tres tipos de elementos (todos los cuales se combinan mediante OR):

  • namespaceSelector — selecciona todo el espacio de nombres;
  • podSelector — selecciona vainas;
  • ipBlock — selecciona una subred.

Además, el número de elementos (incluso idénticos) en las subsecciones from/to no limitado. Todos ellos se combinarán mediante OR lógico.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
    - podSelector:
        matchLabels:
          app: admin
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

2. Dentro de la sección de políticas ingress puede tener muchos elementos from (combinado por OR lógico). De manera similar, la sección egress puede incluir muchos elementos to (también combinado por disyunción):

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
  - from:
    - podSelector:
        matchLabels:
          app: admin
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

3. También se combinan diferentes políticas con OR lógico

Pero al combinarlos, existe una limitación sobre la cual indicado chris cooney: Kubernetes solo puede combinar políticas con diferentes policyTypes (Ingress o Egress). Las políticas que definen la entrada (o la salida) se sobrescribirán entre sí.

Relación entre espacios de nombres

De forma predeterminada, se permite compartir información entre espacios de nombres. Esto se puede cambiar mediante el uso de una política de denegación que restringirá el tráfico saliente y/o entrante al espacio de nombres (consulte "Regla de eliminación" más arriba).

Una vez que haya bloqueado el acceso a un espacio de nombres (consulte la "Regla de eliminación" más arriba), puede hacer excepciones a la política de denegación permitiendo conexiones desde un espacio de nombres específico usando namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database.postgres
  namespace: database
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - namespaceSelector: # <<<
        matchLabels:
          namespace: default
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Como resultado, todos los pods en el espacio de nombres default tendrá acceso a las cápsulas postgres en el espacio de nombres database. Pero ¿qué pasa si quieres abrir el acceso a postgres solo pods específicos en el espacio de nombres default?

Filtrar por espacios de nombres y pods

Kubernetes versión 1.11 y superior permite combinar operadores namespaceSelector и podSelector usando Y lógico. Se ve así:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database.postgres
  namespace: database
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          namespace: default
      podSelector: # <<<
        matchLabels:
          app: admin
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

¿Por qué se interpreta esto como AND en lugar del habitual OR?

Tenga en cuenta que podSelector no comienza con un guión. En YAML esto significa que podSelector y parado frente a él namespaceSelector referirse al mismo elemento de la lista. Por tanto, se combinan con el AND lógico.

Agregar un guión antes podSelector resultará en la aparición de un nuevo elemento de lista, que se combinará con el anterior namespaceSelector usando OR lógico.

Para seleccionar pods con una etiqueta específica en todos los espacios de nombres, ingrese en blanco namespaceSelector:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: database.postgres
  namespace: database
spec:
  podSelector:
    matchLabels:
      app: postgres
  ingress:
  - from:
    - namespaceSelector: {}
      podSelector:
        matchLabels:
          app: admin
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Varios sellos se unen a mí

Las reglas para un firewall con múltiples objetos (hosts, redes, grupos) se combinan mediante OR lógico. La siguiente regla funcionará si el origen del paquete coincide Host_1 Oregón Host_2:

| Source | Destination | Service | Action |
| ----------------------------------------|
| Host_1 | Subnet_A    | HTTPS   | Allow  |
| Host_2 |             |         |        |
| ----------------------------------------|

Por el contrario, en Kubernetes las distintas etiquetas en podSelector o namespaceSelector se combinan con el Y lógico. Por ejemplo, la siguiente regla seleccionará pods que tengan ambas etiquetas, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

La misma lógica se aplica a todos los tipos de operadores: selectores de objetivos de políticas, selectores de pods y selectores de espacios de nombres.

Subredes y direcciones IP (IPBlocks)

Los firewalls utilizan VLAN, direcciones IP y subredes para segmentar una red.

En Kubernetes, las direcciones IP se asignan a los pods automáticamente y pueden cambiar con frecuencia, por lo que se utilizan etiquetas para seleccionar pods y espacios de nombres en las políticas de red.

Subredes (ipBlocks) se utilizan al gestionar conexiones externas (Norte-Sur) entrantes (de entrada) o salientes (salida). Por ejemplo, esta política se abre a todos los pods del espacio de nombres. default acceso al servicio DNS de Google:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-dns
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 8.8.8.8/32
    ports:
    - protocol: UDP
      port: 53

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

El selector de pods vacío en este ejemplo significa "seleccionar todos los pods en el espacio de nombres".

Esta política sólo permite el acceso a 8.8.8.8; Está prohibido el acceso a cualquier otra IP. Entonces, esencialmente, ha bloqueado el acceso al servicio DNS interno de Kubernetes. Si aún deseas abrirlo, indícalo explícitamente.

En general ipBlocks и podSelectors son mutuamente excluyentes, ya que las direcciones IP internas de los pods no se utilizan en ipBlocks. Al indicar módulos IP internos, en realidad permitirá conexiones hacia/desde pods con estas direcciones. En la práctica, no sabrá qué dirección IP usar, por lo que no deberían usarse para seleccionar pods.

Como contraejemplo, la siguiente política incluye todas las IP y, por lo tanto, permite el acceso a todos los demás pods:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-any
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Puede abrir el acceso solo a IP externas, excluyendo las direcciones IP internas de los pods. Por ejemplo, si la subred de su pod es 10.16.0.0/14:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: egress-any
  namespace: default
spec:
  podSelector: {}
  policyTypes:
  - Egress
  egress:
  - to:
    - ipBlock:
        cidr: 0.0.0.0/0
        except:
        - 10.16.0.0/14

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Puertos y protocolos

Normalmente, los pods escuchan en un puerto. Esto significa que simplemente no puede especificar números de puerto en las políticas y dejar todo como predeterminado. Sin embargo, se recomienda hacer que las políticas sean lo más restrictivas posible, de modo que en algunos casos aún pueda especificar puertos:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
    - podSelector:
        matchLabels:
          app: admin
    ports:             # <<<
      - port: 443      # <<<
        protocol: TCP  # <<<
      - port: 80       # <<<
        protocol: TCP  # <<<
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Tenga en cuenta que el selector ports se aplica a todos los elementos del bloque to o from, que contiene. Para especificar diferentes puertos para diferentes conjuntos de elementos, divida ingress o egress en varias subsecciones con to o from y en cada registro tus puertos:

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: default.postgres
  namespace: default
spec:
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: indexer
    ports:             # <<<
     - port: 443       # <<<
       protocol: TCP   # <<<
  - from:
    - podSelector:
        matchLabels:
          app: admin
    ports:             # <<<
     - port: 80        # <<<
       protocol: TCP   # <<<
  podSelector:
    matchLabels:
      app: postgres
  policyTypes:
  - Ingress

Introducción a las políticas de red de Kubernetes para profesionales de la seguridad

Operación del puerto predeterminado:

  • Si omite la definición del puerto por completo (ports), esto significa todos los protocolos y todos los puertos;
  • Si omite la definición del protocolo (protocol), esto significa TCP;
  • Si omite la definición del puerto (port), es decir, todos los puertos.

Mejores prácticas: no confíe en los valores predeterminados, especifique lo que necesita explícitamente.

Tenga en cuenta que debe utilizar puertos de pod, no puertos de servicio (más sobre esto en el siguiente párrafo).

¿Están definidas políticas para pods o servicios?

Normalmente, los pods de Kubernetes acceden entre sí a través de un servicio: un equilibrador de carga virtual que redirige el tráfico a los pods que implementan el servicio. Se podría pensar que las políticas de red controlan el acceso a los servicios, pero no es así. Las políticas de red de Kubernetes funcionan en puertos de pod, no en puertos de servicio.

Por ejemplo, si un servicio escucha el puerto 80, pero redirige el tráfico al puerto 8080 de sus pods, debe especificar exactamente 8080 en la política de red.

Este mecanismo debe considerarse subóptimo: si la estructura interna del servicio (cuyos puertos escuchan los pods) cambia, las políticas de red deberán actualizarse.

Nuevo enfoque arquitectónico utilizando Service Mesh (por ejemplo, consulte sobre Istio a continuación - traducción aprox.) le permite hacer frente a este problema.

¿Es necesario registrar tanto el ingreso como el egreso?

La respuesta corta es sí, para que el pod A se comunique con el pod B, se le debe permitir crear una conexión saliente (para esto necesita configurar una política de salida) y el pod B debe poder aceptar una conexión entrante ( para esto, en consecuencia, necesita una política de ingreso).

Sin embargo, en la práctica, puede confiar en la política predeterminada para permitir conexiones en una o ambas direcciones.

Si alguna vaina-fuente será seleccionado por uno o más salida-Políticos, las restricciones que se le impongan estarán determinadas por su disyunción. En este caso, deberá permitir explícitamente la conexión al pod.al destinatario. Si ninguna política selecciona un pod, su tráfico saliente (de salida) está permitido de forma predeterminada.

De manera similar, el destino de la vaina esdestinatario, seleccionado por uno o más preámbulo-Los políticos, vendrán determinados por su disyunción. En este caso, debes permitirle explícitamente recibir tráfico desde el pod de origen. Si ninguna política selecciona un pod, todo el tráfico de entrada está permitido de forma predeterminada.

Consulte Con estado o Sin estado a continuación.

Registros

Las políticas de red de Kubernetes no pueden registrar el tráfico. Esto dificulta determinar si una política funciona según lo previsto y complica enormemente el análisis de seguridad.

Control de tráfico a servicios externos

Las políticas de red de Kubernetes no le permiten especificar un nombre de dominio completo (DNS) en las secciones de salida. Este hecho genera importantes inconvenientes al intentar limitar el tráfico a destinos externos que no tienen una dirección IP fija (como aws.com).

Verificación de políticas

Los cortafuegos le avisarán o incluso se negarán a aceptar una política incorrecta. Kubernetes también realiza algunas verificaciones. Al establecer una política de red a través de kubectl, Kubernetes puede declarar que es incorrecta y negarse a aceptarla. En otros casos, Kubernetes tomará la política y la completará con los detalles que faltan. Se pueden ver usando el comando:

kubernetes get networkpolicy <policy-name> -o yaml

Tenga en cuenta que el sistema de validación de Kubernetes no es infalible y puede pasar por alto algunos tipos de errores.

Ejecución

Kubernetes no implementa políticas de red por sí mismo, sino que es simplemente una puerta de enlace API que delega la carga del control a un sistema subyacente llamado Container Networking Interface (CNI). Establecer políticas en un clúster de Kubernetes sin asignar el CNI apropiado es lo mismo que crear políticas en un servidor de administración de firewall sin instalarlas luego en los firewalls. Depende de usted asegurarse de tener un CNI decente o, en el caso de las plataformas Kubernetes, alojado en la nube. (puedes ver la lista de proveedores aquí — aprox. trans.), habilite las políticas de red que configurarán CNI por usted.

Tenga en cuenta que Kubernetes no le avisará si establece una política de red sin el CNI auxiliar adecuado.

¿Con estado o sin estado?

Todos los CNI de Kubernetes que he encontrado tienen estado (por ejemplo, Calico usa Linux conntrack). Esto permite que el pod reciba respuestas sobre la conexión TCP que inició sin tener que restablecerla. Sin embargo, no conozco ningún estándar de Kubernetes que garantice el estado.

Gestión avanzada de políticas de seguridad

A continuación se muestran algunas formas de mejorar la aplicación de políticas de seguridad en Kubernetes:

  1. El patrón arquitectónico Service Mesh utiliza contenedores sidecar para proporcionar telemetría detallada y control del tráfico a nivel de servicio. Como ejemplo podemos tomar Istio.
  2. Algunos de los proveedores de CNI han ampliado sus herramientas para ir más allá de las políticas de red de Kubernetes.
  3. Orca Tufin Proporciona visibilidad y automatización de las políticas de red de Kubernetes.

El paquete Tufin Orca administra las políticas de red de Kubernetes (y es la fuente de las capturas de pantalla anteriores).

información adicional

Conclusión

Las políticas de red de Kubernetes ofrecen un buen conjunto de herramientas para segmentar clústeres, pero no son intuitivas y tienen muchas sutilezas. Debido a esta complejidad, creo que muchas políticas de clusters existentes tienen errores. Las posibles soluciones a este problema incluyen la automatización de las definiciones de políticas o el uso de otras herramientas de segmentación.

Espero que esta guía ayude a aclarar algunas preguntas y resolver los problemas que pueda encontrar.

PD del traductor

Lea también en nuestro blog:

Fuente: habr.com

Añadir un comentario