Skip to main content

Pregunta 14 | Actividad Syscall

Usar contexto: kubectl config use-context workload-prod

Hay Pods en el Namespace team-yellow. Una investigación de seguridad notó que algunos procesos ejecutándose en estos Pods están usando la Syscall kill, que está prohibida por una política interna del Equipo Yellow.

Encuentra el/los Pod(s) infractor(es) y elimínalos reduciendo las réplicas del Deployment padre a 0.


Respuesta:

Las Syscalls son utilizadas por procesos ejecutándose en el Espacio de Usuario para comunicarse con el Kernel de Linux. Hay muchas syscalls disponibles: https://man7.org/linux/man-pages/man2/syscalls.2.html. Tiene sentido restringirlas para procesos de contenedores y Docker/Containerd ya restringen algunas por defecto, como la Syscall reboot. Restringir aún más es posible por ejemplo usando Seccomp o AppArmor.

Pero para esta tarea debemos simplemente averiguar qué proceso binario ejecuta una Syscall específica. Los procesos en contenedores simplemente se ejecutan en el mismo sistema operativo Linux, pero aislados. Por eso primero verificamos en qué nodos están ejecutándose los Pods:

➜ k -n team-yellow get pod -owide
NAME ... NODE NOMINATED NODE ...
collector1-7585cc58cb-n5rtd 1/1 ... cluster1-node1 <none> ...
collector1-7585cc58cb-vdlp9 1/1 ... cluster1-node1 <none> ...
collector2-8556679d96-z7g7c 1/1 ... cluster1-node1 <none> ...
collector3-8b58fdc88-pjg24 1/1 ... cluster1-node1 <none> ...
collector3-8b58fdc88-s9ltc 1/1 ... cluster1-node1 <none> ...

Todos en cluster1-node1, por lo tanto nos conectamos por ssh y encontramos los procesos para el primer Deployment collector1.

ssh cluster1-node1

➜ root@cluster1-node1:~# crictl pods --name collector1
POD ID CREATED STATE NAME ...
21aacb8f4ca8d 17 minutes ago Ready collector1-7585cc58cb-vdlp9 ...
186631e40104d 17 minutes ago Ready collector1-7585cc58cb-n5rtd ...

➜ root@cluster1-node1:~# crictl ps --pod 21aacb8f4ca8d
CONTAINER ID IMAGE CREATED ... POD ID
9ea02422f8660 5d867958e04e1 12 minutes ago ... 21aacb8f4ca8d

➜ root@cluster1-node1:~# crictl inspect 9ea02422f8660 | grep args -A1
"args": [
"./collector1-process"

Usando crictl pods primero buscamos los Pods del Deployment collector1, que tiene dos réplicas. Luego tomamos un pod-id para encontrar sus contenedores usando crictl ps.

Y finalmente usamos crictl inspect para encontrar el nombre del proceso, que es collector1-process.

Podemos encontrar los PIDs del proceso (dos porque hay dos Pods):

➜ root@cluster1-node1:~# ps aux | grep collector1-process
root 35039 0.0 0.1 702208 1044 ? Ssl 13:37 0:00 ./collector1-process
root 35059 0.0 0.1 702208 1044 ? Ssl 13:37 0:00 ./collector1-process

# Usando los PIDs podemos llamar a strace para encontrar Syscalls:
➜ root@cluster1-node1:~# strace -p 35039
strace: Process 35039 attached
futex(0x4d7e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
kill(666, SIGTERM) = -1 ESRCH (No such process)
epoll_pwait(3, [], 128, 999, NULL, 1) = 0
kill(666, SIGTERM) = -1 ESRCH (No such process)
epoll_pwait(3, [], 128, 999, NULL, 1) = 0
kill(666, SIGTERM) = -1 ESRCH (No such process)
epoll_pwait(3, ^Cstrace: Process 35039 detached
<detached ...>
...

¡Primer intento y ya una captura! Vemos que usa la Syscall prohibida llamando kill(666, SIGTERM).

Ahora verifiquemos los procesos del Deployment collector2:

➜ root@cluster1-node1:~# ps aux | grep collector2-process
root 35375 0.0 0.0 702216 604 ? Ssl 13:37 0:00 ./collector2-process

➜ root@cluster1-node1:~# strace -p 35375
strace: Process 35375 attached
futex(0x4d9e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x4d9e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x4d9e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x4d9e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
...

Se ve bien. ¿Qué hay de collector3?

➜ root@cluster1-node1:~# ps aux | grep collector3-process
root 35155 0.0 0.1 702472 1040 ? Ssl 13:37 0:00 ./collector3-process
root 35241 0.0 0.1 702472 1044 ? Ssl 13:37 0:00 ./collector3-process

➜ root@cluster1-node1:~# strace -p 35155
strace: Process 35155 attached
futex(0x4d9e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x4d9e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
futex(0x4d9e68, FUTEX_WAIT_PRIVATE, 0, NULL) = 0
epoll_pwait(3, [], 128, 999, NULL, 1) = 0
epoll_pwait(3, [], 128, 999, NULL, 1) = 0
...

Tampoco nada sobre la Syscall prohibida. Así que finalizamos la tarea:

k -n team-yellow scale deploy collector1 --replicas 0

Y el mundo es un poco más seguro de nuevo.