目录

PAM 介绍

linux下PAM模块全称是Pluggable Authentication Module for linux(可插入式授权管理模块),该由Sun公司提供,在Linux中,PAM是可动态配置的,本地系统管理员可以自由选择应用程序如何对用户进行身份验证。PAM应用在许多程序与服务上,比如登录程序(login、su)的PAM身份验证(口令认证、限制登录),passwd强制密码,用户进程实时管理,向用户分配系统资源等。

PAM的配置文件位置 /etc/pam.conf,也可以在/etc/pam.d/文件夹下配置单独的文件,当存在/etc/pam.d文件夹时,Linux-PAM将会使用/etc/pam.d文件夹下的配置文件而忽略/etc/pam.conf配置文件。

配置语法格式

  1. pam.conf配置文件中,配置内容写在一行内,也可以以““作为连接符将配置内容写在多行;
  2. pam.conf以空格作为分割标记,#代表标注信息;
  3. “-”如果在配置语句前面加上该符号,在系统登录时如果该模块未被正确加载,不会将该事件记录到系统日志中,即“-”表示可选项。
#直接在/etc/pam.conf中
service  type   control   module-path module-arguments
服务名称 类型   控制      模块路径    模块参数

如果配置文件放置在/etc/pam.d文件夹下,则配置文件中没有service选项配置段,且配置文件的名字为service名字,文件名必须小写,配置语法区分大小写,配置规则格式为:

#/etc/pam.d/下
type   control   module-path module-arguments
类型   控制      模块路径    模块参数

type类型

类型 说明
account manager(account)提供账户服务验证,如账户密码是否过期,是否对该账户提供服务.
authentication manager(auth)负责对用户进行认证并建立用户凭证;通常该模块通过交互式方
法进行认证,比如你应当输入密码证明你是你,但并非所有的认证都是该类型.
password manager(password)进授权认证机制进行更新,如更改密码.
session manager(session)当开启一个新会话时,该模块负责处理会话的准备任务,而当关闭某一
个会话时,该模块负责善后工作,如卸载该用户home目录。

control控制

control分为简单和复杂两种语法结构,简单语法中仅有一个关键字,而复杂语法通过[ ]引入[value=action]选项

control简单语法选项

选项 说明
required当使用此关键字的PAM模块验证失败,最终会导致PAM-API返回失败,但是会等到后续模块全部被验证后才会返回失败
requisite该关键字与required使用方法类似,但是当PAM验证失败时,requisite会立刻向调用程序或父PAM桟返回失败值;该关键字可以防止攻击者获得系统已存在用户信息,通常该关键字用在重要的系统环境中
sufficient如果该模块验证成功,而且该模块前无required模块验证失败,sufficient关键字将会向调用程序或者父PAM栈返回成功值而不会再调用后续的验证模块;当调用sufficient模块失败,PAM模块不会受sufficient模块失败影响,将会继续执行验证。
optional当配置文件中仅有service+optional这一条规则时,optional模块才会起作用.
include将指定配置文件中所有的type类型作为参数包含在此控制语句中.
substack将指定配置文件中type作为参数包含在此控制语句中,和Include不同的是,在substack中完成任务或者die,只会影响substack内控制命令,不会影响完整的stack桟.

control复杂语法

[value1=action1 value2=action2 …]

valueN代表对应模块中控制语句的返回值,可以是下面的值:success,open_err,symbol_err,service_err,system_err,buf_err,perm_denied,default等,其中default表示所有未被显式提到的所有值

PAM所有的错误信息列表在 /usr/include/security/_pam_types.h文件夹中

actionN可以使下列值中的某一个:

返回值 说明
ignore当在模块桟中使用该参数时,该模块桟的返回值不会影响应用程序获得返回值。
bad当使用bad关键字,证明模块桟的返回值代表失败;当该模块式PAM桟中第一个模块时,该模块的状态将会在整个PAM桟中使用。
die和bad关键字作用相同,当使用该动作关键时,会立刻终止模块桟,PAM会立刻返回到调用的应用程序中。
ok该动作指示将PAM的返回值直接用于所有的模块桟中,即如果前一个桟返回的状态是PAM_SUCCESS,'OK‘中的值会重写返回值;如果返回的是失败,则此'OK'的值不会重写返回值。
done和'OK'动作基本相同,但是PAM会立刻返回到应用程序当中。
reset清空所有模块桟的状态值并以下一个模块进行验证。
N和'OK'副作用相同,但是会跳过接下来的N个模块桟,不允许使用'0'(在某些情况是使用'0'和'OK'作用类似)。
四个关键字required;requisite;sufficient;optional和以下语句有相同作用
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]

module-path

模块路径可以使应用程序使用的PAM模块的文件名,也可是是默认模块的相对路径名:/lib/security 或者/lib64/security

module-arguments

模块参数是以空格作为分隔符的列表,可以用来指定PAM特殊的动作,如果需要在参数中包含空格,需要使用”[ ]”,当需要在语法中使用[]时,需使用“”,如 [..[..]..]→..[..]..;语法中的任何一个错误都会导致验证失败,而且会被记录到系统日志中

pam module

[root@centos76 ~]# ls /lib64/security/
pam_access.so    pam_faildelay.so  pam_listfile.so    pam_pwhistory.so       pam_succeed_if.so   pam_unix_session.so
pam_cap.so       pam_faillock.so   pam_localuser.so   pam_pwquality.so       pam_systemd.so      pam_unix.so
pam_chroot.so    pam_filter        pam_loginuid.so    pam_rhosts.so          pam_tally2.so       pam_userdb.so
pam_console.so   pam_filter.so     pam_mail.so        pam_rootok.so          pam_time.so         pam_warn.so
pam_cracklib.so  pam_ftp.so        pam_mkhomedir.so   pam_securetty.so       pam_timestamp.so    pam_wheel.so
pam_debug.so     pam_group.so      pam_motd.so        pam_selinux_permit.so  pam_tty_audit.so    pam_xauth.so
pam_deny.so      pam_issue.so      pam_namespace.so   pam_selinux.so         pam_umask.so
pam_echo.so      pam_keyinit.so    pam_nologin.so     pam_sepermit.so        pam_unix_acct.so
pam_env.so       pam_lastlog.so    pam_permit.so      pam_shells.so          pam_unix_auth.so
pam_exec.so      pam_limits.so     pam_postgresok.so  pam_stress.so          pam_unix_passwd.so

Practise

文件 功能说明
/etc/pam.d/login 控制台(管理终端)对应配置文件
/etc/pam.d/sshd 登录对应配置文件
/etc/pam.d/system-auth 系统全局配置文件

TroubleShooting

T1

cat /var/log/secure

Mar  5 14:49:06 centos76 useradd[5058]: new group: name=testdel, GID=1003
Mar  5 14:49:06 centos76 useradd[5058]: new user: name=testdel, UID=1003, GID=1003, home=/home/testdel, shell=/bin/bash
Mar  5 14:49:17 centos76 passwd: pam_unix(passwd:chauthtok): password changed for testdel
Mar  5 14:50:29 centos76 su: pam_unix(su:session): session opened for user testdel by root(uid=0)
Mar  5 14:50:32 centos76 unix_chkpwd[5109]: check pass; user unknown
Mar  5 14:50:35 centos76 unix_chkpwd[5110]: check pass; user unknown
Mar  5 14:50:35 centos76 unix_chkpwd[5110]: password check failed for user (root)
Mar  5 14:50:35 centos76 su: pam_unix(su-l:auth): authentication failure; logname=root uid=1003 euid=1003 tty=pts/0 ruser=testdel rhost=  user=root
Mar  5 14:50:35 centos76 su: pam_succeed_if(su-l:auth): requirement "uid >= 1000" not met by user "root"
Mar  5 14:50:41 centos76 su: pam_unix(su:session): session closed for user testdel
#出现场景,
[root@centos76 ~]# chmod u-s /bin/su 
[root@centos76 ~]# ls -alh /bin/su
-rwxr-xr-x 1 root root 32K Dec  3 01:46 /bin/su
#默认权限为
[root@ ~]# ls -alh /bin/su
-rwsr-xr-x 1 root root 32K Dec  3 01:46 /bin/su
[root@centos76 ~]# chmod u+s /bin/su 
#还原权限后,正常su -

问题2_模块参数错误

如高亮标注,问题服务器文件 /etc/pam.d/system-auth-ac 加入了错误粘贴的参数[补,默认的文件中没有此行,其它行一致。],并未去验证。直到后期的某一天禁用root登陆,通过普通用户切换到root时:su -切换时提示 su Module not found 。修改为第2行正确的之后,su - 正常使用。 本问题中引入的模块为pam_tally2.so 具体报错

#报错中提示无法加载模块(所有的参数都因复制粘贴错误而被当作一个模块名了):/usr/lib64/security/pam_tall2.soonerr=faildeny=5

Feb 25 17:25:45 centos77 su: PAM unable to dlopen(/usr/lib64/security/pam_tall2.soonerr=faildeny=5): /usr/lib64/security/pam_tall2.soonerr=faildeny=5: cannot open shared object file: No such file or directory
Feb 25 17:25:45 centos77 su: PAM adding faulty module: /usr/lib64/security/pam_tall2.soonerr=faildeny=5
Feb 25 17:25:50 centos77 su: pam_succeed_if(su-l:auth): requirement "uid >= 1000" not met by user "root"
Feb 25 17:29:39 centos77 su: PAM unable to dlopen(/usr/lib64/security/pam_tall2.soonerr=faildeny=5): /usr/lib64/security/pam_tall2.soonerr=faildeny=5: cannot open shared object file: No such file or directory
Feb 25 17:29:39 centos77 su: PAM adding faulty module: /usr/lib64/security/pam_tall2.soonerr=faildeny=5
Feb 25 17:29:46 centos77 su: pam_succeed_if(su-l:auth): requirement "uid >= 1000" not met by user "root"

#%PAM-1.0
auth    required    pam_tally2.so onerr=fail deny=5 even_deny_root unlock_time=300
#auth    required    pam_tall2.soonerr=faildeny=5 even_deny_rootunlock_time=300
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth        required      pam_env.so
auth        required      pam_faildelay.so delay=2000000
auth        sufficient    pam_unix.so nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 1000 quiet_success
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_localuser.so
account     sufficient    pam_succeed_if.so uid < 1000 quiet
account     required      pam_permit.so

password     requisite    pam_cracklib.so  retry=5    minlen=8    difok=3  ucredit=-1  lcredit=-1  dcredit=-1 ocredit=-1
password    requisite     pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password    sufficient    pam_unix.so sha512 shadow nullok try_first_pass use_authtok  remenber=5
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

Appendix