Hardening de Linux con CIS Benchmarks

Los CIS Benchmarks (Center for Internet Security) son el estándar de referencia mundial para el hardening de servidores Linux, proporcionando guías de configuración segura probadas por la industria y auditadas continuamente. Esta guía explica cómo aplicar los CIS Benchmarks en Ubuntu y CentOS, cómo realizar evaluaciones automatizadas, remediar configuraciones y mantener la conformidad continua.

Requisitos Previos

  • Ubuntu 20.04/22.04 LTS o CentOS 7/8 / Rocky Linux 8/9
  • Acceso root o sudo
  • Entorno de staging para probar los cambios antes de producción
  • Backup completo del sistema antes de aplicar cambios
# Crear una snapshot o backup antes de empezar
# En un VPS, crear un snapshot desde el panel de control

# Documentar el estado inicial del sistema
uname -a
lsb_release -a
systemctl list-units --state=running | wc -l

Niveles de CIS Benchmarks

Los CIS Benchmarks tienen dos niveles de perfil:

  • Nivel 1 (L1): Configuraciones básicas de seguridad con mínimo impacto en funcionalidad. Recomendado para todos los sistemas.
  • Nivel 2 (L2): Hardening intensivo para sistemas de alta seguridad. Puede requerir ajustes según el caso de uso.
# Descargar los CIS Benchmarks (gratuito con registro en cisecurity.org)
# Los PDF están disponibles en: https://www.cisecurity.org/cis-benchmarks/

# Herramientas de evaluación automática:
# 1. Lynis (código abierto)
# 2. OpenSCAP (estándar SCAP)
# 3. CIS-CAT (herramienta oficial de CIS, versión Pro de pago)

Evaluación Inicial con Lynis

# Instalar Lynis para evaluación de seguridad
apt install -y lynis  # Ubuntu/Debian
# dnf install -y lynis  # CentOS/Rocky

# Ejecutar una auditoría completa del sistema
lynis audit system

# La puntuación "Hardening index" indica el nivel de seguridad (0-100)
lynis audit system 2>/dev/null | grep "Hardening index"

# Ver solo las advertencias y sugerencias
lynis audit system 2>/dev/null | grep -E "^Warning|^Suggestion"

# Ver el informe completo
cat /var/log/lynis.log

# Guardar el informe de auditoría
lynis audit system --log-file /var/log/lynis-$(date +%Y%m%d).log

Usar OpenSCAP para evaluación contra CIS:

# Instalar OpenSCAP
apt install -y libopenscap8 openscap-scanner

# Descargar el perfil SCAP para Ubuntu (OVAL/XCCDF)
wget https://security-metadata.canonical.com/oval/oci.ubuntu.jammy.usn.oval.xml.bz2

# Escanear el sistema contra el perfil CIS Level 1
oscap xccdf eval \
    --profile xccdf_org.ssgproject.content_profile_cis_level1_server \
    --results /tmp/resultados-cis.xml \
    --report /tmp/reporte-cis.html \
    /usr/share/xml/scap/ssg/content/ssg-ubuntu2204-xccdf.xml

# Ver el reporte
xdg-open /tmp/reporte-cis.html  # O copiar el HTML a tu máquina local

Hardening del Sistema de Archivos

# CIS 1.1 - Configuración del sistema de archivos

# Deshabilitar sistemas de archivos no utilizados (CIS 1.1.1)
cat << 'EOF' > /etc/modprobe.d/cis-filesystems.conf
# CIS Benchmark: Deshabilitar sistemas de archivos innecesarios
install cramfs /bin/true
install freevxfs /bin/true
install jffs2 /bin/true
install hfs /bin/true
install hfsplus /bin/true
install squashfs /bin/true
install udf /bin/true
EOF

# Verificar que el módulo está deshabilitado
modprobe -n -v cramfs

# CIS 1.1.2 - Opciones de montaje seguras para /tmp
# Si /tmp no es una partición separada, crear un tmpfs
cat << 'EOF' >> /etc/fstab
# /tmp montado como tmpfs con opciones de seguridad
tmpfs /tmp tmpfs defaults,rw,nosuid,nodev,noexec,relatime 0 0
EOF

mount -o remount /tmp

# Verificar las opciones de montaje
mount | grep /tmp

# CIS 1.1 - Opciones de /var/tmp
cat << 'EOF' >> /etc/fstab
tmpfs /var/tmp tmpfs defaults,rw,nosuid,nodev,noexec,relatime 0 0
EOF

# Permisos del directorio /tmp (CIS 1.1.10)
chmod 1777 /tmp
chmod 1777 /var/tmp

Hardening de Servicios del Sistema

# CIS 2.1 - Servicios de tiempo

# Instalar y configurar systemd-timesyncd o chrony
timedatectl set-ntp true
timedatectl status

# CIS 2.2 - Deshabilitar servicios innecesarios
# Lista de servicios comúnmente innecesarios en servidores
SERVICIOS_INNECESARIOS=(
    "avahi-daemon"    # Descubrimiento de servicios en red local
    "cups"            # Sistema de impresión
    "dhcpd"           # Servidor DHCP (solo si no lo usas)
    "slapd"           # Servidor LDAP
    "nfs"             # NFS (solo si no lo usas)
    "rpcbind"         # Portmapper RPC
    "bind9"           # Servidor DNS
    "vsftpd"          # Servidor FTP
    "dovecot"         # Servidor IMAP/POP3
    "samba"           # Compartición de archivos Windows
    "squid"           # Proxy web
    "snmpd"           # SNMP (si no lo usas para monitorización)
)

for SERVICIO in "${SERVICIOS_INNECESARIOS[@]}"; do
    if systemctl is-active "$SERVICIO" &>/dev/null; then
        echo "Deshabilitando: $SERVICIO"
        systemctl stop "$SERVICIO"
        systemctl disable "$SERVICIO"
    fi
done

# CIS 2.3 - Eliminar paquetes innecesarios
apt purge -y xserver-xorg* gdm3 lightdm  # Eliminar entorno gráfico en servidores
apt autoremove -y

Configuración de Red Segura

# CIS 3.1 - Configuración de parámetros del kernel para red

cat << 'EOF' > /etc/sysctl.d/99-cis-network.conf
# CIS Benchmark - Parámetros de red seguros

# Deshabilitar el reenvío de paquetes IP (a menos que el servidor sea router)
net.ipv4.ip_forward = 0
net.ipv6.conf.all.forwarding = 0

# Deshabilitar la aceptación de paquetes de redireccionamiento (ICMP redirect)
net.ipv4.conf.all.accept_redirects = 0
net.ipv4.conf.default.accept_redirects = 0
net.ipv6.conf.all.accept_redirects = 0

# Deshabilitar el envío de ICMP redirects
net.ipv4.conf.all.send_redirects = 0
net.ipv4.conf.default.send_redirects = 0

# Habilitar protección contra Source Route (ataques de enrutamiento de origen)
net.ipv4.conf.all.accept_source_route = 0
net.ipv4.conf.default.accept_source_route = 0

# Habilitar la protección TCP SYN flood
net.ipv4.tcp_syncookies = 1

# Registrar paquetes martians (IPs fuente inválidas)
net.ipv4.conf.all.log_martians = 1
net.ipv4.conf.default.log_martians = 1

# Deshabilitar la aceptación de mensajes ICMP broadcast
net.ipv4.icmp_echo_ignore_broadcasts = 1

# Ignorar respuestas ICMP bogus
net.ipv4.icmp_ignore_bogus_error_responses = 1

# Habilitar la verificación del path de retorno (rpfilter)
net.ipv4.conf.all.rp_filter = 1
net.ipv4.conf.default.rp_filter = 1

# Deshabilitar IPv6 si no se usa
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
EOF

# Aplicar los cambios
sysctl --system

# Verificar los parámetros
sysctl net.ipv4.tcp_syncookies
sysctl net.ipv4.conf.all.log_martians

Políticas de Contraseñas y Autenticación

# CIS 5.3 - Configurar PAM para contraseñas seguras
apt install -y libpam-pwquality

# Configurar la complejidad de contraseñas
cat << 'EOF' > /etc/security/pwquality.conf
# CIS Benchmark - Política de contraseñas
minlen = 14          # Longitud mínima de 14 caracteres
dcredit = -1         # Al menos 1 número
ucredit = -1         # Al menos 1 mayúscula
ocredit = -1         # Al menos 1 carácter especial
lcredit = -1         # Al menos 1 minúscula
maxrepeat = 3        # No más de 3 caracteres consecutivos iguales
dictcheck = 1        # Verificar contra el diccionario de contraseñas comunes
EOF

# Configurar el bloqueo de cuenta por intentos fallidos (CIS 5.3.2)
cat << 'EOF' > /etc/security/faillock.conf
# CIS - Bloquear cuenta después de 5 intentos fallidos
deny = 5
fail_interval = 900  # Ventana de tiempo: 15 minutos
unlock_time = 900    # Tiempo de bloqueo: 15 minutos
audit
EOF

# CIS 5.4 - Caducidad de contraseñas
cat << 'EOF' > /etc/login.defs
# CIS Benchmark - Política de caducidad de contraseñas
PASS_MAX_DAYS   365    # Máximo 365 días de validez
PASS_MIN_DAYS   1      # Mínimo 1 día entre cambios
PASS_WARN_AGE   7      # Advertir 7 días antes de la caducidad
EOF

# CIS 5.2 - Configurar sudo con registro de comandos
cat << 'EOF' >> /etc/sudoers.d/cis-hardening
# CIS - Requerir contraseña para sudo y registrar
Defaults    logfile=/var/log/sudo.log
Defaults    use_pty
Defaults    requiretty
EOF

# CIS 5.2.1 - Configuración segura de SSH
cat << 'EOF' > /etc/ssh/sshd_config.d/99-cis.conf
# CIS Benchmark - Configuración de SSH
Protocol 2
PermitRootLogin no
MaxAuthTries 4
PermitEmptyPasswords no
PasswordAuthentication no      # Usar solo claves SSH
PubkeyAuthentication yes
IgnoreRhosts yes
HostbasedAuthentication no
PermitUserEnvironment no
ClientAliveInterval 300        # Desconectar sesiones inactivas después de 5 min
ClientAliveCountMax 0
LoginGraceTime 60
AllowGroups ssh-users          # Solo usuarios del grupo ssh-users pueden conectar
X11Forwarding no
LogLevel VERBOSE
EOF

# Crear el grupo ssh-users y añadir los usuarios autorizados
groupadd ssh-users
usermod -aG ssh-users tu_usuario

systemctl restart sshd

Auditoría y Logging

# CIS 4.1 - Configurar auditd para el logging de seguridad
apt install -y auditd audispd-plugins

# Configurar las reglas de auditoría (CIS 4.1.2-14)
cat << 'EOF' > /etc/audit/rules.d/99-cis.rules
# CIS Benchmark - Reglas de auditoría

# Borrar reglas existentes al inicio
-D

# Tamaño del buffer del kernel para auditoría
-b 8192

# Acción cuando el log está lleno
-f 1

# Registrar modificaciones a ficheros de sistema de tiempo
-a always,exit -F path=/etc/localtime -F perm=wa -F key=time-change
-w /etc/cron.allow -p wa -k cron
-w /etc/cron.deny -p wa -k cron

# Registrar cambios en la identidad del sistema
-w /etc/group -p wa -k identity
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/sudoers -p wa -k scope
-w /etc/sudoers.d/ -p wa -k scope

# Registrar sesiones de usuario
-w /var/log/wtmp -p wa -k session
-w /var/log/btmp -p wa -k session
-w /var/log/lastlog -p wa -k session

# Registrar intentos de acceso fallidos al sistema de archivos
-a always,exit -F arch=b64 -S open -F dir=/etc -F success=0 -k access
-a always,exit -F arch=b64 -S open -F dir=/bin -F success=0 -k access
-a always,exit -F arch=b64 -S open -F dir=/sbin -F success=0 -k access

# Registrar el uso de comandos privilegiados
-a always,exit -F arch=b64 -S execve -C uid!=euid -F euid=0 -k setuid
-a always,exit -F arch=b64 -S execve -C gid!=egid -F egid=0 -k setgid

# Registrar cambios en la configuración de red
-w /etc/hosts -p wa -k system-locale
-w /etc/network/ -p wa -k system-locale
-w /etc/sysconfig/network -p wa -k system-locale

# Hacer inmutables las reglas (requiere reinicio para cambiarlas)
-e 2
EOF

# Reiniciar auditd para cargar las reglas
systemctl restart auditd

# Verificar las reglas cargadas
auditctl -l

# Buscar eventos de auditoría
ausearch -k identity -ts today | aureport --file -i

Monitorización de Conformidad Continua

# Script de verificación periódica de conformidad CIS
cat << 'EOF' > /usr/local/bin/cis-compliance-check.sh
#!/bin/bash
# Verificación diaria de conformidad con CIS Benchmarks

LOG="/var/log/cis-compliance-$(date +%Y%m%d).log"
ALERTAS=0

echo "=== Verificación CIS - $(date) ===" >> $LOG

# Verificar parámetros de red
echo "--- Verificación de red ---" >> $LOG
PARAMS=("net.ipv4.tcp_syncookies=1" "net.ipv4.conf.all.log_martians=1" \
        "net.ipv4.conf.all.accept_redirects=0" "net.ipv4.ip_forward=0")

for PARAM in "${PARAMS[@]}"; do
    CLAVE=$(echo $PARAM | cut -d= -f1)
    VALOR_ESPERADO=$(echo $PARAM | cut -d= -f2)
    VALOR_ACTUAL=$(sysctl -n $CLAVE 2>/dev/null)
    
    if [ "$VALOR_ACTUAL" != "$VALOR_ESPERADO" ]; then
        echo "FALLO: $CLAVE = $VALOR_ACTUAL (esperado: $VALOR_ESPERADO)" >> $LOG
        ALERTAS=$((ALERTAS + 1))
    fi
done

# Verificar SSH
echo "--- Verificación de SSH ---" >> $LOG
if sshd -T | grep -q "^permitrootlogin yes"; then
    echo "FALLO: PermitRootLogin está habilitado en SSH" >> $LOG
    ALERTAS=$((ALERTAS + 1))
fi

# Verificar auditd
if ! systemctl is-active auditd &>/dev/null; then
    echo "FALLO: auditd no está corriendo" >> $LOG
    ALERTAS=$((ALERTAS + 1))
fi

echo "Total de fallos: $ALERTAS" >> $LOG

if [ "$ALERTAS" -gt 0 ]; then
    mail -s "[CIS] $ALERTAS fallos de conformidad en $(hostname)" \
        [email protected] < $LOG
fi
EOF
chmod +x /usr/local/bin/cis-compliance-check.sh

# Ejecutar diariamente
echo "0 7 * * * root /usr/local/bin/cis-compliance-check.sh" > /etc/cron.d/cis-check

Solución de Problemas

# Servicio que no inicia después del hardening
# Ver los logs del servicio
journalctl -u nombre-servicio -n 50

# El hardening de red rompió la conectividad
# Revertir temporalmente un parámetro
sysctl -w net.ipv4.ip_forward=1

# El SSH rechaza la conexión después del hardening
# Conectar por consola de emergencia (IPMI/KVM) y verificar:
sshd -T | grep -E "permitroot|maxauthtries|protocol"

# Verificar el estado de PAM faillock
faillock --user tu_usuario
# Desbloquear un usuario bloqueado
faillock --user tu_usuario --reset

# Revertir cambios específicos si algo se rompe
# Siempre tener un snapshot o backup antes del hardening
# En caso extremo, revertir el snapshot desde el panel de control del VPS

Conclusión

Los CIS Benchmarks proporcionan un marco sólido y bien documentado para securizar servidores Linux de forma sistemática, cubriendo desde la configuración del kernel hasta las políticas de contraseñas y la auditoría. La clave del éxito es implementar los controles de forma gradual, probando cada cambio en un entorno de staging antes de aplicarlo en producción, y mantener un sistema de verificación continua para asegurar que las configuraciones de seguridad no se degradan con el tiempo. Combinar CIS Benchmarks con herramientas como Lynis, OpenSCAP y auditd crea una postura de seguridad proactiva y auditable.