1. Fundamentos y arquitectura de PAM
Los módulos de autenticación conectables o PAM (Pluggable Authentication Modules) son el mecanismo con el que GNU/Linux desacopla las aplicaciones que necesitan autenticar a un usuario, como login, sshd, sudo, su o passwd, de los métodos concretos con los que se realiza esa autenticación.
Sin PAM, cada aplicación tendría que implementar por su cuenta la lectura de /etc/shadow, la comprobación de la caducidad de la cuenta, el bloqueo tras intentos fallidos o la verificación de un segundo factor. Con PAM, la aplicación delega estas decisiones en una biblioteca común, libpam, que lee la política definida por el administrador y ejecuta los módulos indicados en ella. La implementación utilizada en las distribuciones actuales es Linux-PAM.
Este diseño tiene consecuencias directas para el bastionado:
-
Centralización: una política, como el bloqueo tras intentos fallidos, se aplica a todos los servicios que comparten la misma configuración.
-
Independencia de la aplicación: se puede añadir un segundo factor a
sshdo asudosin modificar ni recompilar estos programas. -
Riesgo concentrado: un error en un archivo de PAM puede impedir el acceso de todos los usuarios, incluido el administrador, o, peor aún, permitir el acceso sin contraseña. Cualquier cambio debe probarse antes de cerrar la sesión con privilegios.
|
PAM frente a NSS PAM decide si un usuario puede autenticarse y abrir una sesión. La resolución de quién es el usuario, es decir, su UID, su grupo o su directorio personal, corresponde al Name Service Switch (NSS), estudiado en el bloque de contenidos sobre gestión de usuarios y grupos. Ambos colaboran, |
|
En entornos empresariales: SSSD En redes corporativas rara vez se usan cuentas puramente locales. Lo habitual es delegar la autenticación en un directorio LDAP o Active Directory a través del demonio SSSD, que aporta a la vez el módulo de PAM |
1.1. Flujo de una autenticación
Conviene ver primero, a grandes rasgos, qué ocurre cuando una aplicación autentica a un usuario a través de PAM. El proceso, que resume la figura, sigue estos pasos:
-
La aplicación inicia una transacción, el diálogo con PAM que dura toda la autenticación, llamando a
pam_start()con el nombre del servicio, por ejemplosshd. -
libpamlee el archivo de configuración de ese servicio,/etc/pam.d/sshd. Si no existe, recurre a/etc/pam.d/other, la configuración por defecto para los servicios que no tienen un archivo propio. -
Cuando la aplicación solicita una operación, como
pam_authenticate(),libpamejecuta en orden la pila de módulos que corresponde, es decir, la lista ordenada de módulos de ese tipo. Los tipos de gestión y las pilas se explican en la sección 2. -
Cada módulo devuelve un código de resultado, de éxito o de error, y el campo de control de su regla decide cómo influye ese resultado en el resultado global, como se detalla en la sección 4.
-
La aplicación recibe un único resultado, éxito o error, y actúa en consecuencia.
Los módulos se comunican con el usuario a través de una función de conversación que proporciona la aplicación. Por eso un mismo módulo puede pedir una contraseña en una terminal, en una ventana gráfica o en el intercambio keyboard-interactive de SSH.
2. Tipos de gestión y orden de ejecución
En la sección 1.1 se vio que libpam ejecuta «la pila del tipo correspondiente». Ese tipo de gestión indica en qué fase del acceso interviene cada módulo, ya sea comprobar las credenciales, decidir si la cuenta puede usarse en ese momento, cambiar la contraseña o preparar y cerrar la sesión. Separar el acceso en fases es lo que permite que un mismo módulo, como pam_unix, participe en varias de ellas con cometidos distintos, y que el administrador combine los módulos de forma ordenada dentro de cada una.
PAM organiza las reglas en cuatro tipos de gestión, cada uno asociado a una función de la API que invoca la aplicación:
| Tipo | Función de la API | Pregunta que responde | Módulos habituales |
|---|---|---|---|
|
|
¿El usuario es quien dice ser? |
|
|
|
¿Puede usar la cuenta ahora, desde aquí? |
|
|
|
¿La nueva credencial cumple la política? |
|
|
|
¿Qué hay que preparar al abrir y cerrar la sesión? |
|
Cada tipo tiene su propia pila, que se evalúa de forma independiente cuando la aplicación invoca la función correspondiente.
2.1. Ejemplo: inicio de sesión de maria en una consola
Los cuatro tipos se entienden mejor siguiéndolos sobre un caso concreto. Cuando maria inicia sesión en una consola de texto, desde que teclea su nombre de usuario hasta que obtiene el prompt del intérprete de comandos, PAM recorre las cuatro pilas en el orden en que la aplicación de login va invocando sus funciones:
-
auth:pam_nologincomprueba que el sistema no está en mantenimiento ypam_unixsolicita y verifica la contraseña demaria. -
account:pam_unixcomprueba en/etc/shadowque la cuenta no ha expirado. Si la contraseña ha caducado, devuelvePAM_NEW_AUTHTOK_REQDy la aplicación obliga a cambiarla. -
password: solo se ejecuta si hay que cambiar la contraseña,pam_pwqualityvalida su robustez ypam_unixalmacena el nuevo hash. -
session:pam_loginuidfija el identificador de auditoría,pam_limitsaplica los límites de recursos,pam_umaskfija la máscara ypam_systemdregistra la sesión ensystemd-logind.
|
La autenticación por clave pública de SSH no ejecuta la pila Cuando un usuario accede a |
3. Archivos de configuración
La política que libpam ejecuta no reside en el código de cada aplicación, sino en un conjunto de archivos de configuración que el administrador lee y modifica. Son, en la práctica, el objeto sobre el que se trabaja al bastionar PAM: casi todas las medidas de las secciones siguientes consisten en añadir o ajustar reglas en estos archivos. Por eso conviene conocer primero dónde residen, cómo se escribe cada regla y cómo se gestionan de forma automatizada en Debian y Ubuntu, que es lo que se describe en los tres apartados siguientes.
3.1. Ubicación
La configuración de PAM no está en un único lugar, sino repartida entre el directorio de los servicios, los archivos de configuración de cada módulo y las propias bibliotecas de los módulos. Conviene saber qué contiene cada ubicación:
-
/etc/pam.d/: contiene un archivo por servicio, con el mismo nombre que el que la aplicación pasa apam_start():sshd,login,sudo,su,passwd,cron… Es el formato utilizado por todas las distribuciones actuales. -
/etc/pam.conf: formato histórico en un único archivo, con el nombre del servicio como primer campo de cada línea. Solo se consulta si/etc/pam.d/no existe. -
/etc/pam.d/other: configuración que se aplica a cualquier servicio sin archivo propio. -
/etc/security/: archivos de configuración de los propios módulos, comofaillock.conf,pwquality.conf,access.conf,limits.confotime.conf.
|
El servicio En Debian y Ubuntu, |
Los archivos de /etc/pam.d/ deben pertenecer a root:root con permisos 644. Un usuario capaz de escribir en ellos puede añadir pam_permit.so a la pila auth y acceder como cualquier usuario sin contraseña, una técnica de persistencia catalogada en MITRE ATT&CK como Modify Authentication Process: Pluggable Authentication Modules (T1556.003).
3.2. Sintaxis de una regla
Cada línea no comentada de un archivo de /etc/pam.d/ es una regla, que hace que un módulo participe en una de las pilas. Una regla se compone de cuatro campos separados por espacios, que se leen de izquierda a derecha: el tipo de gestión, el control que determina cómo influye su resultado, el módulo que se ejecuta y, de forma opcional, los argumentos que lo configuran. El orden en que se escriben las reglas de un mismo tipo es el orden en que libpam las ejecuta.
tipo control módulo argumentos
auth [success=1 default=ignore] pam_unix.so nullok
| Campo | Descripción | Ejemplo | Explicación técnica |
|---|---|---|---|
Tipo |
Pila a la que pertenece la regla |
|
Un guion inicial, como |
Control |
Cómo influye el resultado del módulo |
|
Palabra clave o lista |
Módulo |
Nombre o ruta del módulo |
|
Sin ruta, se busca en el directorio de módulos del sistema. |
Argumentos |
Opciones del módulo |
|
Cada módulo define las suyas. Las opciones |
Además de reglas, un archivo puede incorporar otros:
-
@include archivo: inserta literalmente todas las reglas del archivo indicado. Es el mecanismo que usan Debian y Ubuntu. -
includeen el campo de control, como enauth include system-auth: incluye solo las reglas del tipo indicado. Es habitual en la familia Red Hat. -
substack: comoinclude, pero las accionesdoneydiedel archivo incluido solo terminan la subpila y no la pila completa.
3.3. Los archivos common-* y pam-auth-update
En Debian y Ubuntu, casi todos los servicios incluyen cuatro archivos compartidos: common-auth, common-account, common-password y common-session. Estos archivos no deben editarse a mano, porque los genera la herramienta pam-auth-update a partir de los perfiles que instalan los paquetes en /usr/share/pam-configs/. Cuando se instala o actualiza un paquete con un perfil PAM, como libpam-pwquality, libpam-sss o libpam-modules, pam-auth-update regenera los archivos y descarta los cambios manuales realizados.
La forma correcta de añadir un módulo a las pilas comunes es crear un perfil propio en /usr/share/pam-configs/. Un perfil es un archivo de texto que indica qué reglas añadir y a qué pilas, y que pam-auth-update integra en los archivos common-* al activarlo. Por ejemplo, este perfil añade pam_faillock a las pilas auth y account:
Name: Descripción que aparece en el menú de pam-auth-update (1)
Default: yes (2)
Priority: 1024 (3)
Auth-Type: Primary
Auth: (4)
requisite pam_faillock.so preauth
Account-Type: Primary
Account: (5)
required pam_faillock.so
| 1 | Texto descriptivo del perfil, que aparece en el menú interactivo de pam-auth-update. |
| 2 | Con yes, el perfil se activa de serie al instalarlo. |
| 3 | Posición del perfil en la pila, donde los de mayor prioridad se colocan primero. |
| 4 | Reglas que se insertarán en la pila common-auth. El Auth-Type: Primary de la línea anterior marca el módulo como método de autenticación principal. |
| 5 | Reglas que se insertarán en la pila common-account. Un perfil puede incluir además bloques Password: y Session:. |
Una vez guardado el perfil en /usr/share/pam-configs/, se activa o se desactiva con pam-auth-update, que regenera los archivos common-* incorporando o retirando sus reglas:
sudo pam-auth-update --enable nombre_del_perfil # Activa un perfil
sudo pam-auth-update --disable nombre_del_perfil # Lo desactiva
sudo pam-auth-update # Menú interactivo
|
Con los conceptos explicados hasta aquí, ya puede realizar el Ejercicio 1. Exploración de la configuración de PAM. |
4. El campo de control
El campo de control es el segundo campo de cada regla, visto en la sección 3.2, y, junto con el orden, es lo que define la lógica de seguridad de una pila, ya que decide cómo influye el resultado de cada módulo en el resultado global y si la evaluación continúa o se detiene. Entenderlo es imprescindible para el bastionado, porque un control mal elegido puede tanto bloquear a los usuarios legítimos como dejar entrar a quien no debería. PAM admite dos formas de expresarlo, que se describen en los apartados siguientes. La primera son cuatro palabras clave simples, que cubren la mayoría de los casos. La segunda es una sintaxis avanzada [valor=acción], más expresiva.
4.1. Palabras clave simples
Las cuatro palabras clave simples son la forma más habitual y legible de escribir el control. Cada una resume un comportamiento distinto ante el éxito o el fallo del módulo:
| Control | Si el módulo tiene éxito | Si el módulo falla |
|---|---|---|
|
Continúa con la pila |
Continúa, pero el resultado global será un error |
|
Continúa con la pila |
Termina la pila inmediatamente y devuelve el error |
|
Termina la pila con éxito, si no ha fallado antes ningún |
Continúa. El fallo se ignora |
|
Continúa. Solo influye si es el único módulo de la pila |
Continúa. Solo influye si es el único módulo de la pila |
required continúa ejecutando la pila tras un fallo para no revelar al atacante en qué paso ha fallado la autenticación. requisite detiene la pila de inmediato, lo que es útil cuando continuar no tiene sentido o es peligroso, por ejemplo para no pedir la contraseña de una cuenta ya bloqueada.
4.1.1. Recorrido de una pila paso a paso
Para ver cómo se combinan el orden y el control, considere esta pila account de ejemplo, que libpam recorre de arriba abajo cuando la aplicación llama a pam_acct_mgmt():
account required pam_nologin.so (1)
account requisite pam_time.so (2)
account required pam_unix.so (3)
| 1 | Deniega el acceso a los usuarios normales si existe el archivo /etc/nologin. |
| 2 | Comprueba si la hora actual está dentro del horario permitido en /etc/security/time.conf. |
| 3 | Verifica que la cuenta no esté caducada ni expirada. |
El resultado depende de en qué módulo se produzca el fallo:
-
Todo correcto: se ejecutan
pam_nologin,pam_timeypam_unix, los tres con éxito. Al llegar al final de la pila sin ningún fallo, el resultado global es éxito y la cuenta se acepta. -
Fuera de horario:
pam_nologintiene éxito, peropam_timefalla. Como esrequisite, la pila se detiene en el acto y devuelve error, ypam_unixni siquiera llega a ejecutarse. Tiene sentido, porque si el usuario no puede entrar a esa hora, comprobar la caducidad de la cuenta es irrelevante. -
Cuenta caducada:
pam_nologinypam_timetienen éxito, peropam_unixfalla. Como esrequired, la pila no se corta: se termina de recorrer, pero el resultado global queda marcado como error. Si hubiera más módulos a continuación, se ejecutarían igualmente, para no revelar en qué punto concreto se rechazó el acceso.
El recorrido ilustra la regla general. PAM ejecuta los módulos en el orden escrito, y la palabra de control de cada uno decide si su fallo detiene la pila (requisite), la marca sin detenerla (required) o la termina antes de tiempo con éxito (sufficient).
4.2. Sintaxis avanzada [valor=acción]
Las palabras clave simples son abreviaturas de una sintaxis más expresiva, en la que se asocia una acción a cada código de resultado del módulo, como success, auth_err, user_unknown, new_authtok_reqd o default para cualquier otro:
| Acción | Efecto |
|---|---|
|
El resultado del módulo no influye en el resultado global |
|
El resultado del módulo se tiene en cuenta. Si es un fallo, el resultado global será un fallo |
|
Se marca el resultado global como fallo y se continúa |
|
Se marca el resultado global como fallo y se termina la pila |
|
Se marca el resultado global como éxito, si no había fallos previos, y se termina la pila |
|
Se olvida el estado acumulado y se continúa |
|
Se saltan las |
Las equivalencias con las palabras clave simples son las siguientes:
| Palabra clave | Equivalente |
|---|---|
|
|
|
|
|
|
|
|
4.3. Análisis de common-auth en Ubuntu 24.04
auth [success=1 default=ignore] pam_unix.so nullok (1)
auth requisite pam_deny.so (2)
auth required pam_permit.so (3)
| 1 | Si la contraseña es correcta, se salta la siguiente regla. Si falla, el resultado se ignora y se continúa con la regla siguiente. |
| 2 | Solo se alcanza si pam_unix ha fallado. pam_deny siempre falla y, al ser requisite, termina la pila con error. |
| 3 | Solo se alcanza si pam_unix ha tenido éxito. Como el resultado de pam_unix se descartó con ignore, hace falta un módulo que fije explícitamente un resultado positivo, y pam_permit siempre tiene éxito. |
Este patrón de salto, denegación y permiso se repite en las cuatro pilas comunes y permite que pam-auth-update inserte módulos alternativos, como LDAP o Kerberos, cada uno con un salto distinto hacia pam_permit.
|
El argumento
|
|
Con los conceptos explicados en esta sección, ya puede realizar el Ejercicio 2. Un servicio PAM propio y el campo de control y el Ejercicio 3. Autenticación PAM desde una aplicación Python. |
5. Módulos más utilizados
Hasta aquí se ha visto cómo PAM organiza y evalúa las reglas. Lo que cada regla ejecuta es un módulo, el archivo .so que realiza el trabajo. El sistema trae decenas de ellos, pero en el bastionado de un servidor se maneja habitualmente un grupo reducido. Esta sección los recoge en dos tablas, la de los módulos de uso general y la de los orientados al bastionado, indicando para cada uno su tipo de pila, su función y dónde se configura.
5.1. Módulos de autenticación y gestión general
Los módulos de esta tabla están presentes en casi cualquier configuración y se encargan de la autenticación básica y de la preparación de la sesión. La mayoría los instala el sistema de serie y actúan sin que el administrador tenga que intervenir.
| Módulo | Tipos | Función | Configuración |
|---|---|---|---|
|
Todos |
Autenticación con |
Argumentos en las pilas |
|
Todos |
Siempre falla y cierra las pilas |
Ninguna |
|
Todos |
Siempre tiene éxito y fija un resultado positivo tras un salto. Usado fuera de ese patrón, concede acceso sin autenticar |
Ninguna |
|
|
Tiene éxito si quien invoca es |
|
|
|
Deniega el acceso a los usuarios distintos de |
Archivo |
|
Todos |
Tiene éxito o falla según atributos de la cuenta, como UID o grupo |
Argumentos de la regla |
|
|
Define variables de entorno |
|
|
|
Fija la máscara de creación de archivos |
|
|
|
Aplica límites de recursos por usuario o grupo |
|
|
|
Muestra el mensaje del día |
|
|
|
Fija el UID de auditoría de la sesión, que se conserva aunque el usuario cambie de identidad con |
Ninguna |
|
|
Registra la sesión en |
Ninguna |
|
|
Crea un nuevo anillo de claves del núcleo para la sesión |
Ninguna |
|
No elimine Es el módulo que registra la sesión en |
5.2. Módulos de bastionado
Los módulos de esta tabla son los que se añaden o se ajustan de forma deliberada para endurecer el acceso. Constituyen el núcleo de la configuración de PAM orientada al bastionado y se desarrollan en las secciones siguientes y en los ejercicios.
| Módulo | Tipos | Función | Configuración |
|---|---|---|---|
|
|
Bloquea cuentas tras varios intentos fallidos |
|
|
|
Exige robustez a las nuevas contraseñas |
|
|
|
Impide reutilizar contraseñas anteriores |
Argumentos o |
|
|
Restringe |
|
|
|
Permite o deniega el acceso según usuario, grupo, terminal u origen |
|
|
|
Restringe el acceso por franja horaria |
|
|
|
Fija el retardo tras un intento fallido |
Argumento |
|
|
Segundo factor mediante códigos TOTP |
|
|
|
Registra en el subsistema de auditoría lo que el usuario teclea |
Requiere |
|
|
Crea el directorio personal en el primer acceso, útil con LDAP |
Perfil |
|
Módulos obsoletos que aún aparecen en documentación antigua
|
5.3. Ejemplos de configuración
Los módulos de bastionado de la sección anterior se configuran siguiendo siempre el mismo patrón, que consiste en activar el módulo en el archivo del servicio de /etc/pam.d/ y ajustar su comportamiento en el archivo correspondiente de /etc/security/. Los tres ejemplos siguientes ilustran ese patrón con casos habituales de bastionado, el cierre temporal del acceso, la restricción por origen y los límites de recursos, que se retoman en los ejercicios.
5.3.1. Mantenimiento con nologin
Durante una tarea de mantenimiento conviene impedir que los usuarios entren mientras dura la intervención, sin cerrar el acceso del administrador. El módulo pam_nologin resuelve ese caso con solo crear o borrar un archivo.
echo "Sistema en mantenimiento hasta las 22:00." | sudo tee /etc/nologin > /dev/null
sudo rm /etc/nologin
Mientras el archivo existe, pam_nologin deniega el acceso a cualquier usuario distinto de root y le muestra su contenido. systemd crea automáticamente /run/nologin durante el apagado del sistema para impedir nuevos accesos.
5.3.2. Control de acceso por origen con pam_access
Para que solo los miembros del grupo admins puedan acceder por SSH, y únicamente desde la red de administración, se activa el módulo en /etc/pam.d/sshd:
account required pam_access.so
Y se definen las reglas en /etc/security/access.conf. Cada regla tiene tres campos separados por el carácter :. El primero es el permiso, donde + concede el acceso y - lo deniega. El segundo indica a quién se aplica, con los nombres de grupo entre paréntesis para distinguirlos de los de usuario. El tercero indica el origen, que puede ser una red en formato CIDR, la palabra LOCAL para las sesiones iniciadas en la propia máquina o ALL para cualquier origen.
+:(admins):192.168.10.0/24 (1)
+:root:LOCAL (2)
-:ALL:ALL (3)
| 1 | Permite el acceso a los miembros del grupo admins desde la red 192.168.10.0/24. |
| 2 | Permite el acceso a root solo desde una sesión local, nunca remota. |
| 3 | Deniega el acceso a cualquier otro usuario u origen y actúa como regla de cierre. |
Las reglas se evalúan en orden hasta la primera coincidencia, de modo que el orden importa y la regla de denegación general debe figurar siempre la última, porque cualquier regla escrita después de ella no llegaría a evaluarse.
5.3.3. Límites de recursos con pam_limits
El CIS Benchmark exige impedir los volcados de memoria, que pueden contener contraseñas o claves en claro, mediante un archivo en /etc/security/limits.d/:
* hard core 0
La línea tiene cuatro campos. El primero, *, es el dominio al que se aplica el límite, en este caso todos los usuarios. El segundo, hard, es el tipo de límite, un límite rígido que impone el núcleo y que el usuario no puede superar, frente a soft, que el usuario sí puede elevar hasta el valor rígido. El tercero, core, es el recurso limitado, el tamaño de los archivos de volcado de memoria. El cuarto, 0, es el valor, que al ser cero desactiva por completo esos volcados.
Del mismo modo pueden limitarse el número máximo de procesos por usuario, con nproc, para mitigar las «bombas fork», o el número de sesiones simultáneas, con maxlogins.
|
Con los conceptos explicados en esta sección, ya puede realizar el Ejercicio 4. Mantenimiento y restricción de accesos. |
6. Bastionado de la autenticación con PAM
6.1. Bloqueo por intentos fallidos con pam_faillock
pam_faillock mitiga los ataques de fuerza bruta y de diccionario contra contraseñas, recogidos en MITRE ATT&CK como Brute Force (T1110). Registra los fallos de cada usuario y bloquea la cuenta durante un tiempo cuando se alcanza un umbral.
Para conseguirlo, el módulo no se coloca en un único lugar, sino que tiene que aparecer en tres puntos de la configuración de PAM, cada uno con un cometido distinto. El primero, antes de pedir la contraseña, rechaza el acceso si la cuenta ya está bloqueada. El segundo, después de comprobar la contraseña, anota el intento como fallido si era incorrecta. El tercero, cuando el acceso ha sido correcto, pone a cero el contador de fallos. Los dos primeros se añaden a la pila auth y el tercero a la pila account.
El bloque siguiente es un ejemplo ilustrativo de cómo quedan esas dos pilas, es decir, los archivos /etc/pam.d/common-auth (las cinco primeras líneas) y /etc/pam.d/common-account (la última), una vez activado el módulo. No es un archivo que se escriba a mano. En Debian y Ubuntu lo genera pam-auth-update a partir de un perfil, como se explica al final de este apartado. Se reproduce aquí solo para ver qué hace cada línea:
auth requisite pam_faillock.so preauth (1)
auth [success=2 default=ignore] pam_unix.so (2)
auth [default=die] pam_faillock.so authfail (3)
auth requisite pam_deny.so
auth required pam_permit.so
account required pam_faillock.so (4)
| 1 | Antes de pedir la contraseña, deniega el acceso si la cuenta ya está bloqueada. |
| 2 | Verificación de la contraseña. Si es correcta, salta las dos reglas siguientes y llega a pam_permit. |
| 3 | Solo se alcanza si la contraseña es incorrecta. Registra el fallo, bloquea la cuenta si se alcanza el umbral y termina la pila con error. |
| 4 | Tras una autenticación correcta, pone a cero el contador de fallos del usuario. |
Conviene fijarse en el campo de control [success=2 default=ignore] de la regla de pam_unix, la que comprueba la contraseña. Como se vio en la sección 4, success=2 significa «si la contraseña es correcta, salta las dos reglas siguientes». Esas dos reglas son authfail y pam_deny, de forma que una contraseña válida las esquiva y llega directamente a pam_permit, que confirma el acceso. Ese número tiene que coincidir con cuántas reglas hay detrás de pam_unix. Si se pusiera success=1, una contraseña correcta saltaría solo una regla, caería en pam_deny (que siempre falla) y nadie podría entrar. Calcular bien ese salto es delicado, y es justo lo que hace pam-auth-update de forma automática, un motivo más para no editar las pilas comunes a mano.
En Debian y Ubuntu, estas reglas se añaden mediante perfiles de pam-auth-update, como se muestra en el Ejercicio 5, y los parámetros se definen en /etc/security/faillock.conf:
| Parámetro | Valor CIS | Descripción |
|---|---|---|
|
|
Número de fallos consecutivos que provocan el bloqueo |
|
|
Ventana en segundos en la que se cuentan los fallos |
|
|
Duración del bloqueo en segundos. Con |
|
Activado |
Aplica también el bloqueo a |
|
|
Duración específica del bloqueo de |
|
Opcional |
Registra el nombre de usuario de los intentos contra cuentas inexistentes |
|
|
Directorio de los contadores |
sudo faillock --user maria # Consulta los fallos registrados
sudo faillock --user maria --reset # Desbloquea la cuenta
|
Consideraciones operativas del bloqueo
|
|
|
6.2. Robustez de las contraseñas con pam_pwquality
Las contraseñas débiles son una de las vías de entrada más habituales, así que conviene rechazarlas en el momento en que se crean. De eso se ocupa pam_pwquality, que evalúa cada contraseña nueva en la pila password, la fase de PAM que se ejecuta al cambiar una contraseña, y comprueba que cumple una serie de reglas de robustez antes de que pam_unix la guarde. Si no las cumple, la rechaza y el usuario debe elegir otra.
Su configuración se define en /etc/security/pwquality.conf o, preferiblemente, en archivos de /etc/security/pwquality.conf.d/, que no se sobrescriben al actualizar el paquete. Los parámetros más importantes son los siguientes:
| Parámetro | Valor CIS | Descripción |
|---|---|---|
|
|
Longitud mínima |
|
|
Número de clases de caracteres exigidas: minúsculas, mayúsculas, dígitos y otros símbolos |
|
|
Caracteres que deben cambiar respecto a la contraseña anterior |
|
|
Máximo de caracteres idénticos consecutivos |
|
|
Máxima longitud de secuencias monótonas, como |
|
|
Rechaza contraseñas basadas en palabras de diccionario, con la biblioteca |
|
|
Rechaza contraseñas que contienen el nombre de usuario |
|
|
Rechaza la contraseña en lugar de limitarse a advertir |
|
Activado |
Aplica la política también cuando |
|
Sin |
|
La guía NIST SP 800-63B prioriza la longitud y la comprobación contra listas de contraseñas comprometidas frente a las reglas de composición, que llevan a los usuarios a patrones predecibles como |
Para que la política surta efecto hacen falta dos pasos. El primero es que el módulo pam_pwquality esté instalado y presente en la pila common-password. En Debian y Ubuntu se consigue instalando libpam-pwquality, que pam-auth-update añade a common-password de forma automática. En una instalación mínima el módulo no está, y passwd aceptará cualquier contraseña aunque exista el archivo de configuración.
# Actualiza el índice de paquetes
sudo apt update
# Instala el módulo y, de paso, pwscore (del paquete de herramientas)
sudo apt install -y libpam-pwquality libpwquality-tools
El segundo paso es crear el archivo de configuración en /etc/security/pwquality.conf.d/, que pam_pwquality lee al validar cada contraseña nueva, sin necesidad de reiniciar ningún servicio:
# /etc/security/pwquality.conf.d/99-bastionado.conf
minlen = 14
minclass = 4
difok = 2
maxrepeat = 3
maxsequence = 3
dictcheck = 1
usercheck = 1
enforcing = 1
enforce_for_root
Desde ese momento, cualquier contraseña nueva que no cumpla la política se rechaza cuando el usuario ejecuta passwd.
6.2.1. Comprobar la política con pwscore
pwscore, del paquete libpwquality-tools, evalúa una contraseña con la política vigente sin modificar ninguna cuenta. Lee la contraseña por la entrada estándar y devuelve una puntuación de 0 a 100 si la acepta, o el motivo del rechazo si no la cumple. Es la forma más rápida de probar la configuración antes de aplicarla a los usuarios.
# Un patrón predecible, rechazado por longitud
echo 'Verano2026!' | pwscore
Password quality check failed:
The password is shorter than 14 characters
# Una contraseña que sí cumple la política
echo '7xQ!vp2L#mZ9fR' | pwscore
44
La puntuación no es una nota de corte, sino una orientación, y una contraseña puede cumplir la política y aun así obtener un valor modesto. El ejemplo ilustra también la tensión que señala la nota anterior. La frase de contraseña caballo-grapa-correcta-37, es decir, varias palabras unidas que forman una contraseña larga y fácil de recordar, es mucho más difícil de adivinar que Verano2026!. Aun así, minclass = 4 la rechaza por no reunir cuatro clases de caracteres, mientras que la cadena 7xQ!vp2L#mZ9fR, más corta pero con las cuatro clases, sí la supera. Por eso conviene primar la longitud sobre el número de clases.
pwscore valida el archivo de configuración, porque lee las mismas opciones, pero no depende de que el módulo esté activo en common-password. Para la comprobación de extremo a extremo, pida a una cuenta de prueba que cambie su contraseña con passwd. Si la contraseña no cumple la política, passwd la rechaza con un mensaje que empieza por BAD PASSWORD: seguido del motivo, como BAD PASSWORD: The password is shorter than 14 characters, y vuelve a pedirla.
6.3. Historial de contraseñas con pam_pwhistory
Exigir contraseñas robustas no sirve de mucho si, cuando caducan, el usuario vuelve a la de siempre o alterna entre dos o tres que conoce de memoria. pam_pwhistory lo impide, porque recuerda las últimas contraseñas de cada usuario y rechaza cualquier intento de reutilizar una de ellas.
Para recordarlas, guarda en el archivo /etc/security/opasswd el hash de cada contraseña anterior, es decir, una huella criptográfica irreversible de la que no puede recuperarse la contraseña en claro. El CIS Benchmark exige recordar al menos 24. Al igual que pam_pwquality, el módulo actúa en la pila password, y en Debian y Ubuntu su regla se añade mediante un perfil de pam-auth-update, no se escribe a mano en common-password. La regla resultante tiene este aspecto:
password requisite pam_pwhistory.so remember=24 enforce_for_root try_first_pass use_authtok
Cada argumento cumple una función:
-
remember=24indica cuántas contraseñas anteriores se recuerdan y, por tanto, no pueden reutilizarse. -
enforce_for_rootaplica la comprobación también cuandorootcambia una contraseña. -
try_first_passreutiliza la contraseña que el usuario ya ha tecleado antes de volver a pedírsela. -
use_authtokobliga a usar la contraseña quepam_pwqualityya ha recibido y validado, en lugar de solicitarla otra vez. Es lo que encadena ambos módulos en la misma operación de cambio de contraseña.
El archivo /etc/security/opasswd debe tener permisos 600 y pertenecer a root:root, porque contiene hashes de contraseñas y ningún otro usuario debe poder leerlo.
6.4. Opciones seguras de pam_unix
pam_unix es el módulo clásico de autenticación local. Comprueba la contraseña contra /etc/shadow y, cuando se cambia, calcula y guarda su hash. Interviene en casi todas las pilas, así que conviene revisar con qué opciones se configura. El CIS Benchmark establece estos requisitos para sus reglas en las pilas comunes:
-
Sin
nullok. La opciónnullokpermitiría entrar a una cuenta cuyo campo de contraseña está vacío. Debe retirarse de todas las pilas para que ninguna cuenta pueda autenticarse sin contraseña. -
Sin
rememberen la pilapassword. Esta opción haría que el historial de contraseñas lo llevarapam_unix, pero de eso debe encargarsepam_pwhistory(sección 6.3), que lo hace mejor. -
Algoritmo de hash robusto en la pila
password. Es el algoritmo con el que se calcula el hash de la contraseña al guardarla. Cuanto más robusto, más costoso resulta descifrarla si alguien consigue una copia de/etc/shadow. Se recomiendayescrypt, el valor por defecto en Ubuntu 24.04, osha512. -
use_authtoken la pilapassword. Hace quepam_unixguarde la contraseña que ya han recibido y validado los módulos anteriores, comopam_pwqualityypam_pwhistory, en lugar de pedir una nueva por su cuenta.
6.5. Restricción de su con pam_wheel
La orden su, del inglés switch user, permite adoptar la identidad de otro usuario, normalmente root, si se conoce su contraseña. Esto plantea dos problemas de bastionado. El primero es que cualquiera que averigüe la contraseña de root se convierte en root. El segundo es que la acción no queda ligada a una persona concreta. sudo, en cambio, es nominal, es decir, cada acción queda atribuida al usuario que la ejecuta y registrada en el diario.
Por eso el CIS Benchmark exige restringir su a los miembros de un grupo y dejar ese grupo vacío, de modo que en la práctica nadie pueda usar su y la elevación de privilegios se canalice siempre por sudo. El módulo que aplica la restricción es pam_wheel.
Primero se crea el grupo, sin añadirle ningún usuario:
sudo groupadd sugroup
Después se añade la regla al archivo /etc/pam.d/su, que es el archivo de servicio PAM de la orden su y, a diferencia de los archivos common-*, se edita directamente:
# /etc/pam.d/su
auth required pam_wheel.so use_uid group=sugroup
La regla exige pertenecer al grupo sugroup para poder usar su, y como el grupo está vacío, nadie cumple la condición. La opción use_uid hace que pam_wheel compruebe el UID real de quien ejecuta su, en lugar de un nombre de inicio de sesión que podría falsearse.
|
En Ubuntu, la cuenta |
|
Con los conceptos explicados en los apartados anteriores, ya puede realizar el Ejercicio 5. Bloqueo por intentos fallidos con |
6.6. Autenticación multifactor con TOTP
La autenticación multifactor (MFA) refuerza el acceso al exigir, además de algo que el usuario sabe (la contraseña), algo que tiene (un código temporal generado en su móvil), de modo que una contraseña robada ya no basta para entrar. El módulo pam_google_authenticator, del paquete libpam-google-authenticator, añade ese segundo factor basado en el algoritmo TOTP (Time-based One-Time Password) definido en el RFC 6238. El usuario y el servidor comparten un secreto, y ambos calculan cada 30 segundos un código de seis dígitos a partir de ese secreto y de la hora actual. Lo implementan aplicaciones como Google Authenticator, FreeOTP o Aegis.
-
Se instala el paquete que aporta el módulo y la herramienta
google-authenticatorcon la que cada usuario genera su secreto:# Actualiza el índice de paquetes sudo apt update # Instala el módulo y la herramienta de generación del secreto sudo apt install -y libpam-google-authenticator -
Cada usuario genera su secreto, que se guarda en
~/.google_authenticatorcon permisos400:google-authenticator -t -d -f -C -r 3 -R 30 -w 3Cada opción ajusta el comportamiento del segundo factor:
Opción Función -tUsa códigos basados en el tiempo (TOTP)
-dImpide reutilizar un código ya empleado
-fEscribe el archivo de configuración sin pedir confirmación
-CNo solicita confirmar un código durante la instalación, pensado para configuraciones no interactivas
-r 3y-R 30Limitan los intentos a 3 cada 30 segundos, para frenar los ataques de fuerza bruta contra el código
-w 3Acepta 3 códigos válidos a la vez, para tolerar un pequeño desfase entre el reloj del móvil y el del servidor
La herramienta dibuja en la propia terminal un código QR con caracteres de bloque y, debajo, el secreto en Base32, un primer código de verificación y cinco códigos de emergencia:
Warning: pasting the following URL into your browser exposes the OTP secret to Google: https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/... [aquí se dibuja el código QR] Your new secret key is: JV553MJBX2K5ADDWYPJ4W2PWOQ Your verification code for code 1 is 455530 Your emergency scratch codes are: 43679288 50982468 69373011 66188301 86617512 -
Se registra el secreto en la aplicación del teléfono, por ejemplo Google Authenticator, FreeOTP o Aegis. En Google Authenticator se pulsa el botón +, se elige Escanear un código QR y se apunta la cámara al QR que ha quedado en la terminal. Si la cámara no consigue leerlo, se elige Introducir una clave de configuración, se escribe un nombre para la cuenta, se teclea el secreto de la línea
Your new secret key isy se selecciona el tipo Basada en el tiempo. A partir de ese momento la aplicación muestra un código de seis dígitos que se renueva cada 30 segundos.No abra la dirección de
google.com/chartque aparece en el aviso de la salida. El código QR de la terminal se genera en el propio servidor, mientras que esa URL enviaría el secreto a Google dentro de la propia petición, tal y como advierte el mensaje. Escanee siempre el QR de la terminal o teclee el secreto a mano.Algunos detalles que conviene tener en cuenta al registrar el secreto:
-
Escanee el QR antes de cerrar la terminal. La herramienta no vuelve a mostrarlo, y después el secreto solo está en la primera línea de
~/.google_authenticator, un archivo con permisos400. Si se pierde, hay que generar un secreto nuevo y volver a registrarlo. -
Guarde los cinco códigos de emergencia en un lugar seguro y fuera del servidor. Cada uno sirve una sola vez y son la única vía de acceso si se pierde el teléfono. Se almacenan en claro al final de
~/.google_authenticator, así que quien pueda leer ese archivo puede usarlos.
-
-
Se añade el módulo a la pila
authde/etc/pam.d/sshd, un archivo que ya existe y que en este caso sí se edita, insertando la regla justo a continuación de la línea@include common-auth, de modo que se pidan la contraseña y el código:auth required pam_google_authenticator.so nulloknullokpermite el acceso a los usuarios que aún no han configurado el segundo factor y debe eliminarse cuando todos lo hayan hecho. -
Se habilita en
sshdel método keyboard-interactive, que es el que permite a PAM mantener un diálogo con varias preguntas. Para ello se crea un archivo nuevo en/etc/ssh/sshd_config.d/, en lugar de modificar/etc/ssh/sshd_config:# Crea el archivo de configuración propio de la MFA, que no existe de antemano sudo nano /etc/ssh/sshd_config.d/60-mfa.confKbdInteractiveAuthentication yes UsePAM yesEl directorio
/etc/ssh/sshd_config.d/está vacío en una instalación recién hecha, así que el archivo se crea desde cero. El nombre es libre siempre que termine en.conf, y el número inicial solo fija el orden de lectura cuando hay varios, igual que en/etc/security/pwquality.conf.d/. Se usa60-mfa.confpor coherencia con el Ejercicio 8.Esta forma de configurar
sshdfunciona porque/etc/ssh/sshd_configincluye en su parte superior la directivaInclude /etc/ssh/sshd_config.d/*.conf, antes de las demás opciones, y porque para casi todas las palabras clavesshdconserva el primer valor que encuentra. Lo que se escriba en el archivo propio prevalece, por tanto, sobre lo que aparezca más abajo ensshd_config. En Ubuntu 24.04 esto importa, ya quesshd_configtraeKbdInteractiveAuthentication node serie, y el archivo nuevo lo deja enyessin tocar esa línea. La opciónUsePAM yesya viene activada en Ubuntu, y se incluye para dejar explícito que la MFA depende de ella. -
Se valida la configuración de
sshdy se recarga el servicio:# Comprueba la sintaxis de la configuración antes de aplicarla sudo sshd -t # Relee la configuración sin cortar las sesiones SSH abiertas sudo systemctl reload sshEste último paso solo hace falta por el cambio del paso 5. Los archivos de
/etc/pam.d/los lee PAM en cada autenticación, así que la regla añadida en el paso 4 surte efecto en el siguiente intento de acceso sin tocar el servicio. En cambio,sshdlee su propia configuración al arrancar, por lo queKbdInteractiveAuthenticationno se aplica hasta que se recarga. Conviene usarreloaden lugar derestart, porquereloadrelee la configuración sin cerrar las sesiones establecidas, que es la red de seguridad si la nueva configuración impide autenticarse.
Para exigir además la clave pública, se añade AuthenticationMethods publickey,keyboard-interactive al archivo del paso 5, lo que obliga a recargar de nuevo el servicio. En ese caso, como la clave pública ya sustituye a la contraseña, conviene comentar @include common-auth en /etc/pam.d/sshd para que PAM solo pida el código TOTP.
|
Mantenga abierta una sesión SSH mientras prueba el acceso desde otra terminal. Compruebe también que la hora del servidor está sincronizada, por ejemplo con |
|
Con los conceptos explicados en este apartado, ya puede realizar el Ejercicio 8. Segundo factor TOTP en SSH. |
7. Pruebas, depuración y recuperación
7.1. Pruebas con pamtester
pamtester, del paquete del mismo nombre, ejecuta las operaciones de PAM sobre un servicio y un usuario sin necesidad de iniciar sesión, lo que permite comprobar un cambio antes de depender de él:
sudo pamtester login maria authenticate # Pila auth del servicio login
sudo pamtester sshd maria acct_mgmt # Pila account del servicio sshd
sudo pamtester -v su maria authenticate open_session # Varias operaciones y modo detallado
7.2. Registros y depuración
Los módulos registran sus mensajes en la categoría authpriv de syslog, que en Debian y Ubuntu se escribe en /var/log/auth.log y en el diario de systemd:
sudo journalctl -f SYSLOG_FACILITY=10 # Mensajes de autenticación en tiempo real
sudo journalctl -g 'pam_(unix|faillock|pwquality)' --since '-1h'
sudo grep 'pam_unix' /var/log/auth.log
Muchos módulos admiten el argumento debug, que añade información sobre cada decisión. Debe retirarse al terminar, ya que aumenta el volumen de los registros y puede exponer información sensible.
7.3. Prevención y recuperación de bloqueos
|
Un error en PAM puede dejar el sistema inaccesible Antes de modificar cualquier archivo de
Si se pierde el acceso, la recuperación exige arrancar en modo de rescate, o con el parámetro del núcleo |
8. Guía consolidada de bastionado y lista de verificación
8.1. Matriz de riesgos y medidas técnicas
| Vector de amenaza | Impacto potencial | Medida de bastionado | Verificación técnica |
|---|---|---|---|
Fuerza bruta contra contraseñas |
Acceso con credenciales adivinadas |
|
|
Contraseñas débiles |
Éxito de ataques de diccionario |
|
|
Reutilización de contraseñas |
Uso de credenciales filtradas anteriormente |
|
|
Cuentas sin contraseña |
Acceso sin autenticación |
Eliminar |
|
Uso de |
Elevación sin trazabilidad nominal |
|
|
Robo de la contraseña |
Acceso remoto con una credencial válida |
Segundo factor TOTP o claves con frase de paso |
|
Puerta trasera en |
Acceso sin contraseña persistente |
Permisos |
|
Volcados de memoria con secretos |
Fuga de contraseñas y claves |
|
|
8.2. Lista de verificación CIS Benchmark para Ubuntu 24.04
La siguiente lista reúne los controles del CIS Benchmark para Ubuntu que afectan a PAM, cada uno con la orden que permite verificarlo.
-
Paquetes actualizados:
libpam-runtime,libpam-modulesylibpam-pwqualityinstalados y en su última versión.apt list --installed 'libpam-runtime' 'libpam-modules' 'libpam-pwquality' 2>/dev/null -
Perfiles de
pam-auth-updateactivados parapam_unix,pam_faillock,pam_pwqualityypam_pwhistory:grep -E 'pam_(unix|faillock|pwquality|pwhistory)' /etc/pam.d/common-{auth,account,password} -
Bloqueo por intentos fallidos con
denyigual o inferior a 5,unlock_timeigual a 0 o superior a 900, yeven_deny_rootoroot_unlock_timede al menos 60:grep -Ev '^\s*(#|$)' /etc/security/faillock.conf -
Política de calidad con
minlende al menos 14,difokde al menos 2, complejidad exigida,maxrepeatymaxsequencede 3 o menos, ydictcheck,enforcingyenforce_for_rootactivos:grep -rEv '^\s*(#|$)' /etc/security/pwquality.conf /etc/security/pwquality.conf.d/ grep pam_pwquality /etc/pam.d/common-password -
Historial de contraseñas con
rememberde al menos 24,enforce_for_rootyuse_authtok:grep pam_pwhistory /etc/pam.d/common-password -
pam_unixsinnullokniremember, conyescryptosha512yuse_authtoken la pilapassword:grep -nE 'pam_unix.*(nullok|remember)' /etc/pam.d/common-* && echo "NO CONFORME" grep -E 'pam_unix.*(yescrypt|sha512).*use_authtok|pam_unix.*use_authtok.*(yescrypt|sha512)' /etc/pam.d/common-password -
Acceso a
surestringido a un grupo vacío:grep -E '^\s*auth\s+required\s+pam_wheel\.so.*use_uid.*group=' /etc/pam.d/su getent group sugroup -
Volcados de memoria deshabilitados mediante
pam_limitsyfs.suid_dumpable = 0. -
Integridad de la configuración de PAM: sin cambios respecto a los archivos distribuidos por los paquetes, salvo los documentados.
sudo dpkg --verify libpam-runtime libpam-modules libpam-modules-bin stat -c '%a %U:%G %n' /etc/pam.d/* | grep -v '^644 root:root'
|
Una vez estudiadas todas las medidas de esta guía, puede consolidar sus competencias completando el Ejercicio 9. Auditoría CIS de la configuración de PAM. |
9. Ejercicios prácticos
Los ejercicios están diseñados para realizarse en orden sobre una máquina virtual Ubuntu 24.04 o Debian de pruebas, ya que algunos reutilizan usuarios, perfiles y archivos creados en ejercicios anteriores. El último ejercicio deja el sistema en su estado original.
|
No realice estos ejercicios en un servidor en producción. Durante toda la práctica, mantenga abierta en una terminal aparte una sesión de |
| Nº | Ejercicio | Competencia que desarrolla | Dificultad |
|---|---|---|---|
1 |
Identificar servicios, pilas, módulos y perfiles |
Baja |
|
2 |
Comprender la evaluación de las pilas con |
Media |
|
3 |
Integrar PAM en una aplicación y conocer sus límites |
Alta |
|
4 |
Aplicar |
Media |
|
5 |
Configurar el bloqueo mediante perfiles de |
Media |
|
6 |
Implantar los controles CIS sobre contraseñas |
Media |
|
7 |
Limitar la elevación de privilegios a |
Media |
|
8 |
Añadir autenticación multifactor a un servicio remoto |
Alta |
|
9 |
Verificar la conformidad de forma automatizada |
Alta |
|
10 |
Revertir los cambios realizados durante la práctica |
Baja |
9.1. Ejercicio 1. Exploración de la configuración de PAM
Realice los siguientes pasos:
-
Haga una copia de seguridad de
/etc/pam.d/,/etc/security/y/etc/ssh/en/root/pam_backup/, conservando permisos y propietarios. Instale las herramientas que se usarán en la práctica:pamtester,libpam-pwquality,libpwquality-toolsyopenssh-server.Solución
# Crea el directorio donde se guardará la copia de seguridad sudo mkdir -p /root/pam_backup # Copia los archivos de configuración conservando permisos y propietarios (-a) sudo cp -a /etc/pam.d /etc/security /etc/ssh /root/pam_backup/ # Actualiza el índice de paquetes sudo apt update # Instala las herramientas que se usan durante la práctica sudo apt install -y pamtester libpam-pwquality libpwquality-tools openssh-server -
Liste los servicios configurados en
/etc/pam.d/y compruebe sus permisos y propietario.Solución
# Lista los archivos de servicio de /etc/pam.d/ con sus permisos y propietario ls -l /etc/pam.d/ -
Muestre las reglas activas de
/etc/pam.d/sshdy decommon-auth. Identifique qué archivos incluyesshdy explique el patrón de salto decommon-auth.Solución
# Muestra solo las reglas activas de sshd, omitiendo comentarios y líneas en blanco grep -Ev '^\s*(#|$)' /etc/pam.d/sshd # Lo mismo para common-auth, la pila auth que incluyen casi todos los servicios grep -Ev '^\s*(#|$)' /etc/pam.d/common-authEn
common-authobtendrá un bloque parecido a este:auth [success=1 default=ignore] pam_unix.so nullok auth requisite pam_deny.so auth required pam_permit.so auth optional pam_cap.soEl patrón de salto está en el control
[success=1 default=ignore]depam_unix. Puede encontrar más información en la sintaxis avanzada de la sección 4.2. Si la contraseña es correcta,success=1hace saltar una regla, la depam_deny, y la ejecución cae enpam_permit, que confirma el acceso. Si la contraseña falla,default=ignoredescarta ese resultado y continúa enpam_deny, que siempre falla y, al serrequisite, corta la pila.pam_permites necesario porque el resultado depam_unixse descartó conignore, de modo que hace falta un módulo que fije un resultado positivo tras el salto.La última línea,
pam_cap.so, está después depam_permit, así que no forma parte del salto. Es un módulooptionalque ajusta las capacidades del usuario y solo se alcanza cuando la autenticación ha tenido éxito. Al seroptional, no altera el resultado global aunque falle.El número del salto depende de cuántas reglas haya entre
pam_unixypam_permit. Aquí essuccess=1porque en medio solo estápam_deny. Si se insertan más módulos ahí,pam-auth-updaterecalcula ese número de forma automática, como ocurre en elpam_faillockde la sección 6.1, donde pasa a sersuccess=2. -
Compruebe que
sshdysudoestán enlazados conlibpamy localice el directorio de módulos del sistema.Solución
# Comprueba que el binario de sshd está enlazado con la biblioteca libpam ldd "$(command -v sshd)" | grep libpam # Hacemos lo mismo para sudo ldd "$(command -v sudo)" | grep libpam # Muestra la ruta del módulo pam_unix.so y, con ella, el directorio de módulos del sistema dpkg -L libpam-modules | grep 'pam_unix.so$'Las órdenes
lddydpkg -Llddlista las bibliotecas compartidas de las que depende un ejecutable, de modo que, si entre ellas figuralibpam, el programa usa PAM para autenticar.dpkg-Lmuestra todos los archivos que instaló un paquete de Debian o Ubuntu, así que filtrar porpam_unix.sorevela su ruta y, con ella, el directorio donde residen los módulos del sistema. -
Liste los perfiles disponibles para
pam-auth-updatey muestre el contenido del perfilunix.Solución
# Lista los perfiles disponibles de pam-auth-update (un archivo por perfil) ls /usr/share/pam-configs/ # Muestra el contenido del perfil unix, que define las reglas de pam_unix cat /usr/share/pam-configs/unix
9.2. Ejercicio 2. Un servicio PAM propio y el campo de control
Realice los siguientes pasos:
-
Cree el usuario
prueba_pamcon una contraseña conocida y el grupoadmins_lab, sin añadir el usuario a este grupo.Solución
# Crea el usuario de pruebas con directorio personal (-m) y shell bash sudo useradd -m -s /bin/bash prueba_pam # Le asigna una contraseña conocida (la pedirá de forma interactiva) sudo passwd prueba_pam # Crea el grupo admins_lab, de momento sin ningún miembro sudo groupadd admins_labEl usuario se deja fuera de
admins_laba propósito, porque el paso 2 comprueba justo lo contrario, que la pilaauthdeniega el acceso a quien no pertenece al grupo. El usuario se añadirá al grupo más adelante, en el paso 4. -
Cree el servicio
/etc/pam.d/laboratoriocon una pilaauthque solo permita autenticarse a los miembros deadmins_laby una pilaaccountbasada encommon-account:auth requisite pam_succeed_if.so user ingroup admins_lab auth required pam_unix.so @include common-accountCompruebe con
pamtesterqueprueba_pamno puede autenticarse. Observe si llega a pedirse la contraseña y explique el motivo.Solución
# Crea el servicio con sus tres reglas sudo nano /etc/pam.d/laboratorio # Comprueba el acceso. No se pide la contraseña, porque pam_succeed_if falla y, al ser requisite, termina la pila sudo pamtester laboratorio prueba_pam authenticatepam_succeed_ifsolo tiene éxito si se cumple su condición, que aquí esuser ingroup admins_lab. Comoprueba_pamtodavía no pertenece aadmins_lab(en el paso 1 se creó sin añadirlo al grupo), la condición es falsa y el módulo falla. Al serrequisite, la pilaauthse corta en esa primera regla, de modo quepam_unixno llega a ejecutarse y no se pide la contraseña. El acceso se deniega antes incluso de solicitar credenciales. -
Cambie
requisiteporrequireden la primera regla y repita la prueba. Explique la diferencia de comportamiento y por quérequiredes preferible desde el punto de vista de la seguridad.Solución
# Sustituye requisite por required en la primera regla del servicio sudo sed -i 's/^auth requisite/auth required /' /etc/pam.d/laboratorio # Repite la prueba. Ahora sí se pide la contraseña, aunque el resultado será un error, de modo que el atacante no sabe qué comprobación ha fallado sudo pamtester laboratorio prueba_pam authenticateAunque ahora se pida la contraseña, la autenticación sigue fallando incluso con la contraseña correcta, porque
prueba_pamtodavía no pertenece aadmins_labypam_succeed_ifcontinúa fallando. La diferencia es que, conrequired, ese fallo no corta la pila, sino que marca el resultado global como error y deja continuar hastapam_unix. Por esopam_unixllega a pedir la contraseña y la valida, pero su éxito no rescata el fallo previo. La contraseña correcta solo satisface apam_unix, no al requisito de pertenecer al grupo.Desde el punto de vista de la seguridad,
requiredes preferible precisamente por eso, ya que al pedir siempre la contraseña no revela en qué comprobación se ha fallado. Conrequisite, la ausencia de la pregunta delataría que el usuario no cumple una condición previa, una información útil para un atacante. El acceso solo tendrá éxito cuandoprueba_pamesté enadmins_lab, como se hace en el paso siguiente. -
Añada
prueba_pamal grupoadmins_laby compruebe que la autenticación tiene éxito con la contraseña correcta y falla con una incorrecta.Solución
# Añade prueba_pam al grupo admins_lab sin sacarlo de sus otros grupos (-aG) sudo usermod -aG admins_lab prueba_pam # Prueba las fases auth y account. Con la contraseña correcta ahora sí tiene éxito sudo pamtester laboratorio prueba_pam authenticate acct_mgmtLas dos palabras finales (
authenticateyacct_mgmt) son operaciones quepamtesterejecuta en orden, cada una sobre una pila distinta del serviciolaboratorio.authenticateejecuta la faseauth(pam_succeed_ifypam_unix), que comprueba quién es el usuario y valida su contraseña.acct_mgmtejecuta la faseaccount, que aquí es@include common-account, y comprueba si esa cuenta puede usarse una vez autenticada, es decir, que no esté caducada, expirada ni bloqueada. Pedir ambas reproduce lo que hace un acceso real, donde la aplicación llama primero apam_authenticate()y después apam_acct_mgmt(). -
Compruebe qué ocurre al autenticar contra un servicio inexistente, como
servicio_fantasma, y relacione el resultado con el contenido de/etc/pam.d/other.Solución
# Intenta autenticar contra un servicio que no tiene archivo en /etc/pam.d/ sudo pamtester servicio_fantasma prueba_pam authenticateFunciona con la contraseña correcta. Como no existe
/etc/pam.d/servicio_fantasma, PAM aplica/etc/pam.d/other, que en Debian y Ubuntu incluye las pilascommon-*, de modo que un servicio sin configuración propia autentica igual que cualquier otro. En la familia Red Hat, en cambio,otherusapam_denyy el acceso se denegaría.
9.3. Ejercicio 3. Autenticación PAM desde una aplicación Python
En este ejercicio se desarrolla una aplicación que delega la autenticación en PAM mediante la biblioteca python-pam, utilizando el servicio laboratorio creado en el ejercicio anterior.
Realice los siguientes pasos:
-
Cree un entorno virtual de Python en
~/app_pame instale en él la bibliotecapython-pam.Solución
# Actualiza el índice de paquetes sudo apt update # Instala el módulo de Python para crear entornos virtuales sudo apt install -y python3-venv # Crea un entorno virtual aislado en ~/app_pam/venv python3 -m venv ~/app_pam/venv # Instala python-pam dentro del entorno virtual, sin tocar el Python del sistema ~/app_pam/venv/bin/pip install python-pam -
Cree el archivo
~/app_pam/app.pycon el siguiente contenido:#!/usr/bin/env python3 import getpass import pam def autenticar(): p = pam.pam() usuario = input("Usuario: ") password = getpass.getpass("Contraseña: ") if p.authenticate(usuario, password, service="laboratorio"): print(f"Autenticación correcta. Bienvenido, {usuario}.") else: print(f"Error de autenticación: {p.reason} (código {p.code}).") if __name__ == "__main__": autenticar() -
Ejecute la aplicación con privilegios de
rooty autentique aprueba_pamcon la contraseña correcta y con una incorrecta.Solución
# Ejecuta la aplicación como root, que sí puede leer /etc/shadow sudo ~/app_pam/venv/bin/python ~/app_pam/app.py -
Ejecute la aplicación con su usuario sin privilegios e intente autenticar a
prueba_pam. Explique por qué falla aunque la contraseña sea correcta, teniendo en cuenta que un proceso sin privilegios no puede leer/etc/shadowy quepam_unixrecurre entonces al programa auxiliarunix_chkpwd.Solución
# Ejecuta la aplicación como tu usuario normal, sin sudo ~/app_pam/venv/bin/python ~/app_pam/app.py # El verificador auxiliar de contraseñas es SetGID shadow ls -l /usr/sbin/unix_chkpwdLa autenticación falla aunque la contraseña sea correcta. El archivo
/etc/shadowtiene modo640y pertenece aroot:shadow, así que un proceso sin privilegios no puede leerlo. Cuandopam_unixno se ejecuta comoroot, delega la comprobación en el programa auxiliarunix_chkpwd, que es SetGIDshadowy sí puede leer/etc/shadow. Perounix_chkpwdsolo acepta verificar la contraseña del propio usuario que lo invoca, no la de otra cuenta. Como tu usuario intenta autenticar aprueba_pam, que es distinto,unix_chkpwdse niega y la autenticación falla. Esta restricción impide que un proceso sin privilegios useunix_chkpwdcomo un oráculo de fuerza bruta contra las contraseñas de otros usuarios. Por eso el paso 3 sí funcionaba consudo, ya querootpuede leer/etc/shadowdirectamente.
9.4. Ejercicio 4. Mantenimiento y restricción de accesos
Realice los siguientes pasos:
-
Cree el archivo
/etc/nologincon un mensaje de mantenimiento y compruebe conpamtesterqueprueba_pamno puede autenticarse en el serviciologin, mientras querootsí. Elimine después el archivo.Solución
# Crea /etc/nologin con un mensaje; su mera presencia bloquea el acceso de los no-root echo "Mantenimiento programado." | sudo tee /etc/nologin > /dev/null # prueba_pam es rechazado por pam_nologin sudo pamtester login prueba_pam authenticate # root sí puede entrar, siempre que tenga contraseña; si está bloqueada, falla por ese motivo sudo pamtester login root authenticate # Elimina el archivo para restaurar el acceso normal sudo rm /etc/nologinpam_nologinactúa en la pilaauthdel serviciologin. Si existe/etc/nologin, el módulo muestra su contenido y devuelve un fallo para cualquier cuenta que no searoot, de modo queprueba_pamqueda rechazado sin llegar a comprobar su contraseña. La cuenta derootestá exenta, por lo que el administrador conserva el acceso mientras el sistema permanece en mantenimiento. -
Active
pam_accessen la pilaaccountdel serviciolaboratorioy configure/etc/security/access.confpara que solo los miembros deadmins_labpuedan acceder, y únicamente en local. Haga antes una copia deaccess.conf. -
Compruebe con
pamtesterla operaciónacct_mgmtparaprueba_pam, retírelo del grupoadmins_laby repita la prueba. Restaure despuésaccess.confy vuelva a añadir el usuario al grupo. -
Cree el archivo
/etc/security/limits.d/50-core.confque deshabilita los volcados de memoria y compruebe el límite en una sesión nueva deprueba_pam.
9.5. Ejercicio 5. Bloqueo por intentos fallidos con pam_faillock
Realice los siguientes pasos:
-
Cree los dos perfiles de
pam-auth-updateque utiliza el CIS Benchmark para activarpam_faillock.Solución
# Crea el primer perfil, que añade la regla authfail a la pila auth sudo nano /usr/share/pam-configs/faillockName: Enable pam_faillock to deny access (1) Default: yes (2) Priority: 0 (3) Auth-Type: Primary (4) Auth: [default=die] pam_faillock.so authfail (5)1 Texto descriptivo del perfil, que aparece en el menú interactivo de pam-auth-update.2 Con yes, el perfil queda activado de serie.3 Prioridad 0, menor que la del perfilunixdepam_unix, que vale256, así que esta regla se coloca después depam_unixen la pilaauth.4 Marca el módulo como método de autenticación principal de la pila auth.5 El argumento authfailanota el intento como fallido cuando la contraseña es incorrecta, y el control[default=die]corta la pila en ese momento.# Crea el segundo perfil, con la regla preauth (auth) y el reseteo del contador (account) sudo nano /usr/share/pam-configs/faillock_notifyName: Notify of failed login attempts and reset count upon success Default: yes Priority: 1024 (1) Auth-Type: Primary Auth: requisite pam_faillock.so preauth (2) Account-Type: Primary (3) Account: required pam_faillock.so (4)1 Prioridad 1024, mayor que la depam_unix, de modo que esta regla se sitúa antes depam_unixen la pilaauth.2 El argumento preauthcomprueba antes de pedir la contraseña si la cuenta ya está bloqueada, y el controlrequisiteinterrumpe la autenticación cuando lo está.3 Marca el módulo como principal también en la pila account.4 Pone a cero el contador de fallos tras un acceso correcto. Se crean dos perfiles porque las reglas de
pam_faillockdeben quedar en posiciones distintas de la pila, y en los perfiles depam-auth-updatela posición la fija el campoPriority, donde a mayor prioridad, más arriba en la pila. Tomando como referencia elPriority: 256del perfilunix, el perfilfaillockqueda por debajo depam_unixy el perfilfaillock_notifypor encima.En conjunto, los dos perfiles dejan
pam_faillocken los tres puntos descritos en la sección 6.1.Al copiar el contenido de los dos perfiles, asegúrese de que ninguna línea termina con espacios en blanco.
pam-auth-updatecompara el valor de los camposAuth-Type,Account-TypeyPassword-Typecon los textos exactosPrimaryyAdditional, de modo que un espacio final convierte el valor enPrimaryy deja de coincidir con cualquiera de los dos. Las reglas de ese perfil se descartan en silencio al generar los archivoscommon-*, sin ningún mensaje de error, así quepam_faillockno llega a la pila y el bloqueo nunca se aplica, aunque el perfil se haya activado con--enable.Un espacio final en
Default: yesproduce un efecto parecido, ya que el perfil deja de contar como activable por omisión y no se selecciona cuandopam-auth-updatese ejecuta sin indicar perfiles, que es lo que ocurre al instalarse o actualizarse un paquete. En los camposNameyPriority, y en las líneas de las reglas, los espacios finales son inofensivos, porque el analizador las recorta antes de usarlas. Ante la duda, elíminelos de todas las líneas y vuelva a ejecutarpam-auth-update. -
Active ambos perfiles y compruebe en
common-authycommon-accountla posición en la que se han insertado las reglas. Observe cómo ha cambiado el saltosuccess=depam_unix.Solución
# Activa los dos perfiles de faillock sudo pam-auth-update --enable faillock faillock_notify # Muestra las reglas activas de ambas pilas (grep antepone el nombre de cada archivo) grep -Ev '^\s*(#|$)' /etc/pam.d/common-auth /etc/pam.d/common-accountEn la salida,
pam_faillockaparece insertado en los tres puntos de la sección 6.1: comopreauthantes depam_unixen la pilaauth, comoauthfailjusto después, y como reglarequireden la pilaaccount.Al añadirse
pam_faillock.so authfaildetrás depam_unix, entre este ypam_permitpasa a haber dos reglas (authfailypam_deny), por lo quepam-auth-updateha recalculado el salto depam_unixde[success=1 …]a[success=2 …]. Encommon-account, en cambio,pam_unixconservasuccess=1, porque la regla defaillockva antes de él y no altera el salto. -
Configure en
/etc/security/faillock.confun umbral de 3 fallos, un bloqueo de 120 segundos y la opciónaudit. Estos valores son más laxos que los del CIS para agilizar la prueba.Solución
# Abre el archivo de configuración de faillock sudo nano /etc/security/faillock.confEl archivo ya existe con todas sus opciones comentadas, así que basta con añadir estas tres líneas al final:
deny = 3 unlock_time = 120 auditLas opciones se escriben en
/etc/security/faillock.conf, que es la forma recomendada, en lugar de pasarlas como argumentos de las reglas, ya que así las tres reglas de los dos perfiles comparten una misma configuración. Condeny = 3la cuenta se bloquea al cuarto intento fallido, conunlock_time = 120el bloqueo se levanta solo a los dos minutos yauditregistra en el diario el nombre del usuario de cada intento fallido, incluso cuando la cuenta no existe. -
Introduzca tres contraseñas incorrectas para
prueba_pamconpamtestery compruebe que, en el cuarto intento, se rechaza incluso la contraseña correcta. Consulte el estado confaillocky los mensajes en el diario.Solución
# Tres intentos con contraseña incorrecta para alcanzar el umbral de bloqueo for i in 1 2 3; do sudo pamtester login prueba_pam authenticate; done # Cuarto intento con la contraseña correcta: ahora se rechaza porque la cuenta ya está bloqueada sudo pamtester login prueba_pam authenticate # Consulta el estado del bloqueo y el número de fallos registrados de prueba_pam sudo faillock --user prueba_pam # Busca en el diario los mensajes de pam_faillock de los últimos 10 minutos sudo journalctl -g pam_faillock --since '-10min'Los tres primeros intentos los deniega
pam_unix, porque la contraseña es incorrecta, ypam_faillock.so authfailanota cada fallo en/var/run/faillock/prueba_pam. En el cuarto intento ya no se llega a comprobar la contraseña, pues la reglapam_faillock.so preauth, situada antes depam_unix, detecta que se ha alcanzado el umbral dedeny = 3y corta la pilaauth. La salida defaillockmuestra la marca de tiempo y el origen de cada fallo, y el diario recoge las líneas depam_faillockgracias a la opciónaudit. -
Desbloquee la cuenta manualmente y compruebe que el acceso vuelve a ser posible.
Solución
# Pone a cero el contador de fallos de prueba_pam y desbloquea la cuenta sudo faillock --user prueba_pam --reset # Comprueba que, con la contraseña correcta, el acceso vuelve a funcionar sudo pamtester login prueba_pam authenticateLa opción
--resetborra los intentos fallidos registrados, de modo quepreauthvuelve a dejar pasar la autenticación sin esperar los 120 segundos deunlock_time. El mismo efecto se consigue de forma automática al expirar ese plazo, y el contador se pone a cero también tras un acceso correcto, gracias a la reglarequired pam_faillock.sode la pilaaccount.
9.6. Ejercicio 6. Política de contraseñas con pam_pwquality y pam_pwhistory
Realice los siguientes pasos:
-
Cree el archivo
/etc/security/pwquality.conf.d/50-cis.confcon los valores del CIS Benchmark de la sección 6.2.Solución
# Crea el directorio de configuración si no existe sudo mkdir -p /etc/security/pwquality.conf.d # Crea el archivo con las opciones del CIS Benchmark sudo nano /etc/security/pwquality.conf.d/50-cis.confminlen = 14 minclass = 4 difok = 2 maxrepeat = 3 maxsequence = 3 dictcheck = 1 usercheck = 1 enforcing = 1 enforce_for_rootLos archivos de
/etc/security/pwquality.conf.d/se leen en orden alfabético después de/etc/security/pwquality.confy sus valores prevalecen sobre los de este, así que la política queda en un archivo propio sin modificar el del sistema, que los paquetes pueden sobrescribir al actualizarse. De las opciones escritas,enforcing = 1hace quepam_pwqualityrechace las contraseñas que no cumplen la política, en lugar de limitarse a advertir, yenforce_for_rootextiende la comprobación a los cambios de contraseña realizados porroot, que de serie queda exento. -
Evalúe con
pwscorelas contraseñasBastionado2026,aaaa1234ABCD!!yTr3s-Gatos.Saltan_Murose indique qué regla incumple cada una de las rechazadas.Solución
# Rechazada, solo reúne tres clases de caracteres porque no incluye símbolos echo 'Bastionado2026' | pwscore # Rechazada, tiene cuatro caracteres repetidos y dos secuencias monótonas echo 'aaaa1234ABCD!!' | pwscore # Aceptada, cumple todas las reglas de la política echo 'Tr3s-Gatos.Saltan_Muros' | pwscorepwscorelee la contraseña de la entrada estándar y la evalúa con la misma configuración que usapam_pwquality, de modo que permite probar la política sin cambiar ninguna contraseña. Si la acepta, devuelve una puntuación de 0 a 100, y si la rechaza, indica la regla incumplida.-
Bastionado2026incumpleminclass = 4, ya que solo combina tres clases de caracteres, minúsculas, mayúsculas y dígitos, y no incluye ningún símbolo. -
aaaa1234ABCD!!sí reúne las cuatro clases, pero incumplemaxrepeat = 3por los cuatro caracteresaconsecutivos ymaxsequence = 3por las secuencias monótonas1234yABCD. -
Tr3s-Gatos.Saltan_Murosse acepta, porque supera los 14 caracteres deminlen, reúne las cuatro clases y no contiene repeticiones, secuencias ni palabras de diccionario.
-
-
Cree el perfil
pwhistoryen/usr/share/pam-configs/que añadepam_pwhistoryconremember=24,enforce_for_root,try_first_passyuse_authtok, actívelo y compruebe el orden de las reglas encommon-password.Solución
# Crea el perfil pwhistory, que añade pam_pwhistory a la pila password sudo nano /usr/share/pam-configs/pwhistoryName: pwhistory password history checking Default: yes Priority: 1024 Password-Type: Primary Password: requisite pam_pwhistory.so remember=24 enforce_for_root try_first_pass use_authtok# Activa el perfil para que pam-auth-update regenere common-password sudo pam-auth-update --enable pwhistory # Muestra las reglas activas de common-password para ver dónde se insertó pam_pwhistory grep -Ev '^\s*(#|$)' /etc/pam.d/common-passwordEl perfil sigue la misma mecánica que los del ejercicio 5, pero sobre la pila
password, con los camposPassword-TypeyPassword:en lugar de los deauth. SuPriority: 1024es mayor que el256del perfilunix, así que la regla depam_pwhistoryse inserta antes depam_unix, que es el orden necesario para rechazar una contraseña repetida antes de quepam_unixguarde su hash en/etc/shadow.Las dos últimas opciones afectan a cómo obtiene el módulo la contraseña. Con
use_authtok,pam_pwhistoryno la pide de nuevo, sino que reutiliza la que ya ha recogido el módulo anterior de la pila, ytry_first_passle indica que pruebe primero esa contraseña. Así el usuario la escribe una sola vez aunque varios módulos la comprueben. Por su parte,remember=24conserva los 24 hashes anteriores yenforce_for_rootaplica también la comprobación aroot. -
Como
root, cambie la contraseña deprueba_pampor una que cumpla la política. Intente volver a asignarle la misma y después una débil, y compruebe que ambas se rechazan.Solución
# Asigna una contraseña robusta a prueba_pam: aceptada por pam_pwquality sudo passwd prueba_pam # Intenta reasignar la misma contraseña: rechazada por pam_pwhistory sudo passwd prueba_pam # Intenta una contraseña débil: rechazada por pam_pwquality gracias a enforce_for_root sudo passwd prueba_pam # Muestra el historial de hashes anteriores almacenado por pam_pwhistory sudo cat /etc/security/opasswdCada rechazo lo produce un módulo distinto de la pila
password. La contraseña repetida la deniegapam_pwhistory, que la compara con los hashes guardados en/etc/security/opasswdy responde con el mensajePassword has been already used. La contraseña débil la deniegapam_pwquality, al no cumplir las reglas del apartado 1. Ambos rechazos se producen únicamente porque los dos módulos llevanenforce_for_root, ya que de serierootpuede asignar cualquier contraseña a otra cuenta sin pasar por estas comprobaciones. El archivo/etc/security/opasswdsolo es legible porrooty guarda los hashes antiguos de cada usuario, que son los que sostienen el historial.
9.7. Ejercicio 7. Restricción de su con pam_wheel
Realice los siguientes pasos:
-
Compruebe que
prueba_pampuede usarsupara adoptar la identidad de otra cuenta si conoce su contraseña. Para ello, cree el usuariodestino_labcon una contraseña conocida. -
Cree el grupo vacío
sugroupy añada a/etc/pam.d/su, antes de@include common-auth, la regla depam_wheelde la sección 6.5. -
Repita la prueba del primer paso y compruebe que ahora se deniega aunque la contraseña sea correcta. Verifique que
sudosigue funcionando para su usuario.
9.8. Ejercicio 8. Segundo factor TOTP en SSH
Realice los siguientes pasos:
-
Instale
libpam-google-authenticatoryoathtool, que se usará para calcular los códigos sin necesidad de un teléfono móvil. -
Genere el secreto TOTP de
prueba_pamy obtenga el secreto en Base32, que es la primera línea del archivo~/.google_authenticator. -
Añada el módulo a
/etc/pam.d/sshdtras@include common-authy cree el archivo/etc/ssh/sshd_config.d/60-mfa.confque habilitaKbdInteractiveAuthentication. Valide la configuración y recargue el servicio. -
Sin cerrar su sesión actual, conéctese con
ssh prueba_pam@localhost. Cuando se solicite el código de verificación, calcúlelo en otra terminal conoathtool. -
Compruebe que un usuario sin archivo
~/.google_authenticatorpuede seguir accediendo gracias anulloky razone qué riesgo supone mantener esta opción una vez completado el despliegue.
9.9. Ejercicio 9. Auditoría CIS de la configuración de PAM
Desarrolle el script /root/auditoria_pam.sh que compruebe los controles de la sección 8.2 y muestre CONFORME o NO CONFORME para cada uno. Ejecútelo y analice los controles que no se cumplen tras los ejercicios anteriores, teniendo en cuenta que algunos valores se relajaron deliberadamente para agilizar las pruebas.
9.10. Ejercicio 10. Limpieza del entorno
Para terminar, revierta los cambios realizados durante la práctica.
Realice los siguientes pasos:
-
Desactive y elimine los perfiles de
pam-auth-updatecreados durante la práctica. -
Restaure
/etc/pam.d/,/etc/security/y/etc/ssh/desde la copia de seguridad del primer ejercicio, elimine el archivo/etc/pam.d/laboratorio, que no existía en la copia, y recargue el servicio SSH tras validar su configuración. -
Elimine los usuarios
prueba_pamydestino_labcon sus directorios personales, los gruposadmins_labysugroup, el directorio~/app_pamy el script de auditoría. -
Compruebe con
pamtesterque su propio usuario puede autenticarse con normalidad en los serviciosloginysudoantes de cerrar la sesión derootde seguridad. Elimine finalmente la copia/root/pam_backup.
Con la realización de estos ejercicios se consolidan los procedimientos esenciales de configuración, prueba y auditoría de PAM: la evaluación de las pilas, la gestión de perfiles con pam-auth-update, el bloqueo por intentos fallidos, la política de contraseñas, la restricción de su y la autenticación multifactor, conforme a las directrices del CIS Benchmark.
10. Recursos y referencias
10.1. Documentación oficial
-
Páginas de manual:
man pam.d,man pam-auth-update,man pam_faillock,man faillock.conf,man pam_pwquality,man pam_pwhistory,man pam_wheel,man pam_access,man access.conf. -
MITRE ATT&CK T1556.003: Modify Authentication Process: Pluggable Authentication Modules.
11. Licencia
Licencia CC BY-NC-ND 4.0
Esta página forma parte del curso Bastionado de Redes y Sistemas © 2026 de José Juan Sánchez Hernández y su contenido se distribuye bajo una licencia Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International.
Esta licencia exige que quienes reutilicen el material otorguen el debido crédito al autor. Permite copiar y redistribuir el material en cualquier medio o formato, únicamente en su forma original, y solo para fines no comerciales.