Por Mickaël D., experto en DevOps
En lugar de un único artículo general sobre cómo prepararse para una certificación, como os he propuesto en otras ocasiones, voy a iniciar una serie de artículos que os ayudarán a comprender mejor los distintos temas sobre los que se os examinará (si decidís presentarla).

En este dossier, trataremos los siguientes temas:
- La configuración del clúster,
- El Cluster Hardening,
- El endurecimiento de sistemas,
- Las vulnerabilidades de los microservicios,
- La seguridad de la cadena de suministro,
- Supervisión, registro y seguridad en tiempo de ejecución.
Políticas de seguridad de red
Este primer artículo se centrará en el primer aspecto, es decir, la configuración del clúster, y abordará varios puntos, tales como:
- Las políticas de seguridad de red,
- CIS Benchmark para comprobar el nivel de seguridad de la configuración de cada componente de Kubernetes,
- La seguridad de los controladores de acceso,
- La protección de los metadatos de los nodos,
- El uso de la interfaz de usuario de Kubernetes y su seguridad,
- La verificación de los binarios antes de la implementación.
¿Qué son las políticas de seguridad de red?
Se trata de instrucciones destinadas a especificar cómo un Pod puede comunicarse con entidades de la red mediante una combinación de identificadores:
- Los demás pods (excepto él mismo),
- Los espacios de nombres con los que puede comunicarse,
- Los bloques de IP. Atención: en este caso, un Pod puede acceder a cualquier otro Pod ubicado en el mismo nodo.
Cuando se define una política de seguridad para un pod o un espacio de nombres, se utiliza un selector para especificar qué tráfico se permite desde o hacia el pod o el espacio de nombres asociado a dicho selector.
A TENER EN CUENTA:
- Por defecto, los Pods aceptan tráfico procedente de cualquier fuente.
- Las NetworkPolicies se suman y no entran en conflicto entre sí.
- Solo hay un requisito: ¡un plugin de red o CNI que admita políticas de red!
Algunos ejemplos:
1. Limitar el tráfico hacia una aplicación
yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: api-allow
spec:
podSelector:
matchLabels:
app: bookstore
role: api
ingress:
- from:
- podSelector:
matchLabels:
app: bookstore
2. Bloquear el tráfico hacia el exterior del clúster de Kubernetes
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: foo-deny-external-egress
spec:
podSelector:
matchLabels:
app: foo
policyTypes:
- Egress
egress:
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
- to:
- namespaceSelector: {}
3. Rechazar todo el tráfico no incluido en la lista blanca dirigido a un espacio de nombres
yaml
kind: NetworkPolicy
apiVersion: networking.k8s.io/v1
metadata:
name: default-deny-all
namespace: default
spec:
podSelector: {}
ingress: []
Puntos de referencia de CIS
El CIS (Center for Internet Security) es un consorcio sin ánimo de lucro que ofrece guías y herramientas para proteger los entornos informáticos. Es algo parecido ala ANSSI en Francia.
Por defecto, un sistema puede ser vulnerable a muchos tipos de ataques, por lo que es importante protegerlo al máximo. Se hablade «hardening»cuando se refuerza la seguridad de la configuración y el funcionamiento de un sistema.
Dos ejemplos:
- En el caso de un servidor que disponga de puertos USB y cuyo uso no se haya previsto, estos deben desactivarse para prevenir cualquier tipo de ataque a través de este vector.
- ¿Qué usuarios tienen acceso al sistema y pueden iniciar sesión como root? Si estos realizan cambios que afecten al funcionamiento de los servicios, podría resultar imposible identificar al autor de las modificaciones.
Por eso, las mejores prácticas recomiendan desactivar la cuenta de root e iniciar sesión con la propia cuenta para, a continuación, elevar los privilegios de esta (mediante sudo).
Otros ejemplos: solo deben activarse los servicios y/o sistemas de archivos que sean necesarios para el funcionamiento del servidor... Del mismo modo, solo deben abrirse los puertos que sean realmente necesarios y, por lo tanto, hay que configurar el cortafuegos de la forma más precisa posible.
El sitio web CIS ofrece numerosas pruebas de rendimiento y marcos detrabajo de refuerzo de seguridad para :
- Los sistemas operativos Linux, Windows y OS X, así como los sistemas móviles iOS y Android,
- Las plataformas en la nube AWS, Azure, Google,
- Los equipos de red de CheckPoint,Cisco, Juniper y Palo Alto,
- Así como middleware como Tomcat, Docker o Kubernetes.
CIS Benchmark aplicado a Kubernetes: kube-bench
Kube-bench es una aplicación desarrollada en Go, que se basa en gran medida en las recomendaciones de seguridad de CIS con una configuración muy flexible gracias al uso de archivos en y que se puede utilizar de varias maneras diferentes: yaml
- Al instalarlo desde un contenedor
- Instalación mediante el archivo binario descargado
- Al compilar las fuentes
- Al ejecutarlo desde un contenedor, ya sea un contenedor aislado o dentro de un clúster de Kubernetes u Openshift.
Kube-bench ejecuta las comprobaciones definidas en un archivo nombrado yaml y se puede aplicar a cualquier tipo de control.yaml de tipo maestro o esclavo (independientemente de la versión).nodos
id: 1.2
text: Programador
checks:
- id: 1.2.1
text: «Asegúrate de que el argumento --profiling esté establecido en false (Puntuado)»
audit: "ps -ef | grep kube-scheduler | grep -v grep"
tests:
bin_op: or
test_items:
- flag: "--profiling"
set: true
- flag: "--some-other-flag"
set: false
corrección: "Edita el archivo /etc/kubernetes/config en el nodo maestro y
establece el parámetro KUBE_ALLOW_PRIV en '--allow-privileged=false'"
puntuado: true
Una vez que kube-bench ha realizado las pruebas, los resultados se guardan en un archivo y cada prueba indica un estado según una de las cuatro opciones siguientes:
- PASS, La comprobación se ha realizado correctamente.
- FAIL: la comprobación ha fallado, pero la solución describe cómo corregir la configuración para que, en la próxima comprobación, el resultado sea correcto.
- ADVERTENCIA: la prueba requiere especial atención; consulta la solución para obtener más información. No se trata necesariamente de un informe de error.
- INFORMACIÓN
El uso de la interfaz de usuario de Kubernetes y su seguridad
En este caso, se trata de saber cómo instalar el Dashboard de Kubernetes y cómo protegerlo lo mejor posible.
El Dashboard de Kubernetes se implementa mediante el siguiente comando:
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml` y para acceder a él: `kubectl proxy --address 0.0.0.0. Hay que tener en cuenta que:
- Kubernetes admite cuatro modos de autenticación,
- Estos son gestionados por la API de Kubernetes,
- El Dashboard solo actúa como proxy y sirve de pasarela hacia Kubernetes para toda la información relacionada con la autenticación.
Los ataques a través del front-end de Kubernetes son numerosos y, durante mucho tiempo, han sido el principal vector de ataque.
La autenticación
Como se ha mencionado anteriormente, Kubernetes admite cuatro modos de autenticación, a saber:
- Token al portador,
- Nombre de usuario/Contraseña,
- Kubeconfig,
- Encabezado de autorización (compatible desde la versión 1.6 y con la prioridad más alta).
Los tokens al portador
Para configurarlos de la forma más eficaz posible, es necesario estar muy familiarizado con los conceptos de «cuenta de servicio», «rol», «rol de clúster» y los permisos que se les pueden asignar.
Servicio de cuentas
yaml
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
EOF
ClusterRoleBinding
yaml
cat <<EOF | kubectl apply -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
Una vez creados los dos objetos anteriores, se puede obtener el Token al portador mediante el siguiente comando:kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"
Nombre de usuario/Contraseña
Desactivado por defecto, ya que la API de Kubernetes requiere una configuración a nivel de atributos y no a nivel de roles.
Kubeconfig
Con este modo de autenticación, solo se tienen en cuenta las opciones especificadas por el indicador modo de autenticación se incluyen en el archivo el mencionado. De lo contrario, aparecerá un error en el panel de control.
Encabezado de autorización
Para este tipo de método de autenticación, necesitarás el token Bearer, ya que lo requerirás en cada solicitud que realices al panel de control.
La verificación de los archivos binarios antes de la instalación
Se trata, ni más ni menos, de comprobar el valor del hash de los archivos binarios relacionados con Kubernetes y compararlos con los que descargas en tu servidor... por si acaso un hacker interceptara tu acción.
Aunque el llamado «hacker» modifique un archivo del archivo comprimido, hay que tener en cuenta que cualquier modificación de un archivo comprimido también modifica el valor de su hash.
Para ello, una vez finalizada la descarga, puedes ejecutar el siguiente comando: y comparar el valor obtenido con el que aparece en la página de descarga.shasum -a 512 kubernetes.tar.gz
Por ejemplo, al descargar:
kubeadm, versión 1.21.0, cuyo valor hash es 7bdaf0d58f0d286538376bc40b50d7e3ab60a3fe7a0709194f53f1605129550f
Obtendré el mismo valor de , una vez descargado el archivo (esta vez con el comando hash) shasum -a 256 kubeadm
La seguridad de los controladores de acceso
En primer lugar: ¿qué es un controlador de Ingress?
Se trata de unobjeto de Kubernetes que gestiona el acceso externo a los servicios de un clúster, normalmente el tráfico HTTP, y que también puede ofrecer funciones como el equilibrio de carga.
Los temas que se tratarán en esta sección serán:
- La creación de certificados TLS,
- La creación de secretos (que incluyen certificados TLS) en Kubernetes,
- Configuración de los controladores de Ingress que incorporan los secretos.
Creación de un certificado TLS
Partiendo de la base de que ya has creado tu Ingress Controller y que es accesible a través de HTTP, el siguiente paso es proteger su contenido mediante HTTPS... y, por lo tanto, crear un certificado TLS autofirmado:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes
El origen del secreto
Una vez creado el par clave/certificado, y a menos que ya se haya implementado gestor de certificados en Kubernetes, hay que crear un secreto para poder integrar, posteriormente, el certificado TLS en el controlador de Ingress :
kubectl create secret tls-secure-ingress --cert=cert.pem --key=key.pem
Configuración del Ingress Controller
Una vez creados el certificado TLS y la clave secreta, el último paso consiste en integrar la clave secreta en el Ingress Controller.
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- test-secure-ingress.com
secretName: tls-secure-ingress
rules:
- host: test-secure-ingress.com
http:
paths:
- ruta: /service1
tipo de ruta: Prefijo
backend:
servicio:
nombre: service1
puerto:
número: 80
- ruta: /service2
tipo de ruta: Prefijo
backend:
servicio:
nombre: service2
puerto:
número: 80
La protección de los metadatos de los nodos
Los nodos de metadatos... ¿En qué consisten?
Todas las máquinas virtuales (nodos) alojadas en la nube deberían tener acceso a los puntos finales de los metadatos de los nodos por diversas razones.Sin embargo, no se recomienda permitir el acceso a todos los recursos.
Para mejorar la seguridad en este ámbito, es necesario aplicar políticas de red, de modo que solo los recursos designados dentro de los clústeres de Kubernetes puedan comunicarse con los puntos finales de los nodos de metadatos.
Aquí encontrarás toda la información que puedas necesitar sobre el tema:
Políticas de red
El principio de las políticas de red consiste en gestionar la comunicación entre pods, entre pods y servicios, y entre entornos externos y servicios, del mismo modo que lo haría un cortafuegos. La identificación de los recursos afectados sigue siendo responsabilidad de los administradores, mediante etiquetas, espacios de nombres o direcciones IP.
La documentación oficial indica, por ejemplo, lo siguiente:
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: test-network-policy
namespace: default
spec:
podSelector:
matchLabels:
role: 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
puertos:
- protocolo: TCP
puerto: 5978
En este caso, lo que nos interesa principalmente es la posibilidad de bloquear el acceso al Metadata Endpoint mediante políticas de red en uno o varios pods (véase más abajo):
Denegar el tráfico de metadatos
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cloud-metadata-deny
namespace: default
spec:
podSelector: {}
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- <POD_IP_ADDRESS>
Permitir el tráfico hacia los metadatos
yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: cloud-metadata-allow
namespace: default
spec:
podSelector:
matchLabels:
role: metadata-accessor
policyTypes:
- Egress
egress:
- to:
- ipBlock:
cidr: 0.0.0.0/0
except:
- <POD_IP_ADDRESS>
El próximo artículo tratará todas las cuestiones relacionadas con el refuerzo de clústeres, a saber:
- Las restricciones de acceso a la API de Kubernetes,
- El uso del control de acceso basado en roles con el fin de minimizar la exposición,
- El ajuste fino de las cuentas de servicio,
- La frecuencia de las actualizaciones de Kubernetes.
