Pam
pam es un conjunto de librerías, que proporciona una api para autenticar aplicaciones (servicios), los clientes de pam, son las aplicaciones que tienen que autenticar.
PAM (plugable autenticable mode), la gracia es que es modular el programa(aplicación) utiliza pam y este ya utiliza la autentificación que se le haya asignado (contraseña, huella dactilar, etc..).
Una aplicación pam aware, es una aplicación que sabe que hará autentificación usando pam, en el archivo /etc/pam.conf
Como saber que una aplicación es pam aware, mirando si en sus requisitos existe algún modulo pam.
Cualquier programa que sea pam aware, y no tenga un fichero especifico en /etc/pam.d
, se le aplica other, que deniega todo por defecto.
ldd
list dinamic dependencies. listar dependencias.
➜ ldd /usr/bin/chfn
linux-vdso.so.1 (0x00007ffc98950000)
libpam.so.0 => /lib/x86_64-linux-gnu/libpam.so.0 (0x00007fe8f2566000)
libpam_misc.so.0 => /lib/x86_64-linux-gnu/libpam_misc.so.0 (0x00007fe8f2561000)
....
Directorios de configuración
/etc/pam.d/
/etc/pam.conf
ruta modulos de pam instalados /usr/lib64/security/
Ejemplo archivo pam
#%PAM-1.0
#type control argument
auth sufficient pam_rootok.so
auth include system-auth
account include system-auth
password include system-auth
session include system-auth
file.so la extensión .so
significa (shared object), objeto compartido, y este puede tener, o no argumentos.
[root@pam pam.d]# cat system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_unix.so try_first_pass nullok
auth required pam_deny.so
account required pam_unix.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so
Types
Pam tiene 4 types diferentes: auth, account, password, session
Hay que saber diferenciar:
auth
autentificación, demostrar quien soyautz
a que me da derecho mi autentificación
auth
autenticación de usuario, quien soy.
account
tengo permiso para modificar
password
reglas para cambiar pasword
session
cosas a hacer al iniciar y cerrar sesión
importante: pam no es un servicio, al hacer un cambio en los archivos es inmediato
#%PAM-1.0
auth optional pam_echo.so [auth: %h %s %t %u]
auth required pam_permit.so
auth sufficient pam_unix.so
account optional pam_echo.so [auth: %h %s %t %u]
account sufficient pam_permit.so
suficient
si da cierto ya vale para la autentificación, en caso que de falso se ignora
Controls
La opción de controls, es compleja, tiene echo unos alias donde agrupan una serie de opciones predefinidas mas habituales.
ejemplo:
required
[success=ok new_authtok_reqd=ok ignore=ignore default=bad]
requisite
[success=ok new_authtok_reqd=ok ignore=ignore default=die]
sufficient
[success=done new_authtok_reqd=done default=ignore]
optional
[success=ok new_authtok_reqd=ok default=ignore]
-
ignore
: ignora esta opción -
bad
: marca como fallo y sigue evaluando -
die
: marca como fallo y no evalúes más -
ok
: marca como resultado positivo y sigue avaluando -
done
: resultado positivo y no evalúes más opciones -
N
numero de casillas a saltar -
reset
resetea valores anteriores
Predefinidos
required
Esta opción siempre tendrá que dar cierto, si da falso, fallara pero sigue preguntando la siguiente opción.
requisite
esta opción tiene que dar cierto, si da falso, cierra, no pasa a la siguiente opcion.
suficient
Si da cierto ya vale para la autentificación, en caso que de falso se ignora
optional
Opciones que intentara hacer, el resultado de los módulos en este control, no afectara a no ser que sea el único a evaluar
include
Incluir otros módulos de reglas existentes como si estuvieran en el mismo archivo
substack
llama a otro archivo y devuelve true o false, según la tabla de reglas.
Ejemplo include, subsrack:
En el caso siguiente substack llama al archivo proves, devuelve true, pasa a la siguiente regla y pide contraseña pam_unix.so . Si cambiamos substack por include, include le el archivo proves y como el sufficient da true, ya lo da por valido, no pasa a la siguiente regla y no pide contraseña.
En el caso de que substack devuelva false, seguirá preguntando reglas pero nunca dará positiva la acción.
/etc/pam.d/chfn
#%PAM-1.0
auth optional pam_echo.so
auth substack proves
auth required pam_unix.so
account optional pam_echo.so
account sufficient pam_permit.so
/etc/pam.d/proves
#%PAM-1.0
auth sufficient pam_permit.so
Argumentos
Manejo de contraseñas
Los argumentos tipo pam_unix.so, pam_ldap.so, pam_mount.so, etc...
que requiere insertar contraseña, tienen diferentes atributos para gestionarlas.
-
Si no tiene atributos se pedirá contraseña.
-
try_first_pass
si se a introducido una contraseña anteriormente la hace servir, en el caso contrario la pide. -
use_first_pass
usa la contraseña introducida anteriormente, si no se ha introducido ninguna antes, no usara ninguna. -
nullok
permite acceso a usuarios sin contraseña.
password requisite pam_pwquality.so
establece las reglas para definir condiciones contraseñas
/etc/securitt/pwquality.conf
archivo de condiciones.
Restricciones
pam_succeed_if.so
aplica restricciones
auth required pam_succeed_if.so user = pere
auth required pam_succeed_if.so user != “pere”
auth required pam_succeed_if.so uid > 1000
Otra manera de restringir es crear un control propio. En el siguiente ejemplo, si el usuario es uid=1001
saltara una linea y se le denegara el acceso, en caso contrario se ignorara pam_succed_if
y se evaluara la siguiente linea.
auth [success=1 default=ignore] pam_succeed_if.so debug uid = 1001
auth sufficient pam_permit.so
auth sufficient pam_deny.so
pam_time.so
aplica restricciones, en condiciones en torno al tiempo. Solo funciona en account y funciona junto al archivo /etc/security/time.conf
bloquear a local1 de 8h a 24h toda la semana
services;ttys;users;times
chfn;*;local1;Al0800-2400
todas las combinaciones aceptadas son: Mo Tu We Th Fr Sa Su Wk Wd Al, donde Al son todos, Wk de lunes a viernes, Wd fin de semana.
Dos dias repetidos se anulan MoMo = ninguno, y MoWk = dias laborables menos lunes, AlFr = todos los dias excepto viernes.
El formato de hora es un rango de HHMM-HHMM en modo 24h
Homedir
pam_mkhomedir.so
indica que al iniciar sesión un usuario, a de crear, si no lo tiene, directamente el home de dicho usuario, por defecto lo creara con las directrices de skel, a no ser que se le indique lo contrario.
system-auth
session required pam_mkhomedir.so silent umask=0007
Montajes
Pam_mount permite crear puntos de montaje, de diferentes servicios . pam_mount.so
tiene que estar en auth y session con el control opcional, a de estar antes del sufficient o del included. Para definir los puntos de montaje utiliza el archivo /etc/security/pam_mount.conf.xml
auth optional pam_mount.so
auth sufficient pam_ldap.so use_first_pass
auth required pam_unix.so use_first_pass
account sufficient pam_ldap.so
session optional pam_mount.so
un container para poder hacer mounts tienes que poner la opción --privileged
en el run
diferentes tipos de montaje.
# tmpfs
<volume user="*" fstype="tmpfs" mountpoint="~/tmp"
options="size=100M,uid=%(USER),mode=0775" />
# nfs
<volume user="*" fstype="nfs" server="fileserver" path="/home/%(USER)" mountpoint="~" />
# sshfs
<volume user="*" fstype="fuse" path="sshfs#%(USER)@fileserver:" mountpoint="~" />
# smbfs
<volume user="user" fstype="smbfs" server="krueger" path="public"
mountpoint="/home/user/krueger" />
modulos pam
/usr/lib64/security/
/etc/exports
/usr/share/man *(ro,sync)
/usr/share/doc *(ro,sync)
exportfs -s
mount -t nfs 172.17.0.1:/usr/share/man /mnt
Ejemplo system-auth para ldap
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth optional pam_mount.so
auth sufficient pam_unix.so try_first_pass nullok
auth sufficient pam_ldap.so try_first_pass
auth required pam_deny.so
account sufficient pam_unix.so
account sufficient pam_ldap.so
account required pam_deny.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so try_first_pass use_authtok nullok sha512 shadow
password sufficient pam_ldap.so try_first_pass
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_mkhomedir.so
session optional pam_mount.so
session sufficient pam_unix.so
session sufficient pam_ldap.so
Authconfig
Es una manera de modificar el archivo system-auth
automáticamente, pasando-le una serie de parámetros que los encontraremos en authconfig --help
y man authconfig
.
authconfig --enableshadow --enablelocauthorize \
--enableldap \
--enableldapauth \
--ldapserver='ldapserver' \
--ldapbase='dc=edt,dc=org' \
--enablemkhomedir \
--updateall
enableldap
: modifica los archivosnsswitch.conf, nslcd.conf
para tener acceso al servidor ldap.enableldapauth
: añade las lineaspam_ldap.so
en el archivosystem-auth
enablemkhomedir
: añadepam_mkhomedir.so
asystem-auth
Aplicación PamAware
https://pypi.python.org/pypi/python-pam/
En ocasiones queremos que alguna aplicación autentifique usuarios del sistema. Python tiene su modulo pam python-pam, python3-pam
, que se puede instalar tanto con pip como con dnf.
Ejemplo autentificación con el sistema, si es correcta muestra un rango del 1 al 10.
pamaware.py
#!/usr/bin/python
import pam
p=pam.pam()
userName=raw_input("Nom usuari: ")
userPasswd=raw_input("Passwd: ")
p.authenticate(userName, userPasswd)
print('{} {}'.format(p.code,p.reason))
if p.code == 0:
for i in range(1,11):
print i,
else:
print "Error autenticacio"
# python pamaware.py
Nom usuari: marti
Passwd: marti
10 User not known to the underlying authentication module
Error autenticacio
# python pamaware.py
Nom usuari: pere
Passwd: kaka
7 Authentication failure
Error autenticacio
# python pamaware.py
Nom usuari: pere
Passwd: pere
0 Success
1 2 3 4 5 6 7 8 9 10
Creación modulo pam
documentación
- https://pypi.python.org/pypi/python-pam/1.8.1
- http://stackoverflow.com/questions/5286321/pam-authentication-in-python-without-root-privileges
Pam python
- https://atlee.ca/software/pam/index.html
Python Pam
- http://pam-python.sourceforge.net/
Para la creación de un modulo python, se necesita descargar y compilar el ejecutable pam_python.so
.
Este paquete tiene sus dependencias que instalamos a continuación.
tar xvzf pam-python-1.0.6.tar.gz
dnf -y install sphinx python3-sphinx python2-sphinx gcc
dnf -y install pam-devel
dnf -y install redhat-rpm-config
dnf -y install python-devel
## editar línia 201 de: /usr/include/features.h:
# he canviat 700 per 600 en la línia # define _XOPEN_SOURCE 700
make
cp src/pam_python.so /usr/lib64/security/.
Una vez con el ejecutable del modulo en su sitio ya podemos crear nuestro archivo pam. para la prueba modifico el archivo /etc/pam.d/chfn
#%PAM-1.0
auth optional pam-echo.so [ auth ------- ]
auth sufficient pam_python.so /opt/docker/pam_mates.py
account optional pam-echo.so [ account ------- ]
account sufficient pam_python.so /opt/docker/pam_mates.py
password include pam_deny.so
session include pam_deny.so
y ubico en /opt/docker
mi programa pam_mates.py
# pam_mates.py
# Validar lusuari realitzant una pregunta de matemtiques
def pam_sm_authenticate ( pamh, flags, argv):
print "Quant fan 3*2?"
resposta=raw_input()
if int(resposta) == 6:
return pamh.PAM_SUCCESS
else:
return pamh.PAM_AUTHTOK_ERR
def pam_sm_setcred (pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_acct_mgmt ( pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_open_session ( pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_close_session (pamh, flags, argv):
return pamh.PAM_SUCCESS
def pam_sm_chauthtok (pamh, flags, argv):
return pamh.PAM_SUCCESS
Este programa se a echo a partir de copiar el ejemplo
pam_permit.py
de la documentación de pam_python. http://pam-python.sourceforge.net/examples/
Este ejemplo muestra el resultado del programa, si el usuario acierta la respuesta matemática, se le dejara cambiar el chfn
$ chfn anna
Changing finger information for anna.
Name []: 2
Office []: 2
Office Phone []: 2
Home Phone []: 2
auth -----------------
Quant fan 3*2?
6
account --------------
Finger information changed .