Antes de entrar en materia y comentar donde se definen las directivas de contraseñas en entornos Linux, es necesario conocer los campos que estructuran al fichero donde almacenan cifradas las contraseñas de usuarios locales /etc/shadow.

Este fichero nos muestra el estado actual de cómo se están aplicando estas directivas a los usuarios y que nos resulta útil en procesos de auditoría interna para conocer esta información.

Estructura del fichero /etc/shadow Link to heading

Figura 1: Estructura del fichero /etc/shadow.

Figura 1: Estructura del fichero /etc/shadow.

  • 1. Nombre de usuario.
  • 2. Contraseña cifrada. Se establece con la estructura $id$salt$hashed. El tipo de algoritmo utilizado se define en el inicio en números entre los símbolos $.
IDAlgoritmo
$1$MD5
$2a$Blowfish
$2y$Blowfish
$5$SHA-256
$6$SHA-512
  • 3. Último cambio de contraseña desde el 1/Enero/1970 (epoch).
  • 4. Cantidad de días restantes para que el usuario cambie su contraseña. -1 significa que nunca expira.
  • 5. Número máximo de días que la contraseña es válida después del cambio de contraseña por parte del usuario.
  • 6. Días antes de que caduque la contraseña, advierte al usuario para que la cambie.
  • 7. Días después de que caduque la contraseña, esa cuenta estará deshabilitada.
  • 8. Días desde el 1/Enero/1970. Fecha absoluta que especifica cuándo ya no se pueda usar el inicio de sesión para esa cuenta.

Comando chage (caducidad en las contraseñas) Link to heading

Con el comando chage (change age) podemos establecer la caducidad de contraseñas y cuentas de usuario. Esto no afecta a los nuevos usuarios, se establece de forma nominal a usuarios existentes.

Para aplicar estas opciones a nuevos usuarios y así generar estas directivas por defecto habría que hacer uso de login.defs que se comenta más adelante en este artículo.

Opciones del comando chage:

Opción cortaOpción largaDescripción
-d--lastdayEstablece el día del último cambio de la contraseña
-E--expiredateEstablece la fecha de caducidad
-I--inactiveDeshabilita la cuenta tras X días de inactividad desde la fecha de caducidad
-l--listMuestra la información de la edad de la cuenta
-m--mindaysEstablece el número mínimo de días antes de cambiar la contraseña
-M--maxdaysEstablece el número máximo de días antes de cambiar la contraseña
-R--rootDirectorio en el que hacer chroot
-W--warndaysEstablece los días de aviso de expiración

Con el parámetro -l podemos ver información sobre las cuentas.


# chage -l pepe
Last password change                                    : Apr 18, 2020
Password expires                                        : never
Password inactive                                       : never
Account expires                                         : never
Minimum number of days between password change          : 0
Maximum number of days between password change          : 90
Number of days of warning before password expires       : 5

Más información sobre el comando chage: https://linux.die.net/man/1/chage

Cumplimiento de directivas de seguridad en la calidad de contraseñas seguras de usuarios Link to heading

Al igual que en sistemas Windows es necesario implementar un mínimo cumplimiento de seguridad en el hardening de contraseñas estableciendo directivas a nivel de dominio para definir la complejidad de contraseña, longitud mínima, días de expiración, contraseñas no repetidas respecto a las anteriores, etc.

En sistemas Linux, aplicaciones de terceros o servicios exógenos que hacen uso de usuarios Linux, también es necesario establecer políticas de seguridad estrictas al tratarse de cuentas que pueden tener el mismo riesgo de ser vulneradas y poder pivotar a otros sistemas que sean de un mayor interés para los atacantes.

Lógicamente también dependerá de la infraestructura y su ecosistema. En entornos de producción no sería conveniente provocar la desactivación o bloqueo de una cuenta de usuario y dejar inoperativo un servicio crítico que dependa de dicha cuenta. Independientemente de estos casos es recomendable y diría que necesario establecer este tipo de criterios para garantizar y elevar un poco más las medidas de seguridad de los sistemas de la empresa.

Se pueden establecer políticas por defecto en el momento de creación de nuevas cuentas en el sistema, sin la necesidad de usar chage nominalmente a cada usuario como vimos anteriormente.

login.defs Link to heading

Se trata de un fichero de texto situado en /etc/login.defs de forma nativa se encuentra en cualquier entorno Linux. Se definen las políticas de gestión de contraseñas para la creación de nuevos usuarios. También podemos establecer otras directivas como el valor umask por defecto, si el usuario tendrá un home para él si no se le especifica en su creación (useradd -m), cambiar la secuencia de ID (por defecto suelen ser 1000 y algo para usuarios normales), mensaje de bienvenida del inicio de sesión del usuario (motd_file), etc.

El motivo de este artículo será enfocado únicamente a las que tengan que ver con las políticas de contraseñas.

Algunas de las directivas más comunes que podemos establecer:

DirectivaDescripción
PASS_MAX_DAYSNúmero máximo de días que se puede usar una contraseña
PASS_MIN_DAYSNúmero mínimo de días permitido entre cambios de contraseña
PASS_WARN_AGENúmero de días de advertencia antes de que caduque una contraseña
PASS_MIN_LEN / PASS_MAX_LENNúmero mínimo y máximo de caracteres que debe tener la contraseña
PASS_ALWAYS_WARNAdvierte sobre contraseñas débiles
PASS_CHANGE_TRIESNúmero máximo de intentos de cambiar la contraseña si se rechaza por ser demasiado “fácil”
ENCRYPT_METHODTipo de cifrado de la contraseña (SHA256 $5$ o SHA512 $6$)
LOGIN_RETRIESNúmero máximo de reintentos de inicio de sesión si la contraseña es incorrecta
LOGIN_TIMEOUTTiempo máximo en segundos para iniciar sesión

Más información sobre login.defs: https://linux.die.net/man/5/login.defs

pam_cracklib y pam_pwquality Link to heading

Si queremos tener un mayor nivel de detalle en la personalización de las directivas en la complejidad de contraseñas para las cuentas de usuarios sería más interesante hacer uso de los módulos PAM (Pluggable Authentication Modules) pam_cracklib y pam_pwquality.

pwquality es una versión más actual y mejorada de cracklib. pwquality llama a una rutina cracklib para verificar si la contraseña es parte de un diccionario si este se especifica en la directiva dictpath. En este caso haré referencia siempre a pam_pwquality.

En entornos RHEL/Centos se incorpora de forma nativa, es compatible con derivados Debian pero será necesario instalarlo.

sudo apt install -y libpam-cracklib libpam-pwquality libpwquality-tools

Una vez instalado el módulo de libpwquality podemos editar sus opciones en el fichero /etc/security/pwquality.conf.

Opciones para definir las políticas:

OpciónDescripción
difokCaracteres en la nueva contraseña que no deben estar presentes en la anterior
minlenTamaño mínimo aceptable para la nueva contraseña
dcreditCrédito máximo por tener dígitos en la nueva contraseña
ucreditCrédito máximo por tener letras mayúsculas
lcreditCrédito máximo por tener letras minúsculas
ocreditCrédito máximo por tener otros caracteres
minclassNúmero mínimo de clases de caracteres requeridas
maxrepeatNúmero máximo de caracteres repetidos
maxclassrepeatNúmero máximo de caracteres consecutivos en la misma clase
gecoscheckVerifica si palabras (>3 caracteres) del campo GECOS del usuario están contenidas en la contraseña
dictpathRuta a los diccionarios de cracklib
badwordsLista de palabras (separadas por espacios) que no deben incluirse en la contraseña

Sistema de créditos, valores negativos y clases en pwquality Link to heading

Créditos Link to heading

Para definir la calidad y complejidad de las contraseñas se utiliza un sistema de créditos. Esto es muy interesante, básicamente se obtienen créditos por la complejidad. Una contraseña más corta podría ser aceptable si es más compleja en otras formas.

Por ejemplo una contraseña “ahwouwtdye” podría pasar una prueba minlen = 10. Si dcredit se establece en 2, una contraseña “ahwouw12” pasaría la prueba porque obtendríamos 2 créditos por cada dígito, entonces 8 caracteres más 2 créditos se valoran como 10 caracteres. Esto dependerá de cómo se establezcan los parámetros ucredit, lcredit, dcredit y ocredit.

Valores negativos Link to heading

Establecer valores de créditos negativos significa que debe tener al menos ese tipo de carácter. Por ejemplo, establecer dcredit a -1 significaría que debe incluir al menos un dígito para que se acepte una contraseña. Es decir, no se trata de una suma de créditos sino de un requerimiento obligatorio.

Clases (minclass) Link to heading

Otra configuración interesante es minclass. Determina cuántas clases diferentes de caracteres se deben usar para que una contraseña sea aceptable. Hay 4 tipos de clases: minúsculas, mayúsculas, dígitos, caracteres especiales (símbolos o signos).

Por ejemplo, un minclass = 2 exige que una contraseña contenga la combinación de dos tipos de clases. Ya sean mayúsculas o minúsculas, mayúsculas y caracteres especiales, minúsculas y dígitos, etc. Lo mismo pasaría si se establece a minclass = 4, la contraseña debería contener una combinación de las cuatro clases.

También se puede establecer un límite al número máximo de caracteres de cualquier tipo de clase. Por ejemplo, con el parámetro maxclassrepeat = 4 indicamos que las contraseñas no pueden contener más de 4 minúsculas, mayúsculas, dígitos y otros caracteres especiales.

Más información sobre el uso de directivas del fichero de pwquality: https://linux.die.net/man/8/pam_pwquality

Probando el cumplimiento de requisitos con varias contraseñas.


# passwd pepe
Nueva contraseña:
CONTRASEÑA INCORRECTA: La contraseña tiene menos de 8 caracteres.

# passwd pepe
Nueva contraseña:
CONTRASEÑA INCORRECTA: La contraseña no supera la verificación de diccionario - No contiene suficientes caracteres DIFERENTES.

# passwd pepe
Nueva contraseña:
CONTRASEÑA INCORRECTA: La contraseña no supera la verificación de diccionario - Es demasiado simple/sistemática.

# passwd pepe
Nueva contraseña:
CONTRASEÑA INCORRECTA: La contraseña contiene más de 3 caracteres de la misma clase en forma consecutiva

pwscore Link to heading

pwquality (libpwquality-tools) dispone de una herramienta llamada pwscore que podemos usar para comprobar la complejidad de una contraseña en base a los criterios establecidos en pwquality. Algunos ejemplos de uso.


# echo 123 | pwscore
Falló la comprobación de calidad de la contraseña:
 La contraseña tiene menos de 8 caracteres

# echo abc123.. | pwscore
Falló la comprobación de calidad de la contraseña:
 La contraseña no supera la verificación de diccionario - Es demasiado simple/sistemática.

# echo L3h5as/2a$-ls=72 | pwscore
100

Conclusiones Link to heading

Estos módulos PAM también pueden comprobar si las contraseñas son un palíndromo o si solamente se cambió un solo carácter de mayúscula a minúscula o viceversa, si las contraseñas anteriores son similares o ya han sido usadas anteriormente, si contiene el nombre del usuario, o si hay alguna coincidencia con el campo passwd GECOS (campo de comentarios) de /etc/passwd. Dependiendo del nivel de complejidad que se establezca sería difícil establecerse una mala contraseña.

En definitiva, ofrecen una serie de comprobaciones que ayudan a garantizar un nivel de robustez y calidad de las contraseñas. Así como en la mayoría de compañías se aplican para entornos Windows, intentar aplicar estas políticas de seguridad en sistemas Linux y que no habiten en el olvido.

Saludos!