| 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配置文件。
| 配置语法格式 |
-如果在配置语句前面加上该符号,在系统登录时如果该模块未被正确加载,不会将该事件记录到系统日志中,即“-”表示可选项。
xxxxxxxxxx31#直接在/etc/pam.conf中2service type control module-path module-arguments3服务名称 类型 控制 模块路径 模块参数如果配置文件放置在/etc/pam.d文件夹下,则配置文件中没有service选项配置段,且配置文件的名字为service名字,文件名必须小写,配置语法区分大小写,配置规则格式为:
xxxxxxxxxx1#/etc/pam.d/下2type control module-path module-arguments3类型 控制 模块路径 模块参数
| 类型 | 说明 |
|---|---|
account manager(account) | 提供账户服务验证,如账户密码是否过期,是否对该账户提供服务. |
authentication manager(auth) | 负责对用户进行认证并建立用户凭证;通常该模块通过交互式方 法进行认证,比如你应当输入密码证明你是你,但并非所有的认证都是该类型. |
password manager(password) | 进授权认证机制进行更新,如更改密码. |
session manager(session) | 当开启一个新会话时,该模块负责处理会话的准备任务,而当关闭某一 个会话时,该模块负责善后工作,如卸载该用户home目录。 |
control分为简单和复杂两种语法结构,简单语法中仅有一个关键字,而复杂语法通过[ ]引入[value=action]选项
| 选项 | 说明 |
|---|---|
| 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桟. |
[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] |
模块路径可以使应用程序使用的PAM模块的文件名,也可是是默认模块的相对路径名:/lib/security 或者/lib64/security
模块参数是以空格作为分隔符的列表,可以用来指定PAM特殊的动作,如果需要在参数中包含空格,需要使用”[ ]”,当需要在语法中使用[]时,需使用“”,如 [..[..]..]→..[..]..;语法中的任何一个错误都会导致验证失败,而且会被记录到系统日志中
xxxxxxxxxx121[root@centos76 ~]# ls /lib64/security/2pam_access.so pam_faildelay.so pam_listfile.so pam_pwhistory.so pam_succeed_if.so pam_unix_session.so3pam_cap.so pam_faillock.so pam_localuser.so pam_pwquality.so pam_systemd.so pam_unix.so4pam_chroot.so pam_filter pam_loginuid.so pam_rhosts.so pam_tally2.so pam_userdb.so5pam_console.so pam_filter.so pam_mail.so pam_rootok.so pam_time.so pam_warn.so6pam_cracklib.so pam_ftp.so pam_mkhomedir.so pam_securetty.so pam_timestamp.so pam_wheel.so7pam_debug.so pam_group.so pam_motd.so pam_selinux_permit.so pam_tty_audit.so pam_xauth.so8pam_deny.so pam_issue.so pam_namespace.so pam_selinux.so pam_umask.so9pam_echo.so pam_keyinit.so pam_nologin.so pam_sepermit.so pam_unix_acct.so10pam_env.so pam_lastlog.so pam_permit.so pam_shells.so pam_unix_auth.so11pam_exec.so pam_limits.so pam_postgresok.so pam_stress.so pam_unix_passwd.so12
| 文件 | 功能说明 |
|---|---|
| /etc/pam.d/login | 控制台(管理终端)对应配置文件 |
| /etc/pam.d/sshd | 登录对应配置文件 |
| /etc/pam.d/system-auth | 系统全局配置文件 |
1cat /var/log/secure2Mar 5 14:49:06 centos76 useradd[5058]: new group: name=testdel, GID=10033Mar 5 14:49:06 centos76 useradd[5058]: new user: name=testdel, UID=1003, GID=1003, home=/home/testdel, shell=/bin/bash4Mar 5 14:49:17 centos76 passwd: pam_unix(passwd:chauthtok): password changed for testdel5Mar 5 14:50:29 centos76 su: pam_unix(su:session): session opened for user testdel by root(uid=0)6Mar 5 14:50:32 centos76 unix_chkpwd[5109]: check pass; user unknown7Mar 5 14:50:35 centos76 unix_chkpwd[5110]: check pass; user unknown8Mar 5 14:50:35 centos76 unix_chkpwd[5110]: password check failed for user (root)9Mar 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=root10Mar 5 14:50:35 centos76 su: pam_succeed_if(su-l:auth): requirement "uid >= 1000" not met by user "root"11Mar 5 14:50:41 centos76 su: pam_unix(su:session): session closed for user testdel12#出现场景,13[root@centos76 ~]# chmod u-s /bin/su14[root@centos76 ~]# ls -alh /bin/su15-rwxr-xr-x 1 root root 32K Dec 3 01:46 /bin/su16#默认权限为17[root@ ~]# ls -alh /bin/su18-rwsr-xr-x 1 root root 32K Dec 3 01:46 /bin/su19[root@centos76 ~]# chmod u+s /bin/su20#还原权限后,正常su -如高亮标注,问题服务器文件/etc/pam.d/system-auth-ac加入了错误粘贴的参数[补,默认的文件中没有此行,其它行一致。],并未去验证。直到后期的某一天禁用root登陆,通过普通用户切换到root时:su -切换时提示su Module not found。修改为第2行正确的之后,su - 正常使用。 本问题中引入的模块为pam_tally2.so 具体报错
xxxxxxxxxx81#报错中提示无法加载模块(所有的参数都因复制粘贴错误而被当作一个模块名了):/usr/lib64/security/pam_tall2.soonerr=faildeny=52 3Feb 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 directory4Feb 25 17:25:45 centos77 su: PAM adding faulty module: /usr/lib64/security/pam_tall2.soonerr=faildeny=55Feb 25 17:25:50 centos77 su: pam_succeed_if(su-l:auth): requirement "uid >= 1000" not met by user "root"6Feb 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 directory7Feb 25 17:29:39 centos77 su: PAM adding faulty module: /usr/lib64/security/pam_tall2.soonerr=faildeny=58Feb 25 17:29:46 centos77 su: pam_succeed_if(su-l:auth): requirement "uid >= 1000" not met by user "root"
xxxxxxxxxx261#%PAM-1.02auth required pam_tally2.so onerr=fail deny=5 even_deny_root unlock_time=3003#auth required pam_tall2.soonerr=faildeny=5 even_deny_rootunlock_time=3004# This file is auto-generated.5# User changes will be destroyed the next time authconfig is run.6auth required pam_env.so7auth required pam_faildelay.so delay=20000008auth sufficient pam_unix.so nullok try_first_pass9auth requisite pam_succeed_if.so uid >= 1000 quiet_success10auth required pam_deny.so11 12account required pam_unix.so13account sufficient pam_localuser.so14account sufficient pam_succeed_if.so uid < 1000 quiet15account required pam_permit.so16 17password requisite pam_cracklib.so retry=5 minlen=8 difok=3 ucredit=-1 lcredit=-1 dcredit=-1 ocredit=-118password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=19password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok remenber=520password required pam_deny.so21 22session optional pam_keyinit.so revoke23session required pam_limits.so24-session optional pam_systemd.so25session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid26session required pam_unix.so
| 附录引用 |
无