Tabla de Contenidos
Tener una higiene básica de seguridad es esencial, aunque es un proceso interminable y la seguridad perfecta no existe.
Este tema es muy extenso y está en constante evolución. Por eso decidí dividirlo en múltiples partes. Esta parte cubre únicamente el cifrado completo de disco, el bloqueo de cuentas de usuario y la configuración de PAM para la autenticación de usuarios.

Cifrado Completo de Disco con LUKS
El cifrado de datos en reposo es imprescindible. Si alguien obtiene acceso físico a tu hardware, el cifrado completo de disco es lo único que protege tus datos de ser leídos directamente desde la unidad.
Linux utiliza LUKS (Linux Unified Key Setup) para el cifrado de disco.
¿Qué es LUKS?
LUKS añade una capa de cifrado entre el dispositivo de bloque físico (la representación del disco duro dentro de Linux) y el sistema de archivos (ext4, xfs, btrfs…).
Utiliza el mapeador de dispositivos del kernel para crear un mapeo entre la unidad física cifrada y un volumen lógico descifrado. Cuando estás usando tu computadora, las aplicaciones solo ven un dispositivo descifrado regular en /dev/mapper/. No son conscientes del cifrado.
Cuando cifras una unidad, LUKS añade un encabezado con metadatos sobre el cifrado (cifrador, tamaño de clave, función de derivación de claves) y hasta 32 ranuras de claves en LUKS2. Estas ranuras de claves pueden almacenar frases de contraseña o archivos de claves que desbloquean el mismo volumen cifrado, por lo que pueden ser utilizadas por múltiples usuarios para descifrar la unidad usando sus propias credenciales almacenadas en ranuras separadas.
Ten en cuenta que para acceder a un volumen cifrado con LUKS, necesitas descifrarlo primero. Por lo tanto, los datos solo están cifrados cuando el volumen está cerrado (bloqueado manualmente o cuando apagas la computadora). Mientras estás trabajando con el volumen, los datos están descifrados en memoria.
LUKS1 vs LUKS2
En sistemas modernos LUKS2 es el predeterminado, que proporciona más ranuras de claves y algunas mejoras.
- Hasta 32 ranuras de claves (vs 8 en LUKS1)
- Derivación de claves Argon2 (resistente a ataques basados en GPU)
- Soporte para cifrado autenticado
- Mejor resistencia del encabezado
- Soporte para re-cifrado en línea (cifrar datos existentes sin reformatear)
Funciones de Derivación de Claves
La función de derivación de claves determina cómo tu frase de contraseña se convierte en una clave de cifrado:
- PBKDF2 (predeterminado en LUKS1): Rápido pero vulnerable a ataques de fuerza bruta acelerados por GPU
- Argon2i (predeterminado en LUKS2): Algoritmo con uso intensivo de memoria que resiste ataques de GPU y ataques de tiempo de caché
- Argon2id: Enfoque híbrido con la mejor protección general contra ataques de GPU y ataques de canal lateral
Configuración del Cifrado LUKS
No puedes cifrar una unidad que esté actualmente en uso. Necesitas o una unidad nueva o si usas una existente, respaldar los datos, formatear la unidad, cifrarla y luego restaurar.
La mayoría de las distribuciones de Linux ofrecen configuración de LUKS durante la instalación (generalmente solo haciendo clic en una casilla de verificación). Solo te pedirán que borres la unidad e ingreses una frase de contraseña. Este es el enfoque más fácil.

fuente: imagen encontrada en fedoramagazine
Cifrar una Unidad Después de la Instalación
# Verificar si un dispositivo ya está cifrado con LUKS
cryptsetup isLuks -v /dev/sdb1
# Formatear el dispositivo con cifrado LUKS (se te pedirá una frase de contraseña)
cryptsetup luksFormat /dev/sdb1
# Usar cifrador y tamaño de clave específicos para más control
cryptsetup luksFormat --cipher aes-xts-plain64 --key-size 512 /dev/sdb1
# Especificar función de derivación de claves
cryptsetup luksFormat --type luks2 --pbkdf argon2id --pbkdf-memory 1048576 /dev/sdb1
Crear Volumen LUKS con Encabezado Separado
Almacenar el encabezado LUKS por separado es más seguro. Sin acceso al archivo de encabezado externo, la unidad cifrada permanece inaccesible. Esto es algo extremo, pero puedes almacenar el encabezado en una unidad USB.
# Crear LUKS con encabezado separado
cryptsetup luksFormat /dev/sdb1 --header /root/luks-header.img
# Abrir con encabezado separado
cryptsetup luksOpen /dev/sdb1 encrypted-data --header /root/luks-header.img
Trabajando con LUKS
Ver Versión Actual de LUKS
# Verificar versión de LUKS
cryptsetup luksDump /dev/sdb1 | grep Version
Respaldar Encabezado LUKS
Si el encabezado LUKS se corrompe (sector defectuoso, corrupción del sistema de archivos) tus datos cifrados serán irrecuperables. Respalda tu encabezado LUKS inmediatamente después de cifrar cualquier unidad.
# Respaldar encabezado LUKS (hazlo inmediatamente después del cifrado)
cryptsetup luksHeaderBackup /dev/sdb1 --header-backup-file /root/luks-header-backup.img
# Almacenar respaldo en medios separados (unidad USB, gestor de contraseñas, almacenamiento en la nube)
# NO lo almacenes en la unidad cifrada misma
# Restaurar encabezado corrupto
cryptsetup luksHeaderRestore /dev/sdb1 --header-backup-file /root/luks-header-backup.img
# Verificar integridad del encabezado
cryptsetup luksDump /dev/sdb1
Abrir Volumen LUKS Manualmente
Una vez que la unidad está cifrada, necesitas abrir el volumen LUKS para acceder a su contenido.
# Abrir el volumen LUKS con un nombre de mapeador de dispositivos (crea /dev/mapper/encrypted-data)
cryptsetup luksOpen /dev/sdb1 encrypted-data
# Formatear el volumen descifrado con un sistema de archivos (aquí, xfs)
mkfs.xfs /dev/mapper/encrypted-data
# Montar el volumen como cualquier otro dispositivo
mount /dev/mapper/encrypted-data /mnt/secure
Cerrar Volumen LUKS Manualmente
Cierra el volumen LUKS abierto para restringir el acceso. Esto elimina la entrada del mapeador de dispositivos para asegurar que el contenido ya no sea accesible.
# Desmontar el sistema de archivos primero
umount /mnt/secure
# Cerrar el volumen LUKS
cryptsetup luksClose encrypted-data
# Sintaxis alternativa más corta
cryptsetup close encrypted-data
Trabajando con Ranuras de Claves
Puedes añadir claves a diferentes ranuras de claves para tener múltiples métodos de descifrado (esto es útil para sistemas multiusuario o recuperación).
Yo solo uso la ranura 0 para mi frase de contraseña principal y la ranura 1 para recuperación (guardada en el gestor de contraseñas).
# Ver ranuras de claves actuales y su estado
cryptsetup luksDump /dev/sdb1 | grep "Key Slot"
# Añadir una nueva frase de contraseña a una ranura disponible
cryptsetup luksAddKey /dev/sdb1
# Añadir un archivo de claves en lugar de una frase de contraseña
cryptsetup luksAddKey /dev/sdb1 /path/to/keyfile
# Añadir a un número de ranura específico
cryptsetup luksAddKey --key-slot 2 /dev/sdb1
# Cambiar una frase de contraseña existente
cryptsetup luksChangeKey /dev/sdb1
# Eliminar una ranura de claves
cryptsetup luksKillSlot /dev/sdb1 1
Montaje Automático con Archivos de Claves
Añade archivos de claves para montar automáticamente la unidad al arrancar (esto se configura automáticamente si añades cifrado LUKS en la instalación).
Crear archivo de claves.
# Generar un archivo de claves aleatorio de 4096 bytes
dd if=/dev/urandom of=/root/luks-keyfile bs=4096 count=1
# Restringir permisos (crítico—prevenir acceso no autorizado)
chmod 400 /root/luks-keyfile
# Añadirlo al volumen LUKS
cryptsetup luksAddKey /dev/sdb1 /root/luks-keyfile
Configurar descifrado automático en /etc/crypttab.
# Sintaxis: nombre dispositivo archivo_claves opciones
encrypted-data /dev/sdb1 /root/luks-keyfile luks
Añadir la entrada de montaje automático en /etc/fstab.
# Usar el nombre del mapeador de dispositivos en /etc/fstab
/dev/mapper/encrypted-data /mnt/secure xfs defaults 0 0
El volumen LUKS ahora se descifra y monta automáticamente al arrancar. Los datos permanecen cifrados cuando el sistema está apagado o durante las etapas previas al arranque.
Swap Cifrado
Si estás usando espacio swap, también debes cifrarlo. De lo contrario, los datos sensibles que se paginan al swap durante tu sesión permanecen allí sin cifrar en el disco.
# Clave aleatoria para swap (regenerada en cada arranque)
# Añadir a /etc/crypttab
swap /dev/sda2 /dev/urandom swap,cipher=aes-xts-plain64,size=512
# En /etc/fstab
/dev/mapper/swap none swap defaults 0 0
Seguridad de Cuentas de Usuario
Deshabilitar el Login de Root
Ejecutar como root no es una buena idea. Deshabilita la cuenta root y solo usa un usuario regular con privilegios sudo en su lugar.
Esto previene que cualquiera inicie sesión como root, ya sea en la consola o vía SSH. Aún puedes obtener privilegios root a través de sudo o usando sudo -i para un shell root interactivo.
# Bloquear la cuenta root
passwd -l root
# Denegar login de root vía SSH /etc/ssh/sshd_config
vim /etc/ssh/sshd_config
PermitRootLogin no
Tiempos de Espera de Sesión
Cerrar sesión automáticamente de usuarios inactivos en /etc/profile.
# Añadir a /etc/profile
TMOUT=900 # Cerrar sesión automáticamente después de 15 minutos de inactividad
readonly TMOUT
export TMOUT
Historial de Contraseñas
Prevenir que los usuarios ciclen y reutilicen contraseñas recientes. La mayoría de las distribuciones recuerdan las últimas 10 contraseñas por defecto, así que puedes aumentar este número para prevenir que los usuarios reutilicen contraseñas antiguas. Un poco extremo para mí pero bueno saberlo.
Cambiar la configuración en /etc/security/pwhistory.conf.
# Aumentar a 24 (común en entornos Linux empresariales)
remember = 24
enforce_for_root
Restringir Permisos de Directorio Home
Los permisos predeterminados del directorio home en algunas distribuciones son demasiado permisivos, ya que los usuarios “otros” a menudo pueden leer archivos en tu directorio home.
Cambiar permisos existentes del directorio home.
# Eliminar acceso de lectura para otros
chmod o-r $HOME
# Más explícitamente, establecer acceso solo para el propietario
chmod 700 $HOME
Establecer valores predeterminados restrictivos para nuevos usuarios en /etc/login.defs.
# Establecer umask restrictivo para nuevos archivos
UMASK 077
# Establecer permisos del directorio home solo para el propietario
HOME_MODE 0700
Establecer umask restrictivo para nuevos archivos de usuarios existentes en ~/.bashrc (o mejor, en el directorio drop-in ~/.bashrc.d/).
# Establecer umask para nuevos archivos creados por este usuario
umask 027
# O más restrictivo (acceso solo para el propietario)
umask 077
Configurar Acceso Sudo
sudo permite a usuarios configurados ejecutar comandos con privilegios elevados o como otro usuario sin conocer la contraseña del usuario objetivo. Asegúrate de que esto esté configurado correctamente.
Editar /etc/sudoers con visudo, que valida la sintaxis antes de guardar.
# Editar /etc/sudoers
visudo
# Mejor: crear un archivo de configuración personalizado en el directorio drop-in de sudoers
visudo -f /etc/sudoers.d/custom
Algunas buenas configuraciones de seguridad para sudo:
# Requerir contraseña para cada comando sudo
Defaults timestamp_timeout=0
# O establecer un tiempo de espera de 5 minutos para volver a pedir la contraseña al usuario si es muy molesto
Defaults timestamp_timeout=5
# Usar alias de sudo
# Sintaxis: User_Alias NOMBRE = usuario1, usuario2, %grupo1, ...
User_Alias ADMINS = alice, bob, %sysadmin
# Sintaxis: Host_Alias NOMBRE = host1, host2, ...
Host_Alias PRODUCTION = prod-web01, prod-db01, 10.0.1.0/24
# Sintaxis: Cmnd_Alias NOMBRE = /ruta/al/comando1, /ruta/al/comando2, ...
# ¡Muy importante! Cuando los comandos se listan con argumentos específicos, solo se permiten esas combinaciones exactas de argumentos. Además, no uses comodines ya que por ejemplo, un comando como `/usr/bin/systemctl * sshd` permite `systemctl stop sshd`, `systemctl restart sshd`, etc. ¡Peligroso!
Cmnd_Alias SERVICES = /usr/bin/systemctl, /usr/sbin/service
Cmnd_Alias SOFTWARE = /usr/bin/dnf, /usr/bin/yum, /usr/bin/rpm
# Todo junto, regla sudo usando alias
ADMINS PRODUCTION=(ALL) SOFTWARE, SERVICES
Verificar los privilegios sudo de tu usuario.
# Listar tus propios privilegios sudo
sudo -l
Política de Antigüedad de Contraseñas
Establecer antigüedad de contraseñas para nuevos usuarios en /etc/login.defs.
# Antigüedad máxima de contraseña en días
PASS_MAX_DAYS 90
# Días mínimos entre cambios de contraseña (previene el ciclo inmediato de vuelta a contraseñas antiguas)
PASS_MIN_DAYS 1
# Días antes de la expiración para advertir al usuario
PASS_WARN_AGE 7
# Longitud mínima de contraseña (configuración heredada, usar pwquality en su lugar)
PASS_MIN_LEN 8
Configurar antigüedad de contraseñas para usuarios existentes:
# Ver configuración actual de antigüedad de contraseñas
chage -l username
# Establecer que la contraseña expire en 90 días
chage -M 90 username
# Establecer días mínimos entre cambios de contraseña
chage -m 7 username
# Forzar cambio de contraseña en el próximo login
chage -d 0 username
# Establecer fecha de expiración de cuenta
chage -E 2025-12-31 username
# Modo de configuración interactivo
chage username
Entendiendo PAM
Entender (al menos a alto nivel) PAM es necesario.
PAM es un marco de autenticación centralizado que muchas aplicaciones usan para verificar credenciales de usuario. Sin PAM, cada aplicación implementaría su propia lógica de autenticación.
El proceso de autenticación PAM funciona así:
- La aplicación solicita autenticación a través de la API de PAM
- PAM lee la configuración de
/etc/pam.d/para ese servicio específico - PAM carga y ejecuta los módulos configurados en orden
- Cada módulo realiza su verificación de autenticación específica
- PAM combina los resultados y le dice a la aplicación éxito o fallo
Los módulos PAM se dividen en cuatro tipos:
- auth - Verificar credenciales (contraseñas, tokens, biometría, YubiKeys)
- account - Verificar estado de cuenta (expiración, horarios de acceso, bloqueos)
- password - Manejar cambios de contraseña y aplicar reglas de complejidad
- session - Configurar y desmantelar sesiones de usuario (montar directorios home, establecer límites)
Las banderas de control PAM determinan qué sucede cuando un módulo tiene éxito o falla:
- requisite - Debe tener éxito o la autenticación falla inmediatamente, no se verifican más módulos
- sufficient - Si esto tiene éxito, se omiten los módulos restantes de este tipo
- required - Debe tener éxito, pero PAM continúa verificando otros módulos independientemente
- optional - El resultado del módulo solo importa si es el único módulo en la pila
- include - Incluir todas las líneas del tipo dado desde otro archivo de configuración
Aplicar Complejidad de Contraseñas
Complejidad de Contraseñas con pwquality
El módulo PAM pam_pwquality aplica requisitos de complejidad de contraseñas a través de PAM. Utiliza un sistema de “créditos” para definir la fortaleza de la contraseña (tendrás que especificar el número requerido de dígitos, letras mayúsculas, letras minúsculas y caracteres especiales).
Cómo funciona es algo confuso pero, por ejemplo, para minlen = 12 y estableces dcredit = 1, una contraseña con un dígito obtiene 1 crédito hacia la longitud mínima, por lo que necesita 11 caracteres regulares más el dígito. Pero si ucredit = -1, la mayúscula es requerida pero no reduce el requisito de longitud, aún necesitas 12 caracteres en total incluyendo la mayúscula.
Configurarlo en /etc/security/pwquality.conf.
# Aclaración del sistema de créditos:
# Valor positivo (dcredit = 1): "Si la contraseña tiene 1+ dígitos, reducir minlen en 1"
# Valor negativo (ucredit = -1): "La contraseña DEBE tener 1+ mayúscula, sin crédito de longitud"
# Ejemplo con minlen = 12:
# dcredit = 1 → Contraseña con dígito puede ser de 11 caracteres en total
# ucredit = -1 → Contraseña debe tener mayúscula Y aún ser de 12 caracteres
dcredit = -1 # Requerir al menos 1 dígito
ucredit = -1 # Requerir al menos 1 mayúscula
lcredit = -1 # Requerir al menos 1 minúscula
ocredit = -1 # Requerir al menos 1 carácter especial
# Longitud mínima de contraseña (considerando créditos)
minlen = 12
# Máximo de caracteres idénticos consecutivos
maxrepeat = 2
# Máximo de caracteres consecutivos de la misma clase de caracteres
maxclassrepeat = 3
# Número de intentos de entrada de contraseña antes de rendirse
retry = 3
# Mínimo de caracteres diferentes de la contraseña antigua
difok = 5
# Verificar contra palabras del diccionario
dictcheck = 1
# Rechazar contraseñas que contengan el nombre de usuario
usercheck = 1
# Aplicar reglas para usuario root (0=sí, 1=no)
enforce_for_root = 0
Integrar pwquality con PAM
Asegurar que PAM use el módulo pwquality verificando /etc/pam.d/passwd y /etc/pam.d/system-auth.
# En /etc/pam.d/passwd
password requisite pam_pwquality.so retry=3
password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok
password required pam_deny.so
# En /etc/pam.d/system-auth
password requisite pam_pwquality.so try_first_pass local_users_only retry=3
password sufficient pam_unix.so sha512 shadow try_first_pass use_authtok
password required pam_deny.so
Prevenir Ataques de Fuerza Bruta
El módulo PAM pam_faillock protege contra ataques de contraseña de fuerza bruta bloqueando cuentas después de intentos de autenticación fallidos consecutivos. Esto es importante para cualquier sistema, incluso si no está expuesto a la red. Ten en cuenta que esto solo protege para logins basados en PAM (por ejemplo, no aplica para modo de recuperación).
Configurar el comportamiento de faillock en /etc/security/faillock.conf.
# Directorio para registros de intentos fallidos
dir = /var/run/faillock
# Número de intentos fallidos antes del bloqueo
deny = 4
# Duración del bloqueo en segundos (1200 = 20 minutos)
unlock_time = 1200
# Aplicar bloqueo a la cuenta root
even_deny_root
# Duración del bloqueo específica para root (si even_deny_root está establecido)
root_unlock_time = 600
# Habilitar registro de auditoría
audit
# Bloquear cuentas si faillock no puede escribir en el directorio de registro
silent
Probar la configuración.
# Intentar iniciar sesión con contraseña incorrecta múltiples veces
ssh username@localhost
# Verificar si la cuenta está bloqueada
faillock --user username
# Verificar que aún puedes desbloquear
sudo faillock --user username --reset
Habilitar Faillock con Authselect
En RHEL y Fedora, usa perfiles de authselect en lugar de editar manualmente archivos PAM. Esto previene conflictos de configuración y asegura consistencia entre archivos de servicio PAM.
# Mostrar perfil authselect actual
authselect current
# Listar perfiles disponibles
authselect list
# Listar características de un perfil
authselect list-features sssd
# Habilitar característica faillock
authselect enable-feature with-faillock
# Aplicar cambios
authselect apply-changes
Authselect modifica /etc/pam.d/system-auth y /etc/pam.d/password-auth para incluir verificaciones faillock. La configuración se ve así.
# Sección Auth - verificar bloqueo antes de la autenticación
auth required pam_faillock.so preauth silent
auth sufficient pam_unix.so nullok try_first_pass
auth [default=die] pam_faillock.so authfail
auth required pam_deny.so
# Sección Account - aplicar bloqueo
account required pam_faillock.so
account required pam_unix.so
Ver Intentos de Login Fallidos
# Mostrar todos los intentos fallidos en todo el sistema
faillock
# Mostrar intentos fallidos para usuario específico
faillock --user username
# Información más detallada
faillock --user username --verbose
Login con YubiKey
He añadido reglas PAM para iniciar sesión vía YubiKey para más seguridad.
Más detalles aquí: Using YubiKey for Local Linux Authentication
¿Qué Sigue?
Al final, el endurecimiento de seguridad y la privacidad no son perfectos. Hay medidas extremas que te hacen muy seguro, pero hacen que usar el sistema sea doloroso. Este es un buen equilibrio entre usabilidad y seguridad.
Las próximas partes cubrirán SSH, redes, kernel, LSM (específicamente SELinux), systemd, configuración de firewall…