Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Nota. transl.: O autor do artigo, Reuven Harrison, ten máis de 20 anos de experiencia no desenvolvemento de software, e hoxe é o CTO e cofundador de Tufin, unha empresa que crea solucións de xestión de políticas de seguridade. Aínda que considera as políticas de rede de Kubernetes como unha ferramenta bastante poderosa para a segmentación de redes nun clúster, tamén cre que non son tan fáciles de implementar na práctica. Este material (bastante voluminoso) está destinado a mellorar a concienciación dos especialistas sobre esta cuestión e axudalos a crear as configuracións necesarias.

Hoxe, moitas empresas elixen cada vez máis Kubernetes para executar as súas aplicacións. O interese por este software é tan grande que algúns chaman a Kubernetes "o novo sistema operativo para o centro de datos". Aos poucos, Kubernetes (ou k8s) comeza a ser percibido como unha parte crítica do negocio, o que require a organización de procesos comerciais maduros, incluída a seguridade da rede.

Para os profesionais da seguridade que están desconcertados ao traballar con Kubernetes, a verdadeira revelación pode ser a política predeterminada da plataforma: permitir todo.

Esta guía axudarache a comprender a estrutura interna das políticas de rede; comprender en que se diferencian das regras dos cortalumes habituais. Tamén cubrirá algunhas trampas e ofrecerá recomendacións para axudar a protexer as aplicacións en Kubernetes.

Políticas de rede de Kubernetes

O mecanismo de política de rede de Kubernetes permítelle xestionar a interacción das aplicacións despregadas na plataforma na capa de rede (a terceira no modelo OSI). As políticas de rede carecen dalgunhas das funcións avanzadas dos firewalls modernos, como a aplicación da capa 7 OSI e a detección de ameazas, pero proporcionan un nivel básico de seguridade de rede que é un bo punto de partida.

As políticas de rede controlan as comunicacións entre pods

As cargas de traballo en Kubernetes distribúense en pods, que consisten nun ou máis contedores despregados xuntos. Kubernetes asigna a cada pod un enderezo IP ao que se pode acceder desde outros pods. As políticas de rede de Kubernetes establecen dereitos de acceso para grupos de pods do mesmo xeito que se usan os grupos de seguranza na nube para controlar o acceso ás instancias de máquinas virtuais.

Definición de políticas de rede

Do mesmo xeito que outros recursos de Kubernetes, as políticas de rede especifícanse en YAML. No seguinte exemplo, a aplicación balance acceso a 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

(Nota. transl.: esta captura de pantalla, como todas outras similares posteriores, creouse non usando ferramentas nativas de Kubernetes, senón coa ferramenta Tufin Orca, que foi desenvolvida pola empresa do autor do artigo orixinal e que se menciona ao final do material.)

Para definir a túa propia política de rede, necesitarás coñecementos básicos de YAML. Esta linguaxe baséase na sangría (especificada por espazos en lugar de tabulacións). Un elemento sangrado pertence ao elemento sangrado máis próximo por riba del. Un novo elemento de lista comeza cun guión, todos os demais elementos teñen a forma clave-valor.

Despois de describir a política en YAML, use kubectlpara crealo no clúster:

kubectl create -f policy.yaml

Especificación da política de rede

A especificación da política de rede de Kubernetes inclúe catro elementos:

  1. podSelector: define os pods afectados por esta política (obxectivos) - necesario;
  2. policyTypes: indica que tipos de políticas se inclúen nesta: entrada e/ou saída - opcional, pero recomendo especificalo expresamente en todos os casos;
  3. ingress: define permitido entrante tráfico a vainas de destino - opcional;
  4. egress: define permitido saínte o tráfico dos pods de destino é opcional.

Exemplo tomado do sitio web de Kubernetes (substituín role en app), mostra como se usan os catro 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade
Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Teña en conta que os catro elementos non teñen que estar incluídos. Só é obrigatorio podSelector, outros parámetros pódense utilizar segundo o desexa.

Se omitimos policyTypes, a política interpretarase do seguinte xeito:

  • Por defecto, asúmese que define o lado de entrada. Se a política non o indica explícitamente, o sistema asumirá que todo o tráfico está prohibido.
  • O comportamento no lado de saída virá determinado pola presenza ou ausencia do correspondente parámetro de saída.

Para evitar erros recomendo explícito sempre policyTypes.

Segundo a lóxica anterior, se os parámetros ingress e / ou egress se omite, a política denegará todo o tráfico (consulta a "Regra de eliminación" a continuación).

A política predeterminada é Permitir

Se non se definen políticas, Kubernetes permite todo o tráfico de forma predeterminada. Todos os pods poden intercambiar información libremente entre eles. Isto pode parecer contra-intuitivo desde o punto de vista da seguridade, pero lembre que Kubernetes foi deseñado orixinalmente polos desenvolvedores para permitir a interoperabilidade das aplicacións. As políticas de rede engadíronse máis tarde.

Espazos de nomes

Os espazos de nomes son o mecanismo de colaboración de Kubernetes. Están deseñados para illar ambientes lóxicos entre si, mentres que a comunicación entre espazos está permitida por defecto.

Como a maioría dos compoñentes de Kubernetes, as políticas de rede viven nun espazo de nomes específico. No bloque metadata pode especificar a que espazo pertence a política:

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

Se o espazo de nomes non se especifica explícitamente nos metadatos, o sistema usará o espazo de nomes especificado en kubectl (por defecto namespace=default):

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

eu recomendo especifique o espazo de nomes de forma explícita, a menos que estea escribindo unha política que teña como destino varios espazos de nomes á vez.

O principal elemento podSelector na política seleccionará pods do espazo de nomes ao que pertence a política (négaselle o acceso a pods desde outro espazo de nomes).

Do mesmo xeito, podSelectors nos bloques de entrada e saída só pode seleccionar pods do seu propio espazo de nomes, a menos que, por suposto, os combines con eles namespaceSelector (Isto comentarase na sección "Filtrar por espazos de nomes e pods").

Normas de nomeamento das políticas

Os nomes das políticas son únicos dentro do mesmo espazo de nomes. Non pode haber dúas políticas co mesmo nome no mesmo espazo, pero pode haber políticas co mesmo nome en espazos diferentes. Isto é útil cando queres volver aplicar a mesma política en varios espazos.

Gústame especialmente un dos métodos de nomeamento. Consiste en combinar o nome do espazo de nomes cos pods de destino. Por exemplo:

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Etiquetas

Podes engadir etiquetas personalizadas a obxectos de Kubernetes, como pods e espazos de nomes. Etiquetas (etiquetas - tags) son o equivalente ás etiquetas na nube. As políticas de rede de Kubernetes usan etiquetas para seleccionar vainasaos que se aplican:

podSelector:
  matchLabels:
    role: db

… ou espazos de nomesaos que se aplican. Este exemplo selecciona todos os pods en espazos de nomes coas etiquetas correspondentes:

namespaceSelector:
  matchLabels:
    project: myproject

Unha precaución: ao usar namespaceSelector asegúrese de que os espazos de nomes que seleccione conteñan a etiqueta correcta. Teña en conta que espazos de nomes integrados como default и kube-system, por defecto non conteñen etiquetas.

Podes engadir unha etiqueta a un espazo como este:

kubectl label namespace default namespace=default

Ao mesmo tempo, espazo de nomes na sección metadata debería referirse ao nome do espazo real, non á etiqueta:

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

Orixe e destino

As políticas de firewall consisten en regras con fontes e destinos. As políticas de rede de Kubernetes defínense para un destino (un conxunto de pods aos que se aplican) e despois establecen regras para o tráfico de entrada e/ou saída. No noso exemplo, o obxectivo da política serán todos os pods do espazo de nomes default con etiqueta con chave app e 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade
Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Subsección ingress nesta política, abre o tráfico entrante aos grupos de destino. Noutras palabras, a entrada é a orixe e o destino é o destino correspondente. Así mesmo, a saída é o destino e o destino é a súa orixe.

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Isto equivale a dúas regras de firewall: Entrada → Destino; Obxectivo → Saída.

Saída e DNS (importante!)

Ao limitar o tráfico de saída, preste especial atención ao DNS - Kubernetes usa este servizo para mapear servizos a enderezos IP. Por exemplo, a seguinte política non funcionará porque non permitiu a aplicación balance acceso 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Podes solucionalo abrindo o acceso ao servizo 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Último elemento to está baleiro e, polo tanto, selecciona indirectamente todos os pods en todos os espazos de nomes, permitindo balance enviar consultas DNS ao servizo Kubernetes adecuado (normalmente en execución no espazo kube-system).

Este enfoque funciona, con todo excesivamente permisiva e insegura, porque permite que as consultas DNS sexan dirixidas fóra do clúster.

Podes melloralo en tres pasos sucesivos.

1. Permitir só consultas DNS dentro cluster engadindo 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

2. Permitir consultas DNS só dentro do espazo de nomes kube-system.

Para iso cómpre engadir unha etiqueta ao espazo de nomes kube-system: kubectl label namespace kube-system namespace=kube-system - e anótao na 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

3. As persoas paranoicas poden ir aínda máis lonxe e limitar as consultas de DNS a un servizo DNS específico kube-system. A sección "Filtrar por espazos de nomes E pods" indicarache como conseguilo.

Outra opción é resolver o DNS a nivel de espazo de nomes. Neste caso, non será necesario abrir para cada servizo:

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

Baleiro podSelector selecciona todos os pods no espazo de nomes.

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Primeira partida e orde de regras

Nos firewalls convencionais, a acción (Permitir ou Denegar) nun paquete está determinada pola primeira regra que cumpra. En Kubernetes, a orde das políticas non importa.

De forma predeterminada, cando non se definen políticas, permítense comunicacións entre pods e poden intercambiar información libremente. Unha vez que comeza a formular políticas, cada pod afectado por polo menos un deles queda illado segundo a disxunción (OU lóxico) de todas as políticas que o seleccionaron. As cápsulas non afectadas por ningunha política permanecen abertas.

Podes cambiar este comportamento usando unha regra de eliminación.

Regra de eliminación ("Denegar")

As políticas de firewall normalmente negan calquera tráfico que non estea permitido explícitamente.

Non hai ningunha acción de negar en Kubernetes, non obstante, pódese conseguir un efecto semellante cunha política regular (permisiva) seleccionando un grupo baleiro de pods fonte (entrada):

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Esta política selecciona todos os pods do espazo de nomes e deixa a entrada sen definir, o que nega todo o tráfico entrante.

Do mesmo xeito, pode restrinxir todo o tráfico saínte dun espazo de nomes:

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Teña en conta que Calquera política adicional que permita o tráfico a pods no espazo de nomes terá prioridade sobre esta regra (semellante a engadir unha regra de permiso antes dunha regra de denegación nunha configuración de firewall).

Permitir todo (Calquera-Calquera-Calquera-Permitir)

Para crear unha política Permitir todo, cómpre complementar a política Denegar anterior cun elemento baleiro ingress:

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Permite o acceso desde todos os pods de todos os espazos de nomes (e toda a IP) a calquera pod do espazo de nomes default. Este comportamento está activado por defecto, polo que normalmente non é necesario definir máis. Non obstante, ás veces pode ter que desactivar temporalmente algúns permisos específicos para diagnosticar o problema.

A regra pódese reducir para permitir o acceso só a un conxunto específico de vainas (app:balance) no espazo de nomes default:

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

A seguinte política permite todo o tráfico de entrada e saída, incluído o acceso a calquera IP fóra do clúster:

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade
Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Combinando varias políticas

As políticas combínanse usando OU lóxico en tres niveis; Os permisos de cada pod establécense de acordo coa disxunción de todas as políticas que o afectan:

1. Nos campos from и to Pódense definir tres tipos de elementos (todos os cales se combinan mediante OR):

  • namespaceSelector — selecciona todo o espazo de nomes;
  • podSelector - selecciona vainas;
  • ipBlock — selecciona unha subrede.

Ademais, o número de elementos (mesmo idénticos) en subseccións from/to non limitado. Todos eles combinaranse por OU lóxico.

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

2. Dentro da sección de políticas ingress pode ter moitos elementos from (combinado por OR lóxico). Do mesmo xeito, sección egress pode incluír moitos elementos to (tamén combinado por disxunció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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

3. Tamén se combinan diferentes políticas co OU lóxico

Pero ao combinalos, hai unha limitación sinalou Chris Cooney: Kubernetes só pode combinar políticas con diferentes policyTypes (Ingress ou Egress). As políticas que definen a entrada (ou a saída) sobrescribiranse entre si.

Relación entre espazos de nomes

De forma predeterminada, está permitido compartir información entre espazos de nomes. Isto pódese cambiar usando unha política de denegación que restrinxirá o tráfico de saída e/ou entrada no espazo de nomes (consulta "Regra de eliminación" máis arriba).

Unha vez que bloquee o acceso a un espazo de nomes (consulte a "Regra de eliminación" anterior), pode facer excepcións á política de denegación permitindo conexións desde un espazo de nomes 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Como resultado, todos os pods no espazo de nomes default terá acceso ás vainas postgres no espazo de nomes database. Pero que pasa se queres abrir o acceso postgres só pods específicos no espazo de nomes default?

Filtra por espazos de nomes e pods

Kubernetes versión 1.11 e superior permítelle combinar operadores namespaceSelector и podSelector usando AND lóxico. Parece 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Por que se interpreta isto como AND en lugar do habitual OU?

Nótese que podSelector non comeza cun guión. En YAML isto significa que podSelector e de pé diante del namespaceSelector referirse ao mesmo elemento da lista. Polo tanto, combínanse co AND lóxico.

Engadindo un guión antes podSelector dará lugar á aparición dun novo elemento de lista, que se combinará co anterior namespaceSelector usando OR lóxico.

Para seleccionar vainas cunha etiqueta específica en todos os espazos de nomes, escriba en branco 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Varias etiquetas se unen con I

As regras para un cortalumes con varios obxectos (anfitrións, redes, grupos) combínanse mediante OR lóxico. A seguinte regra funcionará se a orixe do paquete coincide Host_1 Ou Host_2:

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

Pola contra, en Kubernetes as distintas etiquetas en podSelector ou namespaceSelector combínanse con AND lóxico. Por exemplo, a seguinte regra seleccionará pods que teñan ambas as etiquetas, role=db И version=v2:

podSelector:
  matchLabels:
    role: db
    version: v2

A mesma lóxica aplícase a todos os tipos de operadores: selectores de obxectivos de políticas, selectores de pods e selectores de espazos de nomes.

Subredes e enderezos IP (IPBlocks)

Os firewalls usan VLAN, enderezos IP e subredes para segmentar unha rede.

En Kubernetes, os enderezos IP asígnanse aos pods automaticamente e poden cambiar con frecuencia, polo que as etiquetas úsanse para seleccionar pods e espazos de nomes nas políticas de rede.

Subredes (ipBlocks) utilízanse cando se xestionan conexións externas (norte-sur) de entrada (entrada) ou de saída (saída). Por exemplo, esta política ábrese a todos os pods do espazo de nomes default acceso ao servizo 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

O selector de pods baleiros neste exemplo significa "seleccionar todos os pods do espazo de nomes".

Esta política só permite o acceso a 8.8.8.8; o acceso a calquera outra IP está prohibido. Polo tanto, en esencia, bloqueou o acceso ao servizo interno de DNS de Kubernetes. Se aínda queres abrilo, indícalo de forma explícita.

Xeralmente ipBlocks и podSelectors son mutuamente excluíntes, xa que os enderezos IP internos dos pods non se utilizan ipBlocks. Ao indicar Pods IP internos, en realidade permitirás conexións a/desde pods con estes enderezos. Na práctica, non saberás que enderezo IP usar, polo que non se deberían usar para seleccionar pods.

Como contraexemplo, a seguinte política inclúe todas as IP e, polo tanto, permite o acceso a todos os demais 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Podes abrir o acceso só a IPs externas, excluíndo os enderezos IP internos dos pods. Por exemplo, se a subrede do teu pod é 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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Portos e protocolos

Normalmente os pods escoitan un porto. Isto significa que simplemente non pode especificar os números de porto nas políticas e deixar todo como predeterminado. Non obstante, recoméndase facer políticas o máis restritivas posible, polo que nalgúns casos aínda pode especificar portos:

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Teña en conta que o selector ports aplícase a todos os elementos do bloque to ou from, que contén. Para especificar portos diferentes para diferentes conxuntos de elementos, divídeo ingress ou egress en varias subseccións con to ou from e en cada rexistro os seus portos:

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

Unha introdución ás políticas de rede de Kubernetes para profesionais da seguridade

Operación do porto predeterminado:

  • Se omites completamente a definición do porto (ports), isto significa todos os protocolos e todos os portos;
  • Se omite a definición do protocolo (protocol), isto significa TCP;
  • Se omite a definición de porto (port), isto significa todos os portos.

Práctica recomendada: non confíe nos valores predeterminados, especifique o que precisa de forma explícita.

Teña en conta que debe usar portos de pod, non portos de servizo (máis sobre isto no seguinte parágrafo).

Están definidas políticas para pods ou servizos?

Normalmente, os pods en Kubernetes acceden entre si a través dun servizo: un equilibrador de carga virtual que redirixe o tráfico aos pods que implementan o servizo. Podes pensar que as políticas de rede controlan o acceso aos servizos, pero este non é o caso. As políticas de rede de Kubernetes funcionan nos portos de pod, non nos portos de servizo.

Por exemplo, se un servizo escoita o porto 80, pero redirixe o tráfico ao porto 8080 dos seus pods, debes especificar exactamente 8080 na política de rede.

Tal mecanismo debería considerarse subóptimo: se a estrutura interna do servizo (os portos dos que escoitan os pods) cambia, as políticas de rede terán que ser actualizadas.

Novo enfoque arquitectónico usando Service Mesh (por exemplo, consulte sobre Istio a continuación - aprox. trad.) permítelle xestionar este problema.

É necesario rexistrar tanto a entrada como a saída?

A resposta curta é si, para que o pod A se comunique co pod B, debe permitirse crear unha conexión de saída (para iso é necesario configurar unha política de saída) e o pod B debe poder aceptar unha conexión entrante ( para iso, en consecuencia, precisa unha política de ingreso). política).

Non obstante, na práctica, pode confiar na política predeterminada para permitir conexións nunha ou ambas direccións.

Se algunha vaina-fonte será seleccionado por un ou máis saída-os políticos, as restricións que se lle impoñan virán determinadas pola súa disxunción. Neste caso, terás que permitir explícitamente a conexión ao pod -destinatario. Se ningunha política selecciona un pod, o seu tráfico de saída (saída) está permitido de forma predeterminada.

Do mesmo xeito, o destino da vaina édestinatario, seleccionado por un ou máis entrada-políticos, estarán determinadas pola súa disxunción. Neste caso, debes permitir explícitamente que reciba tráfico do pod de orixe. Se ningunha política selecciona un pod, todo o tráfico de entrada está permitido por defecto.

Consulte con estado ou sen estado a continuación.

Rexistros

As políticas de rede de Kubernetes non poden rexistrar o tráfico. Isto dificulta determinar se unha política funciona como se pretende e dificulta moito a análise da seguridade.

Control do tráfico a servizos externos

As políticas de rede de Kubernetes non che permiten especificar un nome de dominio completo (DNS) nas seccións de saída. Este feito provoca importantes inconvenientes cando se intenta limitar o tráfico a destinos externos que non teñen un enderezo IP fixo (como aws.com).

Verificación de políticas

Os firewalls avisarán ou mesmo rexeitarán aceptar a política incorrecta. Kubernetes tamén realiza algunha verificación. Ao establecer unha política de rede a través de kubectl, Kubernetes pode declarar que é incorrecta e negarse a aceptala. Noutros casos, Kubernetes tomará a política e encheraa cos detalles que faltan. Pódense ver usando o comando:

kubernetes get networkpolicy <policy-name> -o yaml

Ten en conta que o sistema de validación de Kubernetes non é infalible e pode perder algúns tipos de erros.

Execución

Kubernetes non implementa políticas de rede en si, senón que é só unha pasarela de API que delega a carga do control nun sistema subxacente chamado Container Networking Interface (CNI). Establecer políticas nun clúster de Kubernetes sen asignar o CNI axeitado é o mesmo que crear políticas nun servidor de xestión de firewall sen instalalas despois en firewalls. Depende de ti asegurarte de ter un CNI digno ou, no caso das plataformas Kubernetes, aloxado na nube (podes ver a lista de provedores aquí - aprox. trans.), activa as políticas de rede que configurarán CNI por ti.

Teña en conta que Kubernetes non che avisará se estableces unha política de rede sen o CNI auxiliar adecuado.

Con estado ou sen estado?

Todos os CNI de Kubernetes que atopei teñen estado (por exemplo, Calico usa Linux conntrack). Isto permite que o pod reciba respostas na conexión TCP que iniciou sen ter que restablecela. Non obstante, non coñezo un estándar de Kubernetes que garanta o estado.

Xestión avanzada de políticas de seguridade

Aquí tes algunhas formas de mellorar a aplicación das políticas de seguranza en Kubernetes:

  1. O patrón arquitectónico Service Mesh usa contedores sidecar para proporcionar telemetría detallada e control de tráfico a nivel de servizo. Como exemplo podemos tomar Istio.
  2. Algúns dos provedores de CNI ampliaron as súas ferramentas para ir máis aló das políticas de rede de Kubernetes.
  3. Tufin Orca Ofrece visibilidade e automatización das políticas de rede de Kubernetes.

O paquete Tufin Orca xestiona as políticas de rede de Kubernetes (e é a fonte das capturas de pantalla anteriores).

información adicional

Conclusión

As políticas de rede de Kubernetes ofrecen un bo conxunto de ferramentas para segmentar clústeres, pero non son intuitivas e teñen moitas sutilezas. Debido a esta complexidade, creo que moitas políticas de clúster existentes teñen erros. As posibles solucións a este problema inclúen a automatización das definicións de políticas ou o uso doutras ferramentas de segmentación.

Espero que esta guía axude a aclarar algunhas dúbidas e a resolver os problemas que poida atopar.

PS do tradutor

Lea tamén no noso blog:

Fonte: www.habr.com

Engadir un comentario