[TOC]
0x00 前言介绍 Q: 什么是PAM? 答:PAM 的全称为可插拔认证模块(Pluggable Authentication Modules:简称 PAM /pæm/
),Linux中的一种安全验证方式是基于模块化设计、具有可插入功能的一种独立于应用程序之外
的验证方式;设计的初衷是将不同的底层认证机制集中到一个高层次的API中,从而省去开发人员自己去设计和实现各种繁杂的认证机制的麻烦。 PAM 机制最初由 Sun 公司提出,并在其 Solaris 系统上实现,后来各个版本的 UNIX 以及 Linux 也陆续增加了对它的支持。
Q:为什么要使用PAM? 描述:服务器的系统安全确实是一件让用户头痛的事情,比如下面所列问题常规的安全措施并不能妥善地解决特别是在应用之中。
如何确保系统中使用应用程序或服务的用户确是用户本人?
如何给这些用户指定限制访问服务的时间段?
以及如何限制各种应用程序或服务对系统资源的使用率等等? 如果没有 PAM 认证功能只能写在各个应用程序中,一旦要修改某个认证方法,开发人员可能不得不重写程序,然后重新编译程序并安装;有了 PAM 认证的工作都交给 PAM ,程序主体便可以不再关注认证问题了“ PAM 允许你进来,那你就进来吧。” 在从RedHat系列发行版Linux 3.x(>=内核中)已经集成了PAM安全验证方式, 并且能够使用它来解决上面所示的相关问题;
PAM特点&功能:
给程序的开发人员提供一套统一的认证接口, 即应用程序可以不需要集成验证功能;
具有很大的灵活性可以通过它为应用程序自由选择需要使用的验证方式。
增强 Linux 服务器的安全性能。
Q: 如何使用PAM? 答:当 LINUX 服务器中的某个应用程序或服务需要使用 PAM 来进行验证时,只要此应用程序或服务支持 PAM 验证功能,就可以通过修改其相应的 PAM 配置文件(所有验证功能都是通过一些库文件来提供的
)来配置相应的验证方式,当重新启用些服务或应用程序时 PAM 模块就会通过其专用 API 来读取它的配置文件
,根据配置文件中的内容来提供相应的验证功能;
我们先用一个例子来直观感受一下 PAM:
su 是一个很常用的 Linux 命令,可以让我们从一个用户切换到另一个用户。我们都知道,当用户使用 root 账号登录时,su 到别的用户是不需要密码的,而从其他用户 su 到 root 则需要输入密码。在用 su 命令切换用户的过程中, su 做了两件事:认证(是否是 root、不是 root 的话是否有目标用户的密码)和启动相应的 Shell。
让我们来关注一下 su 的认证功能。按照正常的逻辑, su 的开发人员很可能会自己写出认证的功能:先判断是不是 root,是则判定认证通过;不是则要求用户输入目标账号的密码,匹配成功则认证通过,否则不通过。这套逻辑并不复杂,开发人员开发出来便是了。
过了几天,用户提出了这样的一个需求:运维团队都属于 wheel 组,能不能让 wheel 组的用户也能不输入密码而使用 su 切换?看起来也不是什么特别困难的需求,开发人员本可以满足就是了。但是如果再过几天,运维小张考虑到安全想要 su 有短信验证码功能,而用户小王为了方便测试想要一个完全不用密码的 su。认证需求的差异化越来越明显,开发人员的工作也变得越来越困难。
这时PAM 出现了对开发人员说:“认证的事情交给我,你只要告诉我你想做用户认证就好,余下的事情由我来解决,能不能通过由我来说了算。”它又对运维人员说:“你们来我这里编写你们想要的针对 su 的认证策略吧,我将充分保证功能的灵活。”
从此su 的开发人员可以专注地为用户启动 Shell 服务,而不需要关心用户认证的细节了;用户或复杂、或简单的认证需求也都得到了满足。真是皆大欢喜。
注意事项:
Linux系统下的应用程序如果需要得到PAM功能的支持,需要将支持PAM功能的代码集成到了源代码之中;如果你能够得到一个应用程序的原代码,你也可以自行将支持 PAM 的功能代码加入其中。
查看应用程序是否支持 PAM 验证功能,使用ldd命令进行查看动态链接库中有木有 libpam 和 libpam.misc
名称;1 2 ldd `which sshd` | grep "libpam"
PAM 不仅仅在用户登录时才发挥作用sudo命令,su命令,passwd命令
都会用到 PAM。前文中所有提及“登录”的地方都仅仅是举例,您完全可以用其他需要用户认证的服务(或者命令)去举例,从而更全面地理解 PAM。
[TOC]
0x00 前言介绍 Q: 什么是PAM? 答:PAM 的全称为可插拔认证模块(Pluggable Authentication Modules:简称 PAM /pæm/
),Linux中的一种安全验证方式是基于模块化设计、具有可插入功能的一种独立于应用程序之外
的验证方式;设计的初衷是将不同的底层认证机制集中到一个高层次的API中,从而省去开发人员自己去设计和实现各种繁杂的认证机制的麻烦。 PAM 机制最初由 Sun 公司提出,并在其 Solaris 系统上实现,后来各个版本的 UNIX 以及 Linux 也陆续增加了对它的支持。
Q:为什么要使用PAM? 描述:服务器的系统安全确实是一件让用户头痛的事情,比如下面所列问题常规的安全措施并不能妥善地解决特别是在应用之中。
如何确保系统中使用应用程序或服务的用户确是用户本人?
如何给这些用户指定限制访问服务的时间段?
以及如何限制各种应用程序或服务对系统资源的使用率等等? 如果没有 PAM 认证功能只能写在各个应用程序中,一旦要修改某个认证方法,开发人员可能不得不重写程序,然后重新编译程序并安装;有了 PAM 认证的工作都交给 PAM ,程序主体便可以不再关注认证问题了“ PAM 允许你进来,那你就进来吧。” 在从RedHat系列发行版Linux 3.x(>=内核中)已经集成了PAM安全验证方式, 并且能够使用它来解决上面所示的相关问题;
PAM特点&功能:
给程序的开发人员提供一套统一的认证接口, 即应用程序可以不需要集成验证功能;
具有很大的灵活性可以通过它为应用程序自由选择需要使用的验证方式。
增强 Linux 服务器的安全性能。
Q: 如何使用PAM? 答:当 LINUX 服务器中的某个应用程序或服务需要使用 PAM 来进行验证时,只要此应用程序或服务支持 PAM 验证功能,就可以通过修改其相应的 PAM 配置文件(所有验证功能都是通过一些库文件来提供的
)来配置相应的验证方式,当重新启用些服务或应用程序时 PAM 模块就会通过其专用 API 来读取它的配置文件
,根据配置文件中的内容来提供相应的验证功能;
我们先用一个例子来直观感受一下 PAM:
su 是一个很常用的 Linux 命令,可以让我们从一个用户切换到另一个用户。我们都知道,当用户使用 root 账号登录时,su 到别的用户是不需要密码的,而从其他用户 su 到 root 则需要输入密码。在用 su 命令切换用户的过程中, su 做了两件事:认证(是否是 root、不是 root 的话是否有目标用户的密码)和启动相应的 Shell。
让我们来关注一下 su 的认证功能。按照正常的逻辑, su 的开发人员很可能会自己写出认证的功能:先判断是不是 root,是则判定认证通过;不是则要求用户输入目标账号的密码,匹配成功则认证通过,否则不通过。这套逻辑并不复杂,开发人员开发出来便是了。
过了几天,用户提出了这样的一个需求:运维团队都属于 wheel 组,能不能让 wheel 组的用户也能不输入密码而使用 su 切换?看起来也不是什么特别困难的需求,开发人员本可以满足就是了。但是如果再过几天,运维小张考虑到安全想要 su 有短信验证码功能,而用户小王为了方便测试想要一个完全不用密码的 su。认证需求的差异化越来越明显,开发人员的工作也变得越来越困难。
这时PAM 出现了对开发人员说:“认证的事情交给我,你只要告诉我你想做用户认证就好,余下的事情由我来解决,能不能通过由我来说了算。”它又对运维人员说:“你们来我这里编写你们想要的针对 su 的认证策略吧,我将充分保证功能的灵活。”
从此su 的开发人员可以专注地为用户启动 Shell 服务,而不需要关心用户认证的细节了;用户或复杂、或简单的认证需求也都得到了满足。真是皆大欢喜。
注意事项:
Linux系统下的应用程序如果需要得到PAM功能的支持,需要将支持PAM功能的代码集成到了源代码之中;如果你能够得到一个应用程序的原代码,你也可以自行将支持 PAM 的功能代码加入其中。
查看应用程序是否支持 PAM 验证功能,使用ldd命令进行查看动态链接库中有木有 libpam 和 libpam.misc
名称;1 2 ldd `which sshd` | grep "libpam"
PAM 不仅仅在用户登录时才发挥作用sudo命令,su命令,passwd命令
都会用到 PAM。前文中所有提及“登录”的地方都仅仅是举例,您完全可以用其他需要用户认证的服务(或者命令)去举例,从而更全面地理解 PAM。
0x01 基础配置 描述:在Linux发行版的系统中每个支持PAM验证的应用程序或者服务都一个与之对应的PAM的配置文件; 默认PAM 的各个模块路径: /lib/security/ 和 /lib64/security/
以动态库文件的形式存在文件名格式一般为pam_*.so(取决于操作系统位数); 默认PAM 配置文件路径:/etc/pam.conf(在时下的发行版可能没有)
或者 /etc/pam.d/
单个应用;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 ls -alh /etc/pam.d/ 总用量 112K -rw-r--r--. 1 root root 192 4月 1 12:51 chfn -rw-r--r--. 1 root root 192 4月 1 12:51 chsh -rw-r--r--. 1 root root 232 4月 1 11:59 config-util -rw-r--r--. 1 root root 287 8月 9 2019 crond lrwxrwxrwx. 1 root root 19 6月 2 14:15 fingerprint-auth -> fingerprint-auth-ac -rw-r--r--. 1 root root 702 6月 2 14:15 fingerprint-auth-ac -rw-r--r--. 1 root root 796 4月 1 12:51 login -rw-r--r--. 1 root root 154 4月 1 11:59 other -rw-r--r--. 1 root root 188 4月 1 11:57 passwd lrwxrwxrwx. 1 root root 16 6月 2 14:15 password-auth -> password-auth-ac -rw-r--r--. 1 root root 1.1K 6月 2 14:15 password-auth-ac -rw-r--r--. 1 root root 155 4月 1 12:07 polkit-1 lrwxrwxrwx. 1 root root 12 6月 2 14:15 postlogin -> postlogin-ac -rw-r--r--. 1 root root 330 6月 2 14:15 postlogin-ac -rw-r--r--. 1 root root 681 4月 1 12:51 remote -rw-r--r--. 1 root root 143 4月 1 12:51 runuser -rw-r--r--. 1 root root 138 4月 1 12:51 runuser-l lrwxrwxrwx. 1 root root 17 6月 2 14:15 smartcard-auth -> smartcard-auth-ac -rw-r--r--. 1 root root 752 6月 2 14:15 smartcard-auth-ac lrwxrwxrwx. 1 root root 25 6月 2 14:12 smtp -> /etc/alternatives/mta-pam -rw-r--r--. 1 root root 76 4月 1 12:08 smtp.postfix -rw-r--r--. 1 root root 904 8月 9 2019 sshd -rw-r--r--. 1 root root 540 4月 1 12:51 su -rw-r--r--. 1 root root 200 4月 1 12:37 sudo -rw-r--r--. 1 root root 178 4月 1 12:37 sudo-i -rw-r--r--. 1 root root 137 4月 1 12:51 su-l lrwxrwxrwx. 1 root root 14 6月 2 14:15 system-auth -> system-auth-ac -rw-r--r--. 1 root root 1.1K 6月 2 14:15 system-auth-ac -rw-r--r--. 1 root root 129 5月 12 23:45 systemd-user -rw-r--r--. 1 root root 84 10月 31 2018 vlock
pam 相关文件目录如下: 1 2 3 4 /etc/pam.conf /etc/pam.d/* /usr/lib/libpam.so.* /lib/security/pam_*.so
其中每行代表一个独立的验证方式每个配置文件可以由多种验证规则相互叠加而成
。 验证时 PAM-API 会按照从上往下的方式一一读取这些验证规则,并根据其中的控制标志做出相应的动作。
PAM配置文件特殊字符说明:
# 表示注释
。
每一行代表一条规则。但也可以用\
来放在行末,来连接该行和下一行。
例子的最后一行开头有一个短横线 - 意思是如果找不到这个模块,导致无法被加载时,这一事件不会被记录在日志中
。这个功能适用于那些认证时非必需的、安装时可能没被安装进系统的模块。
注意事项:
在进行应用或者系统相关服务的PAM配置的时候需要小心谨慎,由于规则验证有严格的上下顺序之分所以配置时候需要核验,因为一旦出错可导致系统或者功能不能正常访问;
不难看出/etc/pam.conf与/etc/pam.d/
类型的配置文件中的不同,文件夹形式的配置文件中只是没有了服务名称这一列服务名称已经是文件名
了。
1.配置简要说明 描述:要正常配置 PAM 配置文件就应当了解配置文件方法格式中每列的所包括的内容,下面是这些列的简短说明:
Type 列|Module-type 备注:主要用来指定需要验证的类型共有以下四种验证类型
;
auth: 主要负责验证使用者身份以及用户权限授予; 例如你的验证方式有很多比如一次性密码、指纹、虹膜等等,都应该添加在 auth 下以及比如赋给用户某个组的组员身份等等。
account: 主要负责在用户能不能使用某服务上具有发言权,但不负责身份认证; 例如验证帐户的此操作是否已经过期,权限多大,拥有此权限的时间期限是否已经过期等等
password: 主要负责和密码有关的工作; 例如控制密码的使用期限,重复输入的次数,密码锁定后的解禁时限以及保存密码的加密放方式等; (等保必须要做的)
session: 主要负责对每个会话进行跟踪和记录,例如记录的内容包括登录的用户名及登录的时间和次数等等
Control-flag 列|Control-flag 备注:主要用来控制在验证过程中动作和返回结果的方式, 简单的说用于定义各个认证模块在给出各种结果时 PAM 的行为,或者调用在别的配置文件中定义的认证流程栈;
它有两种类型的表达方式关键字模式
与“用方括号 [] 包含的“返回值=行为”模式
:
(1) 关键字模式下,有以下几种控制模式:
required
: 当使用此控制标志时,当验证失败时仍然会继续进行其下的验证过程,它会返回一个错误信息,但是由于它不会由于验证失败而停止继续验证过程,因此用户不会知道是哪个规则项验证失败;
requisite
: 与required 的验证方式大体相似,但是只要某个规则项验证失败则立即结束整个验证过程,并返回一个错误信息。使用此关键字可以防止一些通过暴力猜解密码的攻击,但是由于它会返回信息给用户,因此它也有可能将系统的用户结构信息透露给攻击者。
sufficient
: 只要有此控制标志的一个规则项验证成功,那么 PAM 构架将会立即终止其后所有的验证,并且不论其前面的 required 标志的项没有成功验证,它依然将被忽略然后验证通过。
optional
: 表明对验证的成功或失败都是可有可无的,所有的都会被忽略。(通常用于 session 类型
)
include
: 将其他配置文件中的流程栈包含在当前的位置,就好像将其他配置文件中的内容复制粘贴到这里一样。
substack
:运行其他配置文件中的流程,并将整个运行结果作为该行的结果进行输出。该模式和 include 的不同点在于认证结果的作用域:如果某个流程栈 include 了一个带 requisite 的栈,这个 requisite 失败将直接导致认证失败同时退出栈;而某个流程栈 substack 了同样的栈时,requisite 的失败只会导致这个子栈返回失败信号,母栈并不会在此退出。
(2) 复杂的控制标志能够让管理员可以指定在验证过程中发生某种事件时可以执行的动作, 复杂的可以使用方括号来嵌套控制标志并可在方括号中使用 value=action
的方式表达。
查看PAM中可用的Value列表值:/usr/include/security/_pam_types.h
有 success、user_unknown、new_authtok_reqd、default
等等数十种
1 2 3 4 5 6 7 8 9 10 11 auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so ignore:在一个栈中有多个认证条目的情况下,如果标记 ignore 的返回值被命中,那么这条返回值不会对最终的认证结果产生影响。 bad:标记 bad 的返回值被命中时,最终的认证结果注定会失败。此外,如果这条 bad 的返回值是整个栈的第一个失败项,那么整个栈的返回值一定是这个返回值,后面的认证无论结果怎样都改变不了现状了。 die:标记 die 的返回值被命中时,马上退出栈并宣告失败。整个返回值为这个 die 的返回值。 ok:在一个栈的运行过程中,如果 ok 前面没有返回值,或者前面的返回值为 PAM_SUCCESS,那么这个标记了 ok 的返回值将覆盖前面的返回值。但如果前面执行过的验证中有最终将导致失败的返回值,那 ok 标记的值将不会起作用。 done :在前面没有 bad 值被命中的情况下,done 值被命中之后将马上被返回,并退出整个栈。N(一个自然数):功效和 ok 类似,并且会跳过接下来的 N 个验证步骤。如果 N = 0 则和 ok 完全相同。 reset:清空之前生效的返回值,并且从下面的验证起重新开始。
PS:实际上关键字模式可以等效地用返回值=行为
模式来表示,具体的对应如下:1 2 3 4 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|Module-path 描述:用来为要验证的服务提供需要使用的验证模块,前我们说过引用的动态链接库处于 /lib/security/
或 /lib64/security/
目录中;
注意事项:
使用时如果模块在默认路径之中则只填写其完整的动态链接库名称,如要引用的模块不存在这两个默认的保存目录,就必需在模块的完整名称前加上完整的模块路径名/usr/lib/security/pam-test.so
Module-arguments|Arguments 描述:用来为引用的模块指定特殊的选项, 模块参数用空格与模块路径相隔。该参数将只和特定模块相关,因此某个模块的文档中一定包含其参数的信息。
注意事项:
如果需要在单个参数中使用空格可以将整个参数用方括号 [] 包裹起来, 当选项超过一行时用 \ 符号连接下一行;
2.常用模块说明 描述:要想掌握PAM的使用,就必须了解常用的PAM验证模块的作用,毕竟PAM 的具体验证功能都是由这些可插入的验证模块来完成的。 每个PAM验证模块的使用对象总是与PAM验证类型是相对应即(白话:动态链接库名称包含Type关键字相关关联的名称或者应用相关关键字
)1 2 3 4 5 6 $ls /usr/lib64/security/pam_access.so pam_debug.so pam_faildelay.so pam_group.so pam_listfile.so pam_motd.so pam_pwhistory.so pam_selinux_permit.so pam_succeed_if.so pam_tty_audit.so pam_unix_session.so pam_xauth.so pam_cap.so pam_deny.so pam_faillock.so pam_issue.so pam_localuser.so pam_namespace.so pam_pwquality.so pam_selinux.so pam_systemd.so pam_umask.so pam_unix.so pam_chroot.so pam_echo.so pam_filter pam_keyinit.so pam_loginuid.so pam_nologin.so pam_rhosts.so pam_sepermit.so pam_tally2.so pam_unix_acct.so pam_userdb.so pam_console.so pam_env.so pam_filter.so pam_lastlog.so pam_mail.so pam_permit.so pam_rootok.so pam_shells.so pam_time.so pam_unix_auth.so pam_warn.so pam_cracklib.so pam_exec.so pam_ftp.so pam_limits.so pam_mkhomedir.so pam_postgresok.so pam_securetty.so pam_stress.so pam_timestamp.so pam_unix_passwd.so pam_wheel.so
(1) pam_access|登陆访问限制模块 描述:它主要用于对访问进入管理,提供基于登录名、主机名或域名、公网 IP 地址或网络号,以及非网络登录时的 tty 名称的访问控制。 该验证模块一般与account 验证(Type)类型
一同使用, 它主要是根据 /etc/security/access.conf
配置文件中的内容,来进行相应的验证工作的;
配置文件说明: 1 2 3 4 5 cat /etc/security/access.conf permission (权限)字段可以用 + 即表示允许访问, - 禁止访问来表示相应的权限。 users/groups(用户或组)字段可以是一个或几个登录名、组名及 ALL (表示任何人)的一个清单。 origins (来源)字段可以是非网络登录时的 tty 名称、主机名、域名(以.开始)、主机地址、网络号(以.结束)、带有子网掩码的公网 IP 地址,以及 ALL 表示任何主机和 LOCAL 只要不包含.的所有字符)
基础示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 -:ALL EXCEPT root:tty1 -:ALL EXCEPT wheel shutdown sync:LOCAL -:wsbscaro wsbsecr wscosor wstaiwde:ALL +:root:192.168.200.1 192.168.200.4 192.168.200.9 +:root:192.168.201. +:root:.foo.bar.org +:john:2001:4ca0:0:101::/64 -:wheel:ALL EXCEPT LOCAL .win.tue.nl
注意事项:
1.如果 access.conf 文件不在缺省的 /etc/security/ 目录,你可以在其后使用 accessfile 参数指定自定义配置文件的绝对路径。
(2) pam_cracklib | 密码策略验证模块(old) 描述:该模块通常与password验证类型一起使用,通过插入 password 堆栈为特殊的应用提供可插入式密码强度性检测,它是PAM 配置接口的基本模块。 它的工作方式就是先提示用户输入密码,然后使用一个系统字典和一套规则来检测输入的密码是否不能满足强壮性要求。
温馨提示: 在最新的centos 8 与Ubuntu 22.04 中使用的是 pam_faillock 模块。
密码的强度检测分二次进行:
1.第一次只是检测密码是否是提供的对比字典中的一部分
2.如果检测结果是否定的,那么就会提供一些附加的检测来进一步检测其强度,(例如检测新密码中的字符占旧密码字符的比例,密码的长度,所用字符大小写状况,以及是否使用了特殊字符等等。
)
pam_cracklib 选项:
debug
:此选项表示将模块信息写入系统日志;
type=xxx
:此选项用来修改缺省的密码提示文本;(默认是 "New UNIX password: " and "Retype UNIX password: "
)
retry=N
: 定义用户在重试输入多少次密码后,返回一个错误信息,然后不准继续输入;(缺省一次)
difok=N:
此选项用来定义新密码中必须有几个字符要与旧密码不同,缺省是1/2以上的字符与旧密码不同时就OK;
maxlen=N
:此选项用来设置新密码的最大长度
minlen=N
:此选项用来设置新密码的最小长度。
dcredit=N
:此选项用来设定新密码中可以包含数字的最大数目。
ucredit=N
:此选项用来设定新密码中可以包含的大写字母的最大数目。
lcredit=N
:此选项用来设定新密码中可以包含的小写字母的最大数目。
ocredit=N
:此选项用来设定新密码中可以包含的特殊字符的最大数目。
minclass=N
:此选项用来规定新密码中的字符类别的最小数目,字符一般有四种类别:数字、大写字母、小写字母,以及特殊字符。
dictpath=/path/to/dict
: 指定 cracklib 目录路径。
use_authtok
:在某个与密码相关的验证模块后使用此选项,例如 pam_unix.so 验证模块,可以强迫此模块不提示输入密码而使用上面设置的另一种方式;
(3) pam_limit|资源服务限制模块 描述:该模块通常与session验证类别一同使用,它主要用来限制用户在会话过程中对系统资源的使用,即使 UID=0 的用户也受它的限制; 默认独立的配置文件: /etc/security/limits.conf 模块参数选项: conf
选项指定自定义配置文件即sudo:session required pam_limits.so conf=/etc/custom_limits.conf
配置文件格式如下:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 - <domain> : 可以是用户名、采用@group 语法的组名,还可以用通配符 * 来表示任何用户, 以及使用 “%” 通配符来只限制 maxlogins ,并可以采用 %group 的语法格式。 - <type > : - soft : 用来设置对系统资源的软限制,它允许用户所使用的系统资源可以在设定的硬限制值的规定范围来上下浮动 - hard : 用来设置对系统资源的硬限制,这些硬限制由超级用户设置,并由系统内核来执行。(`普通用户对系统资源的使用率不能超过设置的硬限制设定值`) - "-" : 表示无限制系统资源; - <item> <value> : 两者总是成对使用的,"Item" 表示某类具体的系统资源,而"Value" 就是"Item" 的值; * as * core * data * fsize * memlock * rss * stack * cpu * nproc * maxlogins * priority * sigpending * msqqueue * nofile * locks
1.上面item项目中是一些对系统资源使用情况非常有用的但它仅仅是一部分,可能随着内核的升级会加入某些新的item,你可以通过查看其帮助文档来了解;
2.十分注意用户的限制优先级要高于组的限制,如果你为一个组设置了某种系统资源限制,但是其中的某个用户设置了另一级别的系统资源限制,那么系统将会优先按用户级别的限制处理;
(4) pam_time|日期时间终端限制模块 描述:该模块通常与 account 验证类型一起使用,它并不对用户提供验证服务,而是用来限制用户在指定的日期、时间及终端线路上对系统或特定应用程序进行访问
。 默认配置文件路径:/etc/security/time.conf 配置文件语法格式:1 2 3 4 5 6 7 8 9 - services 字段:表示应用 PAM 功能的服务名称。 - ttys 字段:应用此规则的终端名,可以*号表示任何终端,!表示非。 - users 字段:应用此规则的用户名单或网络组名,可以 “*” 号表示任何用户,!表示非。 - times 字段:指定时间,通常使用日期 / 时间范围的格式来表示 - 日期: - 时间: - 日期 / 时间范围前可有 ! 表表除此以外的所有日期 / 时间 , 还可以用 - 连接指定的时间范围;
基础实例:1 2 3 4 5 6 7 8 xsh;tty*;root;!MoMo1800-0600 xsh;ttyp*;root;!WdMo0000-2400 blank;tty* & !ttyp*;you|me;!Al0000-2400
(5) pam_listfile|文件服务访问验证模块 描述: 该验证模块通常与 auth 验证类型一起使用,此模块提供根据某个指定的文件来允许或禁止用户访问某个应用程序或服务的功能,这些被指定的文件必需事先存在,然后通过 file 参数来指定该文件。 该模块可以根据用户名、 tty 、 rhost 、 ruser 、用户组、使用的 shell 来对用户进行访问控制。
模块选项: 1 2 3 4 5 * item=[tty|user|rhost|ruser|group|shell] : 设置访问控制的对象类型。 * apply=[user|@group] :用指定使用非用户和组类别时,这些规则所适用的对象。当 item=[user|ruser|group] 时该选项没有任何意义,只有当 item=[tty|rhost|shell] 时才有意思。 * sense=allow|deny : 用来指定当在保存 "item" 对象的文件中找不到 item 指定的对象时的动作方式,如果在文件中找不到相应的对象则执行相反的动作。 * onerr=succeed|fail : 用来指定当某类事件(如无法打开配置文件)发生时的返回值。 * file=filename : 指定保存有 "item" 对象的文件位置。
基础实例: 1 2 vsftpd:auth required pam_listfile.so item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed
(6) pam_unix|认证类型验证模块 描述:该模块提供基于 /etc/passwd 和 /etc/shadow 文件的类 UNIX 风格的认证,它适用所有的验证类型,包括: auth 、 account 、 password 、 session
。
模块选项: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 - debug: 将调试信息写入系统日志,当pam_unix 验证模块与所有验证类别使用时都有效。 - audit: 提供比 debug 更多诊断调试,它只有当与auth 、 account 及 password 验证类型使用时有效。 - nullok: 默认情况下如果密码为空那么就不允许用户访某项服务,而使用此项后将则覆盖这个默认动作。它只有当与 auth 、和 password 验证类型使用时有效。 - nodelay :当用户验证失败后,系统在给出错误信息时会有一个延迟,默认为 2 秒钟。当使用此选项后,将取消这个延迟。它只有当与 auth 验证类型使用时有效 - use_first_pass :当与 auth 验证类型一起使用时,使用该选项将在提示用户输入密码前,直接使用以往的密码验证方式来对用户进行验证。而当与 password 验证类型一起使用时,该选项主要用来防止用户新设定的密码与前面 password 提供的密码相同。 - try_first_pass :当与 auth 验证类型一起使用时,使用该选项将在提示用户输入密码前,尝试使用以往的密码验证方式来对用户进行验证。而当与 password 验证类型一起使用时,该选项主要用来防止用户新设定的密码与以前的旧密码相同。 - use_authok :当用户修改时使用此选项强制用户使用前面堆叠验证模块提供的密码,例如由 pam_cracklib 验证模块提供的新密码。当与 password 验证类型一起使用时有效。 - authtok_type :参数用于指定通过哪种方式传递用户密码给 PAM 模块进行验证。 * clear:明文方式传递密码。这是默认选项,密码以明文形式传递给 PAM 模块进行验证。 * md5:使用 MD5 哈希算法对密码进行加密后传递给 PAM 模块进行验证。 * sha256:使用 SHA-256 哈希算法对密码进行加密后传递给 PAM 模块进行验证。 * sha512:使用 SHA-512 哈希算法对密码进行加密后传递给 PAM 模块进行验证。 - md5 : 采用 md5 对用户密码进行加密,当与 password 验证类型一起使用时有效。 - shadow : 使用用 shadow 密码,当与 password 验证类型一起使用时有效。 - sha256 : 使用此选项,当下次修改密码时将用 SHA256 算法加密,如果 SHA256 的 libcrypt 不存在,就会重新使用 MD5 加密密码。 - Sha512 : 与此选项相同,只是加密强大不同而已,当与 password 验证类型一起使用时有效。 - rounds=n : 用来指定使用 SHA256 和 SHA512 算法加密密码时重复哈希算法的次数。当与 password 验证类型一起使用时有效。 - remember=n : 使用此选项将会将 n 个使用过的旧密码,以 MD5 的方式加密后保存到 /etc/security/opasswd 文件中。当与 password 验证类型一起使用时有效。
基础实例: 1 2 3 4 5 6 7 8 system-auth-ac:auth sufficient pam_unix.so nullok try_first_pass system-auth-ac:account required pam_unix.so system-auth-ac:password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok authtok_type=sha512 system-auth-ac:session required pam_unix.so
注意事项:
1.与 auth 验证类型一起使用时,此模块可以使用的选项有 debug 、 audit 、 use_first_pass 、 try_first_pass 、 nullok 和 nodelay
,主要功能是验证用户密码的有效性,在缺省情况下(即不带任何参数时),该模块的主要功能是禁止密码为空的用户提供服务;
2.在作为 account 类型使用时,此时该模块可识别的参数有 debug 、 audit
,该模块主要执行建立用户帐号和密码状态的任务,然后执行提示用户修改密码,用户采用新密码后才提供服务之类的任务;
3.在作为 password 类型使用时,此时该模块可识别的参数有 debug 、 audit 、 nullok; 、 not_set_pass 、 use_authtok 、 try_first_pass 、 use_first_pass 、 md5 、 bigcrypt 、 shadow 、 nis 、remember
,该模块完成让用户更改密码的任务;
4.在作为 session 类型使用时,此时该模块没有可识别的参数,该模块仅仅完成记录用户名和服务名到日志文件的工作。
(7) pam_deny|配置访问验证模块 描述:该验证模块可以用来禁止所有的访问,当你设置 PAM 配置文件时,为了安全,在开始的行可以使用它来禁止所有的访问,以减少错误配置引起的安全风险。 而 pam_permit 验证模块却总是允许所有的访问,你要谨慎的使用此验证模块。它们都适用于所有的验证类型。
(8) pam_rootok|验证模块 描述:该验证模块允许 /etc/pam.d/su 中的用户不需要任何验证就可以登录系统。因此你应当小心设置 /etc/pam.d/su 文件,并且在使用时要与 pam_wheel 验证模块一同使用,以保证 root 权限只允许在 pam_wheel 的限制中进行。它只适用于 auth 验证类型。
1 2 3 4 5 6 7 $ cat /etc/pam.d/su auth sufficient pam_rootok.so
(9) pam_security|验证模块 描述:该验证模块只对 root 用户有影响。当 root 用户登录时, pam_security 验证模块会参考 /etc/securetty
目录中的控制终端列表,来保证 root 用户不会从不安全的终端登录,它一般与 auth 验证类型一现使用。1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 $ cat /etc/securetty console vc/1 vc/2 vc/3 vc/4 vc/5 vc/6 vc/7 vc/8 vc/9 vc/10 vc/11 tty1 tty2 tty3 tty4 tty5 tty6 tty7 tty8 tty9 tty10 tty11 ttyS0 ttysclp0 sclp_line0 3270/tty1 hvc0 hvc1 hvc2 hvc3 hvc4 hvc5 hvc6 hvc7 hvsi0 hvsi1 hvsi2 xvc0
(10) pam_nologin|验证模块 描述:该验证模块如果 /etc/nologin 文件存在,此模块将禁止所有的登录。它一般与 auth 和 account 验证类型一同使用。
(11) pam_echo|验证模块 描述:该验证模块用来给用户显示通过 file 选项指定的文件中的内容,它适用于所有的验证类型。
(12) pam_motd 验证模块 允许将 /etc/motd 文件中的内容显示给用户,它只适用于 session 验证类型。
(13) pam_lastlog|验证模块 描述:显示用户上次登录的日期和时间,它主要通过读取 /var/log/lastlog 文件来显示。它只适用与 session 验证类型。
(14) pam_warn|验证模块 描述:将刚登录的信息记录到系统日志当中,它一般与 auth 和 password 验证类型一同使用。
(15) pam_wheel|验证模块 描述:当使用此验证模块后,只有加入到了一个 wheel group 中的的根用户,并且提交的密码有效,才能访问指定的服务或系统。将它与 pam_rootok 一同使用能增加对根用户的限制。它只适用于 auth 和 account 验证类型。
(16) pam_passwdqc|密码策略验证模块 描述:该模块与pam_cracklib差不多,主要用来设置Linux用户密码的复杂度;
模块选项说明:1 2 3 4 5 6 7 8 9 10 11 12 * mix: 设置口令字最小长度,默认值是 mix=disabled 。 * max: 设置口令字的最大长度,默认值是 max=40 。 * passphrase: 设置口令短语中单词的最少个数,默认值是 passphrase=3 ,如果为 0 则禁用口令短语。 * atch: 设置密码串的常见程序,默认值是 match=4 。 * similar: 设置当我们重设口令时,重新设置的新口令能否与旧口令相似,它可以是permit 允许相似或 deny 不允许相似。 * random: 设置随机生成口令字的默认长度。默认值是 random=42 ,设为 0 则禁止该功能。 * retry: 设置用户输入口令字时允许重试的次数,默认值是 retry=3 * enforce: 设置约束范围 - enforce=none 表示只警告弱口令字,但不禁止它们使用; - enforce=users 将对系统上的全体非根用户实行这一限制; - enforce=everyone 将对包括根用户在内的全体用户实行这一限制。 * non-unix: 它告诉这个模块不要使用传统的 getpwnam 函数调用获得用户信息,
PS:PAM 管理员指南来得到它们的详细说明。
(17) pam_faillock | 在指定间隔内对身份验证失败进行计数模块 描述: 该模块 pam_faillock 与 pam_tally2 模块使用类似提供了身份验证和帐户模块类型, 但pam堆栈中pam_faillock的设置不同于pam_ tally2模块设置。
即: 该模块在指定的时间间隔内维护每个用户的失败身份验证尝试列表,并在连续多次拒绝失败身份验证的情况下锁定帐户。 简单说: 其都是记录用户登陆失败次数, 超过此阈值将在有效时间内锁定该用户.
帮助文档: man pam_faillock
模块语法:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 auth ... pam_faillock.so {preauth|authfail|authsucc} [conf=/path/to/config-file] [dir=/path/to/tally-directory] [even_deny_root] [deny=n] [fail_interval=n] [unlock_time=n] [root_unlock_time=n] [admin_group=name] [audit] [silent] [no_log_info] account ... pam_faillock.so [dir=/path/to/tally-directory] [no_log_info] {preauth|authfail|authsucc} - preauth :在请求用户凭据(如密码)的模块之前调用模块时必须使用preauth参数(预授权阶段), 该模块仅检查是否应阻止用户访问服务,以防最近出现异常数量的失败连续身份验证尝试 (前置检查)。 - authfail :在确定身份验证结果的模块失败后调用模块时,必须使用authfail参数。(中途检查) - authsucc :在确定身份验证结果的模块成功后调用模块时,必须使用authsucc参数。(认证成功) conf=/path/to/config-file : 指定该模块的外置配置文件,默认为 `/etc/security/faillock.conf`。 dir=/path/to/tally-directory : 指定该模块的失败次数记录文件目录,每个用户都将创建日志记录,默认为`/var/run/faillock/`。 silent : 静默不显示详细的错误信息,防止攻击者判断系统上是否存在该用户。 audit : 如果登录的用户没有找到,则将用户名信息记录到系统日志中 no_log_info : 不通过syslog记录日志信息 deny=n :登陆失败次数 fail_interval=n :在时间范围内登陆失败次数 unlock_time=n : 锁定时间 root_unlock_time=n : root 锁定时间
使用示例: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 $ cat /etc/pam.d/common-auth auth [success=1 default=ignore] pam_unix.so nullok auth [default=die] pam_faillock.so authfail auth sufficient pam_faillock.so authsucc $ vim /etc/security/faillock.conf dir = /var/run/faillock audit silent deny = 3 fail_interval = 900 unlock_time = 600 even_deny_root root_unlock_time = 900 admin_group = <admin_group_name> $ cat /etc/pam.d/common-auth auth [success=1 default=ignore] pam_unix.so nullok auth [default=die] pam_faillock.so authfail silent audit dir=/var/run/faillock fail_interval=300 deny=6 unlock_time=600 even_deny_root root_unlock_time=600 auth sufficient pam_faillock.so authsucc sudo vi /etc/pam.d/system-auth /etc/pam.d/password-auth auth required pam_faillock.so preauth silent audit deny=6 unlock_time=600 auth [default=die] pam_faillock.so authfail audit deny=6 unlock_time=600 account required pam_faillock.so
weiyigeek.top-pam_faillock.so模块使用示例图
温馨提示: faillock 模块会因中途输入正确密码而重置错误次数,失败则会错误次数会不断累加。
结果验证:分别打开两个shell终端,一个运行faillock --user ubuntu
观察,一个运行ssh命令连接到其服务器尝试6次输错密码。1 2 3 4 5 6 7 8 9 10 11 $ faillock --user ubuntu ubuntu: When Type Source Valid 2022-08-21 04:02:23 RHOST 10.20.176.101 V ...... 2022-08-21 04:02:45 RHOST 10.20.176.101 V $ faillock --user ubuntu --reset $ faillock --user ubuntu ubuntu: When Type Source Valid
0x02 PAM应用 描述:在说到PAM实例应用的使用,我们来复用一哈/etc/passwd文件中用户相关信息;1 2 3 4 5 6 7 $ cat /etc/passwd root:x:0:0:root:/root:/bin/bash $ cat /etc/shadow web:$6 $s15TWGyS4h9vSto8 $Te5j92jO6FLTRbI5CE2f0ECM66rPl4yJQm9GMPpYNrTGBtR2WbkpZJxfJEdw .ieSat5eWRiI0jQzwk9cbuO2a.::0:99999:7:::
1.密码复杂度 描述:Linux 用户密码的有效期是否可以修改密码可以通过 login.defs 文件控制,注意对 login.defs 文件修只影响后续建立的用户,如果要改变以前建立的用户的有效期等可以使用 chage 命令。
Linux 用户密码的复杂度可以通过 pam_cracklib
或 pam_passwdqc
模块控制 , 两者不能同时使用个人感觉 pam_passwdqc 更好用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 cat /etc/login.defs MAIL_DIR /var/spool/mail PASS_MAX_DAYS 99999 PASS_MIN_DAYS 0 PASS_MIN_LEN 5 PASS_WARN_AGE 7 UID_MIN 1000 UID_MAX 60000 SYS_UID_MIN 201 SYS_UID_MAX 999 GID_MIN 1000 GID_MAX 60000 SYS_GID_MIN 201 SYS_GID_MAX 999 CREATE_HOME yes UMASK 077 USERGROUPS_ENAB yes ENCRYPT_METHOD SHA512
密码复杂度通过 /etc/pam.d/system-auth
实施:1 2 3 4 5 6 7 8 password requisite /lib/security/$ISA /pam_passwdqc.so min=disabled,24,12,8,7 passphrase=3 password sufficient /lib/security/$ISA /pam_unix.so nullok use_authtok md5 shadow password required pam_cracklib.so retry=3 minlen=12 difok=4 password required pam_unix.so sha512 remember=12 use_authtok
注意事项:
1.第一步是建立一个空文件用来存储旧密码 /etc/security/opasswd
,如果你没有建立文件却使用了历史密码记录功能的话,所有的密码更新都会失败因为 pam_unix 模块会报错。1 2 3 4 5 6 7 8 9 10 11 if [[ ! -f "/etc/security/opasswd" || "$(ls -l /etc/security/opasswd | egrep -c '\-rw\-\-\-\-\-\-\-') " != "1" ]];then mv /etc/security/opasswd /etc/security/opasswd.old > /dev/null 2>&1 touch /etc/security/opasswd chown root:root /etc/security/opasswd chmod +600 /etc/security/opasswd fi hal:1000::,,...,
2.检查用户设置的密码是不是违反系统内部的密码字典,不同的发行版密码字典存放地址是不一样的,在Debian:/var/cache/cracklib
与CentOS:/usr/share/cracklib
目录下,而且每天晚上 update-cracklib 脚本会自动的 rebuild 密码字典。
3.在密码管理方面 one time password(OTP) 也很有效果,动态密码管理,有兴趣的同学可以研究一下。
2.访问锁定 描述:下面主要正对于ssh多次登录失败锁定用户;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 1 、修改配置文件 auth required pam_tally.so deny=3 auth required pam_tally2.so deny=3 unlock_time=5 even_deny_root root_unlock_time=10 2 、在客户端测试 3 、3 次后再次测试并用正确密码登录会发现仍不能登录 4 、解除锁定方法 方式1: pam_tally.so 方式2: pam_tally2.so pam_tally2 -u test pam_tally2 -r -u test