Linux nsswitch and pam
nsswitch:network service switch,网络服务转换;
用于网络服务中的名称解析;
名称解析:将人类易于记忆的字符串转换成计算机易于识别的数字,或将数字转换成字符串;(name:id)
名称解析的过程也就是去查找事先已经存在的文件或数据库,然后从中基于某个键(key),查找相对应的值(value);就像NDS一样,当我们需要名称解析时,就会去请求某个DNS服务器,DNS接受请求后就会去自己的存有名称解析对应关系的文件中查找网址所对应的IP地址,最后将结果返回给用户;像这种存储着各种key和value对应关系的库文件或数据库我们将它称为解析库;
解析库:
文件:如果是存储在文件中,只要我们让有需要的程序去读取这个文件中的各个key就可以找到对应的value了;
数据库(mysql,nis,ldap,dns等):如果是存储在数据库中的话,就会比较麻烦,因为想要读取各种数据库中的数据来验证信息的前提是有关于某种数据库的驱动,才可以实现连接到数据库来查询数据,并且还要理解数据库的响应结果;连接数据库倒不是什么难的事情,难的是我们的数据库种类有很多,如果相对于每个有名称解析需要的程序都要编写关于各种数据库的驱动的话,就要提供很多的接口,这对于程序员来说实在是太头疼了,所以就有了一个一劳永逸的办法,就是nsswitch框架,它可以实现将各种的数据库接口都抽象成一个统一的接口,提供给各种程序访问,将访问各种不同数据库的专用接口隐藏起来,不让上层程序知道,也不需要知道,程序访问的都是那一个抽象出来的接口,而到底是使用的哪种数据库,需要调用的是哪种专用接口的操作对与应用程序来说是透明的;这种做法在计算机中是很常见的,比如VFS就跟这个很类似,只不过VFS是将各种文件系统的接口抽象成为一个通用的逻辑接口;
通用框架:一种服务或者库,只要有需要的时候作为客户端访问这个服务或者加载这个库的接口就可以调用其功能;nsswitch就是一个库;
库文件:/usr/lib64/libnss*,/lib64/libnss*
配置文件:通过配置文件,标明某个具有解析需要的程序需要调用哪个库文件;
/etc/nsswitch.conf
dbname: store1 [STATUS=ACTION] [,store2,…]
STATUS :每种存储中查找到的结果状态:
=> success | notfound | unavail | tryagain
ACTION:对应每种状态要采取的行为:
=> return(直接返回结果) | continue(继续查找后面的store)
passwd: file
group: file
services: nisplus [NOTFOUND=return] files
比如服务端口对应的:/etc/services,passwd对应的:/etc/passwd,shadow对应的:/etc/shadow,它们的格式都是不同的;
我们可以通过getent命令手动进行解析查询:
getent dbname [entry]
getent services sshd
getent passwd root
getent shadow apache
认证服务:用于识别请求资源的用户是否为本人;
最平常的认证就是使用用户名或者密码,但是是怎么认证的呢?比如用户登陆系统的时候,首先会输入用户名,然后我们的系统就会将用户名转换成对应的用户ID,查看是否有此用户,然后验证用户的密码是否正确,密码验证是通过:我们计算机本地会有一个文件或者数据库,里面存储着一份有关用户名和密码的数据(加密或明文),当有用户来登陆时,系统拿着用户输入的用户名和密码与自己本机中的相比较,如果相同则授权登陆成功,如果不同等显示登陆失败;
pam:pluggable authentication module,插拔式认证模块;
跟nsswiitch类似,也是一种框架;因为认证时也是需要查询各种数据的,这些数据可能存储在文件中,也能存储在某种数据库中,为了避免对于每种数据库到都要实现一遍其专用的调用接口,所以pam实现了将各种数据库接口抽象成一个逻辑接口,供各种程序或服务使用;这些存放认证需要的数据的地方我们可以称之为认证库;但是pam的是实现要比nsswitch复杂些,比如用户登陆时,密码比对成功,但是用户帐号处于禁用期,或者我们修改密码时,如果密码不符合安全策略,我们还要提示相关信息,使之更换密码等,这些都是需要考虑的;
认证库:
文件;
数据库;
通用框架:PAM,在一定程度上也实现了类似于授权的功能;
模块位置:/lib64/security/
其中有很多模块,比如pam_shells.so就是检查用户登陆时使用的shell是否在/etc/shells(安全shell)中,如果在,则可以登陆,否则会卡住不动,无法登陆;
配置文件:/etc/pam.conf,/etc/pam.d/
通常每个应用使用一个单独的配置文件;
格式:配置文件中每行定义一种检查规则;
type control model-path module-arguments
type:检查类别
auth:帐号的认证和授权;
account:负责账户合法性检查,确认帐号是否过期,是否有权限登录系统等;
session:处理为用户提供服务之前/后需要做的些事情,实现从用户登录成功到退出的会话控制;
password:控制用户更改密码的全过程;
control:同一种功能(检查类别)的多个检查项之间如何进行组合;
两种实现机制:
1.使用一个关键词来定义;
required:表示该行以及所涉及模块的成功是用户通过鉴别的必要条件。换句话说,只有当对应于应用程序的所有带 required标记的模块全部成功后,该程序才能通过鉴别。同时,如果任何带required标记的模块出现了错误,PAM并不立刻将错误消息返回给应用程序,而是在所有模块都调用完毕后才将错误消息返回调用他的程序;
requisite:与required相仿,只有带此标记的模块返回成功后,用户才能通过鉴别;不同之处在于其一旦失败就不再执行堆中后面的其他模块,并且鉴别过程到此结束,同时也会立即返回错误信息;
sufficient:表示该行以及所涉及模块验证成功是用户通过鉴别的充分条件;也就是说只要标记为sufficient的模块一旦验证成功,那么PAM便立即向应用程序返回成功结果而不必尝试任何其他模块;即便后面的层叠模块使用了requisite或者required控制标志也是一样;当标记为sufficient的模块失败时,sufficient模块会当做 optional对待;因此拥有sufficient 标志位的配置项在执行验证出错的时候并不会导致整个验证失败,但执行验证成功之时则大门敞开;所以该控制位的使用务必慎重;
optional:他表示即便该行所涉及的模块验证失败用户仍能通过认证。在PAM体系中,带有该标记的模块失败后将继续处理下一模块。也就是说即使本行指定的模块验证失败,也允许用户享受应用程序提供的服务;
include:表示在验证过程中调用其他的PAM配置文件;在RHEL系统中有相当多的应用通过完整调用/etc/pam.d/system-auth来实现认证而不需要重新逐一去写配置项;这也就意味着在很多时候只要用户能够登录系统,针对绝大多数的应用程序也能同时通过认证;
2.使用一个或多个”value=action”形式的组合表示;
value:为一些pam库的返回值;
action:可以是一个非负整数或者是下面的记号之一;
ignore:如果使用层叠模块,那么这个模块的返回值将被忽略,不会被应用程序知道。
bad:他表示这个返回码应该被看作是模块验证失败的标志。如果这个模块是层叠模块的第一个验证失败的模块,那么他的状态值就是整个层叠模块验证的状态值和结果。
die:终止层叠模块验证过程,立刻返回到应用程序。
ok:告诉PAM这个模块的返回值将直接作为所有层叠模块的返回值。也就是说,如果这个模块前面的模块返回状态是PAM_SUCCESS,那这个返回值就会覆盖前面的返回状态。注意:如果前面的模块的返回状态表示模块验证失败,那么不能使用这个返回值再加以覆盖。
done:终止后续层叠模块的验证,把控制权立刻交回应用程序。
reset:清除所有层叠模块的返回状态,从下一个层叠模块重新开始验证。
model-path:模块路径;
/lib64/security/:此目录下的模块引用时可以使用相对路径;
module-arguments:options用于向特定模块传递相关的选项;
常用模块:
pam_unix.so auth 提示用户输入密码,并与/etc/shadow文件相比对.匹配返回0;
pam_unix.so account 检查用户的账号信息(包括是否过期等).帐号可用时,返回0;
pam_unix.so password 修改用户的密码. 将用户输入的密码,作为用户的新密码更新shadow文件;
pam_shells.so (auth,account) 如果用户想登录系统,那么它的shell必须是在/etc/shells文件中;
pam_deny.so (account,auth,password,session) 该模块可用于拒绝访问;
pam_deny.so (account,auth,password,session)模块任何时候都返回成功;
pam_securetty.so auth 如果用户要以root登录时,则登录的tty必须在/etc/securetty之中;
pam_listfile.so (account,auth,password,session) 访问应用程的控制开关;
pam_cracklib.so password 这个模块可以插入到一个程序的密码栈中,用于检查密码的强度;
pam_limits.so session 定义使用系统资源的上限,root用户也会受此限制,可以通过/etc/security/limits.conf或/etc/security/limits.d/*.conf来设定;
pam_limits.so模块通过读取配置文件完成用户对系统资源的使用控制;
配置文件:/etc/security/limits.conf
/etc/security/limits.d/*
帮助信息:man limits.conf
格式: <domain> <type> <item> <value>
domain:指定对谁做限制;
user:用户名
@group:组名
通配符:比如”*”表示所有;
type:限制类型;
hard:由root设置,用户怎样都无法超过的限制;
soft:用户可以超过此限制,但是永远无法超过hard;
-:二者同时限定;
item:限制的资源类型;
fsize:可创建的文件最大大小;
nofile:同时能打开的做最大文件数;
cpu:使用CPU的做大时间;
nproc:同时启动的最大进程数;
msqqueue:使用的POSIX消息队列能够占用的最大内存空间;
value:数值;
ulimit命令可以实现类似pam_limits.so模块的功能;
例子:
cat /etc/pam.d/su
#%PAM-1.0
auth sufficient pam_rootok.so
# Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group.
#auth required pam_wheel.so use_uid
auth include system-auth
account sufficient pam_succeed_if.so uid = 0 use_uid quiet
account include system-auth
password include system-auth
session include system-auth
session optional pam_xauth.so
注:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删;
借鉴文章:https://blog.csdn.net/thakyouhaha/article/details/47810471
https://blog.csdn.net/wbiblem/article/details/71494699