Descripcion

Preparacion de entorno de detección en la nube CDR (Cloud-Native Detection & Response). Utilizaremos la herramienta Falco en nuestro cluster de K8s con Kubeadm. Falco Es capaz de detectar comportamientos anomalos en los contenedores del cluster, gracias a él podremos tener un control y alertador de un cluster enrome, que de manera individual sería imposible monitorizar. Es imprescindible en un entorno de Kubernetes para un agente de ciberseguridad ya que alertará de todo e indicará detalladamente de los incidentes.

Requisitos

  • Cluster de Kubernetes instalado con Kubeadm.
  • HELM previamente instalado

Instalacion de Falco

Para la instalación utilizaremos el gestor de paquetes de Kubernetes “Helm” Lanzaremos el siguiente comando para agregar el repositorio de la herramienta Falco y actualizar las librerias

helm repo add falcosecurity https://falcosecurity.github.io/charts
helm repo update

Creacion de contenedores Falco

Con el siguiente comando instalaremos falco con los siguientes parametros.

helm install falco falcosecurity/falco \
  --namespace falco \
  --create-namespace \
  --set driver.kind=modern_ebpf \
  --set falcosidekick.enabled=true \
  --set falcosidekick.webui.enabled=true \
  --set collectors.kubernetes.enabled=true \
  --set resources.requests.cpu=100m \
  --set resources.requests.memory=512Mi \
  --set resources.limits.cpu=500m \
  --set resources.limits.memory=1Gi

Donde definimos la creación de un nuevo “namespace”, indicamos el driver de firewall ebpf que se va a utilizar, si hay webUI para la interfaz web, los recursos maximos que va a consumir y su recolección dentro del cluster.

En caso de que falle el contenedor o la creación diagnosticaremos el error con el siguiente comando

kubectl logs -n falco daemonset/falco -c falco-driver-loader

En algunas instalaciones faltan los headers del kernel de linux en los nodos, se instalarán con:

sudo apt install -y linux-headers-$(uname -r)

NOTA: anteriormente se utilizaba “–set driver.kind=ebpf”, esta configuración esta deprecated y actualmente se utiliza “modern_ebpf”. El kernel 6.12 de Debian 13 es demasiado reciente, no hay driver precompilado en los repos de Falco, modern_ebpf usa CO-RE (Compile Once - Run Everywhere) y no necesita el paquete headers.

Existen dos tipos vigilantes que podemos instalar en el cluster.

  • kmod -> integro del kernel de linux escrito en C. (Se carga con insmod)
  • eBPF -> programa que se carga en kernel, mas seguro y dinamico.
    - Más seguro que kmod (el kernel verifica el código)
    - No requiere módulo de kernel compilado aparte
    - Se puede cargar/descargar sin reiniciar

Un posible error es la falta de Volumen Persistente.

Warning FailedScheduling 15m default-scheduler 0/3 nodes are available: pod has unbound immediate PersistentVolumeClaims. not found

Borraremos el despliegue StatefulSet

kubectl delete statefulset falco-falcosidekick-ui-redis -n falco

Actualizaremos el setup de Falco eliminando el volumen persistente (PV) de redis ya que solo necesitaremos falco para detectar los incidentes y enviaremos los datos a plataformas externas o los exportaremos a otros sistemas.

helm upgrade falco falcosecurity/falco \
  --namespace falco \
  --reuse-values \
  --set falcosidekick.webui.redis.storageEnabled=false

Borraremos los pods antiguos para que se vuelvan a crear correctamente apuntando al nuevo Volumen

kubectl delete pod falco-falcosidekick-ui-848fb7b9-5hhvc falco-falcosidekick-ui-848fb7b9-nm429 -n falco

Una vez hayamos instalado los paquetes necesarios reiniciamos los pods de Falco a traves del daemonset.

kubectl rollout restart daemonset/falco -n falco

Monitoreamos la instalación:

kubectl get pods -n falco -o wide -w

Una vez esten todos en “Ready” procederemos a conectar la consola con “port-forward”.

alt text

kubectl port-forward svc/falco-falcosidekick-ui -n falco 2802:2802 --address 0.0.0.0

Accederemos al Dashboard con las credenciales “admin:admin” y accederemos a info para ver las caracteristicas de Falco. (Nota, cambiar la contraseña una vez estemos dentro)

alt text

Veremos que esta vacío asique vamos a generar una alerta para ver si se refleja en el panel. Crearemos un pod de nginx y lanzaremos el comando “cat /etc/shadow” para provocar una lectura de un archivo indebido como el usuario root.

kubectl run nginx --image=nginx

Una vez se haya creado y este en “Ready” nos conectaremos al pod y ejecutaremos el cat.

kubectl exec -it nginx -- /bin/bash
cat /etc/shadow
exit

Vamos a revisar el panel de falco.

alt text

¡Bingo! en el dashboard principal ya nos indica detecciones, avanzaremos a la sección “Events” para ver mas detalles. alt text

Podremos observar como se notifica la hora, el origen y el nodo trabajador desde el que se ha lanzado el comando. Tiene un indicador de prioridad y criticidad de las alertas junto a la regla que ha saltado. Veamos el Output:

22:11:08.847534899: 
Warning Sensitive file opened for reading by non-trusted program 
| file=/etc/shadow gparent=crun ggparent=crio gggparent=systemd 
evt_type=openat user=root user_uid=0 user_loginuid=-1 process=cat 
proc_exepath=/usr/bin/cat parent=bash command=cat /etc/shadow 
terminal=34816 k8smeta_pod_name=nginx k8smeta_ns_name=default 
container_id=8154abbfe223 container_name=nginx 
container_image_repository=docker.io/library/nginx 
container_image_tag=latest k8s_pod_name=nginx k8s_ns_name=default

Desglosando podemos destacar:

  • El comando que se ha ejecutado
    command=cat /etc/shadow
  • El proceso que ha lanzado la alerta con su path process=cat proc_exepath=/usr/bin/cat parent=bash
  • La terminal desde la que se ha lanzado y su pod terminal=34816 k8smeta_pod_name=nginx
  • La imagen de la que se ha obtenido ese pod el nombre y su version container_image_repository=docker.io/library/nginx
    container_image_tag=latest k8s_pod_name=nginx
  • El namespace en el que se encuentra
    k8s_ns_name=default
  • Y el mensaje
    Warning Sensitive file opened for reading by non-trusted program | file=/etc/shadow

Conexion a Grafana

Vamos a conectar Falco con Grafana. Para ello necesitaremos crear un “ServiceMonitor”. Ésto es un servicio íntegro que le indica a prometheus donde ir a buscar (scrapping) para indexar información en su base de datos que posteriormente pintaremos en Grafana.

Crearemos un archivo llamado “falco-servicemonitor.yaml” en el que indicaremos lo siguiente:

cat falco/falco-servicemonitor.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: falco-falcosidekick-monitor
  namespace: monitoring
  labels:
    release: prometheus
  annotations:
    recordatorio-mental: "Este archivo vive en 'monitoring' pero vigila al namespace 'falco' para enviar las alertas a Grafana."
spec:
  namespaceSelector:
    matchNames:
      - falco 
  selector:
    matchLabels:
      app.kubernetes.io/name: falcosidekick
      app.kubernetes.io/component: core
  endpoints:
  - port: http
    interval: 15s
    path: /metrics

Este archivo crea un “ServiceMonitor” en el namespace monitoring con la etiqueta prometheus para que prometheus lo identifique. En las “spec” indicamos con matchNames y namespaceSelector a que namespace ir a buscar los pods para sacar la informacion, con “Selector” y matchLabels indicamos como se llaman los pods a escrapear y por último en endpoints indicaremos el puerto port http que viene definido por Kubernetes y el interval.

Nota: para averiguar el parametro port lanzaremos el siguiente comando

kubectl get svc falco-falcosidekick -n falco -o jsonpath='{.spec.ports[*].name}'

Nos indicará el nombre del puerto que utilzia el servicio de falco-sidekick, normalmente http y http-notls.

Aplicaremos el archivo con

kubectl apply -f falco-servicemonitor.yaml

Comprobamos que se ha creado correctamente.

kubectl get servicemonitor -n monitoring

Debería de aparecer una linea como “falco-falcosidekick-monitor”

Accederemos a prometheus y en la sección targets veremos el “ServiceMonitor” de Falco en estado UP

alt text

Crearemos un nuevo evento con el siguiente comando

kubectl exec -it -n falco $(kubectl get pods -n falco -l app.kubernetes.io/name=falco -o jsonpath='{.items[0].metadata.name}') -- cat /etc/shadow

Nos dirigiremos a Grafana y crearemos una nueva dashboard, creamos una nueva visualización e introducimos Prometheus como origen (source). Indicaremos en el apartado “Metric” el elemento que queramos de Falco (falcosecurity_falcosideckick_falco_envets_total) y veremos como el evento que hemos generado aparece.

alt text

Conclusion

Como podemos ver tenemos una monitorización activa y completa de contenedores que incluso ¡¡SE ACABAN DE CREAR!!
Gracias a esta herramienta el control es absoluto, podremos copiar en formato json la alerta incluso para trasladarla a Grafana o ELK con el scraper de prometheus.
Esta monitorización es muy detallada y profunda, otorgando una gran cantidad de datos y tranquilidad a quien monitoriza un cluster.
Falco es una herramienta muy potente y a tener en cuenta en cualquier despliegue de kubernetes.