Aplicar Remediaciones CIS Benchmark en Debian 12 con Ansible

¿Qué es Ansible y la Orquestación de Servidores?

Ansible es una herramienta de automatización y orquestación de servidores basada en archivos YAML llamados playbooks. Permite gestionar configuraciones, implementar software y aplicar cambios en múltiples servidores sin necesidad de agentes adicionales, usando solo SSH.

La orquestación de servidores consiste en coordinar la administración de múltiples máquinas de manera automatizada, asegurando que todas cumplan con ciertos estándares de seguridad y configuración, como los definidos en el CIS Benchmark.

1. Instalación de Ansible

Antes de comenzar, instala Ansible en la máquina de control (desde donde ejecutarás los playbooks). Si usas Debian 12, ejecuta:

sudo apt update
sudo apt install ansible -y

Verifica que Ansible está instalado correctamente con:

ansible --version

2. Estructura de un Playbook de Ansible

Un playbook es un archivo YAML que define las tareas a ejecutar en los servidores. A continuación, un ejemplo básico para aplicar algunas remediaciones de CIS Benchmark en Debian 12:

---
- name: CIS Benchmark Hardening for Debian 12
  hosts: all
  become: yes  # Usa sudo para todas las tareas
  gather_facts: yes  # Recopila información del sistema

  vars:
    # Lista de módulos a deshabilitar.  Ajusta según tus necesidades.
    modules_to_disable:
      - cramfs
      - freevxfs
      - jffs2
      - hfs
      - hfsplus
      - squashfs
      - udf
      # - usb-storage  # Comentar o descomentar según sea necesario

    # Opciones para el montaje de /tmp, /var/tmp, /dev/shm.  Ajusta según tus necesidades.
    tmp_mount_opts: "defaults,rw,nosuid,nodev,noexec,relatime"

  tasks:
    ###########################################################################
    # 1. DESHABILITAR MÓDULOS DEL KERNEL NO NECESARIOS
    ###########################################################################

    - name: "Crear /etc/modprobe.d/{{ item }}.conf"
      ansible.builtin.file:
        path: "/etc/modprobe.d/{{ item }}.conf"
        state: touch
        owner: root
        group: root
        mode: "0644"
      with_items: "{{ modules_to_disable }}"
      when: ansible_virtualization_type != "docker"
      tags: modprobe

    - name: "Agregar 'install {{ item }} /bin/true' a /etc/modprobe.d/{{ item }}.conf"
      ansible.builtin.lineinfile:
        path: "/etc/modprobe.d/{{ item }}.conf"
        line: "install {{ item }} /bin/true"
        create: yes
      with_items: "{{ modules_to_disable }}"
      when: ansible_virtualization_type != "docker"
      tags: modprobe

    - name: "Verificar si el módulo {{ item }} o alguno de sus alias está cargado y descargarlo"
      ansible.builtin.shell: |
        if modinfo {{ item }} &>/dev/null; then
          aliases=$(modinfo {{ item }} | grep alias | awk '{print $2}' | tr '\n' '|')
          if lsmod | grep -E "{{ item }}|$aliases"; then
            rmmod {{ item }}
            exit 0
          fi
        fi
        exit 1
      register: module_loaded
      ignore_errors: yes
      with_items: "{{ modules_to_disable }}"
      when: ansible_virtualization_type != "docker"
      tags: modprobe

    ###########################################################################
    # 2. CONFIGURAR OPCIONES DE MONTAJE PARA /tmp, /var/tmp Y /dev/shm
    ###########################################################################

    - name: "Configurar opciones de montaje para /tmp"
      ansible.builtin.mount:
        path: /tmp
        src: /dev/null  # Usa /dev/null para sistemas que no tienen una partición /tmp dedicada
        fstype: tmpfs
        opts: "{{ tmp_mount_opts }}"
        state: mounted
      tags: tmp

    - name: "Configurar opciones de montaje para /var/tmp"
      ansible.builtin.mount:
        path: /var/tmp
        src: /dev/null
        fstype: tmpfs
        opts: "{{ tmp_mount_opts }}"
        state: mounted
      tags: tmp

    - name: "Configurar opciones de montaje para /dev/shm"
      ansible.builtin.mount:
        path: /dev/shm
        src: /dev/null
        fstype: tmpfs
        opts: "{{ tmp_mount_opts }}"
        state: mounted
      tags: tmp

  handlers:
    - name: Reconstruir initramfs
      ansible.builtin.command: update-initramfs -u
      become: yes  # Requiere privilegios de root
      tags: modprobe

Este es un punto de partida que puede expandirse con otras remediaciones necesarias.

3. Configuración de Ansible para conectarse a los servidores

Debes definir un archivo de inventario que contenga las direcciones de los servidores. Crea un archivo llamado hosts.ini con el siguiente contenido:

[servidores]
192.168.1.100 ansible_user=root ansible_ssh_private_key_file=~/.ssh/id_rsa

Si usas otra clave SSH, ajusta ansible_ssh_private_key_file según corresponda.

4. Ejecutar el Playbook

Para ejecutar el playbook en los servidores definidos en hosts.ini, usa el siguiente comando:

ansible-playbook -i hosts.ini playbook.yml

5. Consejo:

Antes de aplicar estas configuraciones en servidores en producción, es una buena práctica probarlas primero en un entorno de laboratorio. Algunos ajustes pueden afectar el funcionamiento del sistema, por lo que es mejor asegurarse de que todo funciona correctamente. Puedes utilizar máquinas virtuales o contenedores para hacer pruebas sin riesgos y garantizar que las remediaciones se implementen sin inconvenientes.