SELinux · Mandatory Access Control
La diferencia más grande entre Rocky y Ubuntu. SELinux pone una segunda capa de control de acceso que ni root puede saltear. En este proyecto nunca se desactiva. Se configura para que conviva con k3s.
¿Por qué no desactivarlo como hace todo el mundo?
Sin SELinux, un proceso que corre como root tiene acceso a todo. SELinux agrega MAC: cada proceso, archivo y puerto tiene un contexto de seguridad, y el kernel aplica reglas que ni root puede eludir. Así de simple.
- Usuario, grupo, otros (rwx)
- Root puede todo
- Un proceso comprometido como root = sistema comprometido
- No hay control sobre qué puede hacer un proceso con lo que lee
- Contextos de seguridad en cada objeto del sistema
- Ni root puede eludir las reglas
- Un proceso comprometido solo accede a lo que su política permite
- Cada transición entre contextos está controlada
Caso concreto: si alguien explota Grafana y
escala a root, sin SELinux puede leer /etc/shadow.
Con enforcing, el proceso tiene contexto container_t
y el kernel le niega el acceso a archivos shadow_t,
aunque se haya escapado a root. La política gana.
Los tres modos
Enforcing bloquea. Permissive solo registra. Disabled apaga todo. SELinux tiene tres estados operativos. Este proyecto usa exclusivamente enforcing. Es el único modo que tiene sentido en un entorno que se presenta como hardening de producción.
Bloquea y registra. Todo lo que no está en la política se niega y se loguea. Es el modo que usamos: ni siquiera root puede saltearlo.
No bloquea nada, pero registra lo que habría bloqueado. Sirve para debuggear políticas sin romper el sistema.
Apagado del todo. Así viene Ubuntu por default. No lo usamos: si lo desactivás, perdés toda la capa de MAC.
El rol en Ansible
SELinux en enforcing y booleanos para k3s activados. Cero configuración manual. Ansible lo aplica.
Defaults
selinux_mode: enforcing
selinux_booleans:
- name: container_manage_cgroup
state: true
- name: virt_use_nfs
state: true Tasks
- name: Instalar policycoreutils-python-utils (semanage, getsebool)
ansible.builtin.dnf:
name: policycoreutils-python-utils
state: present
- name: Verificar que SELinux esté en modo enforcing
ansible.builtin.selinux:
policy: targeted
state: "{{ selinux_mode }}"
- name: Configurar booleanos de SELinux para k3s y servicios
ansible.posix.seboolean:
name: "{{ item.name }}"
state: "{{ item.state }}"
persistent: true
loop: "{{ selinux_booleans }}"
- name: Mostrar estado de SELinux
ansible.builtin.command:
cmd: sestatus
changed_when: false
register: selinux_status
- name: Debug — estado de SELinux
ansible.builtin.debug:
var: selinux_status.stdout_lines
La tarea ansible.builtin.selinux es el core del
rol. Asegura que la política targeted esté activa
en modo enforcing. La política targeted es la estándar en RHEL
— protege los servicios más comunes sin requerir reglas para
cada proceso del sistema.
Booleanos que k3s necesita
Los booleanos son interruptores de la política. Modifican lo que SELinux permite o bloquea para funcionalidades específicas.
container_manage_cgroup virt_use_nfs Para verificar los booleanos manualmente después de correr el playbook:
Contextos que vas a ver seguido
Cada archivo, proceso y puerto tiene un contexto SELinux. Estos son los tres que aparecen una y otra vez en el lab.
container_file_t Pod volumes, ConfigMap mounts container_runtime_exec_t /usr/bin/containerd ssh_port_t tcp/2222
Para ver el contexto de un archivo o directorio, se usa
ls -Z. Para cambiarlo temporalmente,
chcon. Para hacer el cambio persistente,
semanage fcontext + restorecon.
Chequear que SELinux ande
Playbook terminado → confirmar que SELinux está enforcing y los booleanos activos.
ausearch muestra denegaciones (AVC), usar
audit2why < /var/log/audit/audit.log para
obtener una explicación legible de qué booleano o contexto
falta.
Cuando SELinux rompe algo
Casi siempre es un booleano en false o un contexto incorrecto. Estos son los errores que van a aparecer con k3s.
setsebool -P container_manage_cgroup on chcon -Rt container_file_t /ruta/al/volumen semanage port -a -t ssh_port_t -p tcp 2222 ausearch -m avc -ts recent | audit2why SELinux vs AppArmor
Ubuntu trae AppArmor, Rocky trae SELinux. No son lo mismo y no se reemplazan. Tener experiencia con ambos marca diferencia.
- Etiquetas en cada objeto del filesystem (inodo)
- Política centralizada (
targeted) - Booleanos para ajustar sin tocar la política
- Viene enforcing por defecto en Rocky 9
- Mayor granularidad, mayor complejidad
- Perfiles por aplicación basados en path
- Modo complain/deny por perfil individual
- Más simple de configurar
- Menos granularidad: basa las reglas en rutas de archivo
- Viene con perfiles más permisivos por defecto
¿Por qué el proyecto usa SELinux? Porque es el estándar en entornos RHEL, que dominan el mercado enterprise. Tener un proyecto con SELinux enforcing demuestra que se entiende la capa de seguridad que los entornos corporativos exigen.
Siguiente: Firewalld
Con SELinux protegiendo el acceso a nivel de kernel, la siguiente capa es firewalld, el firewall de red que controla qué puertos y servicios son accesibles desde fuera de la VM.