用户账户

摘要:NSS和PAM认证

    要使验证能够正确进行,就必须提供你的两种基本信息。首先需要的是账户信息,它提供有关账户的基本信息,例如UID号码,主GID号码,默认shell等等。其次需要的是验证信息,它用来证明用来访问账户的密码的正确性。本地用户的账户信息被保存在/etc/shadow文件中。对于中央管理的而昂罗用户,两类信息都被保存在一个或多个网络服务中。
                                                      账户信息(名称服务)
    必须在登录是提供关于用户账户的基本信息,这些信息包括账号的UID号码,主UID号码,账号的主目录,它的默认shell等。最初,这些信息被保存在/etc/passwd这类本地文件中。
    应用程序通常不直接在/etc/passwd文件中寻找这类信息。他们使用系统的标准C程序库提供的库功能来查找。例如,getpwnam()功能能够查找通常保存在/etc/passwd文件中的账户信息。添加对新信息源(名称服务),如NIS或LDAP的支持,设计到适当改变C程序库。修改后可使所有使用这些库功能的应用程序可以立即从中获益。
    用户使用名称服务来查找其他用户账户。例如,LInux使用UID和GID号码来保存文件权限。每当用户列出目录来显示每个文件的拥有者和组群的名称时,都会用到名称服务。
    名称服务切换(NSS)
    名称服务切换或NSS,是一种允许对libc支持的名称服务进行配置和扩展的机制。辅助名称服务库被安装为/lib/libnss_service.so文件,例如,/lib/libnss_files.so支持从标准本地文件中检索名称服务信息。
    /etc/nsswitch.conf文件控制要使用的名称服务及其使用次序。每一行代表一个被libc功能使用的名称管理数据库(“名称服务”)。每一行的第一项指定要配置的名称服务,随后是冒号:
aliases,ethers,group,hosts,netgroup,networks,passwd,protocols,rpc,services,shadow
数据库名称通常与/etc/中用来保存该信息的文件名称相符。这一行的其他项目包括用空格间隔的可依次查找信息的名称服务。查找到的第一项匹配生效。例如:
passwd:  files nis ldap
这行指定通常被保存在/etc/passwd中的信息,首先在本地文件中查找,然后使用NIS服务器,然后使用LDAP服务器。
    getent是用来检查名称服务操作情况的一个重要工具。getent可以从任何标准C库数据库中查找名称。它还能够在标准输出中提供相应数据库转储。这对于类似以下的问题解决很有帮助:“系统上没有使用相同UID的用户?”,“该用户是不是本地文件和NIS中都有记录?”
    例如,getent passwd root这个命令可能会产生以下输出:(语法:getent database  name)
        root:x:0:0root:/root:/bin/bash
   验证
   最初,用用程序使用NSS来保存密码散列以及常规账户信息。在试图登录是,应用程序会为输入的密码加密,使用getpwnam()来查找NSS中该账户的passwd文件信息,然后和加密的密码作比较。如果密码散列匹配,这说明所输入的密码是正确的,用户就通过验证。本地用户验证仍旧在使用于此相同的基本方法。
    其他验证用户的方法已被开发出来。如果现代应用程序仍旧调用libc功能直接验证用户,那么每个程序都得重新编写以便支持不在NSS保存散列的密码验证机制。
                                            PAM认证加强Linux服务器的安全


PAM(Pluggable Authentication Modules)即可插拔式认证模块,它是一种高效而且灵活便利的用户级别的认证

方式,它也是当前Linux服务器普遍使用的认证方式。
1.部署PAM认证的必要性

我们知道一台Linux服务器会开许多不同的服务,这些服务中很多服务本身并没有认证功能,只是把认证交给用

户名及密码。如果这样的话,那么所有服务都用Linux系统的用户名及密码来认证,对于服务器来说是很危险的

。比如一台服务器开着FTP、SMTP、SSH等服务,那么新建一个用户默认就享有对以上的服务的操作权限,那么如

果一个用户的帐号密码泄露会涉及到多个服务。因此,不管是PC还是服务器在类Linux系统中部署PAM认证是非常

必要的。通过新型的认证模块——PAM就能解决认证方面的不足,加强Linux系统安全。

2.PAM认证的方式

PAM认证一般遵循这样的顺序:Service(服务)→PAM(配置文件)→pam_*.so。PAM认证首先要确定那一项服务,然

后加载相应的PAM的配置文件(位于/etc/pam.d下),最后调用认证文件(位于/lib/security下)进行安全认证。通

常情况下,在Linux系统安装完成后会在/etc/pam.d路径下为我们提供了一些默认的配置文件。另外,大家要知

道/lib/security目录是认证文件的默认存放位置。/etc/pam.d路径下的默认配置文件是我们进行PAM配置的模板

,通常情况下我们根据安全需要对于进行修改或者添加相应的项即可。

3.PAM认证的构成

客观地说PAM认证还是比较复杂的,简单地讲它包括四种常见认证类型(module type):即auth认证管理、

account用户管理、password密码认证管理、session会话管理。以/etc/pam.d/login为例,我们可以看到它的配

置文件,区域1中的auth、account、password、session等都是认证类型。区域2中的required、 requisite 、

sufficient 、optional是认证的流程控制。最后面的区域3就是认证的PAM文件了。

4.PAM认证的流程

为了便于大家深入了解PAM认证的流程,我们以验证用户登录的PAM-login为例进行说明。PAM认证流程是从行首

验证到行尾,逐条认证。比如用户登录服务器,共有十条auth类型认证,假设第一条认证失败,一般情况后九条

也必须要认证。为什么就一般情况呢?其实还有非一般情况。那么这个用户动作成功与否是要看auth认证后面的

区域2是怎么处理的。在有的处理字段有required和optional,其中required代表认证必须通过,也就是说,无

论成功多少条语句,只要失败一条,那么认证就失败。

5.PAM认证测试

pam_securetty.so是一个认证模块文件,该认证模块只对root用户有效,当root登录系统时,会查看有没有安全

终端,安全终端就是/etc/securetty文件里的东西,比如你运行“W”命令看到TTY下面的东西就是安全终端。如

果有安全终端就通过认证,否则失败。有些管理员为了安全,不让root用户直接登录,他会把/etc/securetty文

件清代空,这就保证了在有root密码时,也不能够在本地登录。

为了以下的实验方便,能看出效果来,我们把“auth required pam_securetty.so”这条认证加入SSH服务的PAM

模块谁文件里(/etc/pam.d/sshd)的第一行,目的就是让SSH服务应用这条认证。大家可在控制台窗口中执行“vi

etc/pam.d/sshd”然后添加这条认证语句。同样的道理,如果把这条语句加到login文件(默认这条认证是被注销

掉的,我们取消前面的#就可以了),控制的是从本地控制台登录,同样的话如果把这条语句加入到sshd文件内,

那么它将控制的是从远程登录服务器22端口的过程。

下面我们试着SSH登录系统看看效果,在控制台中执行命令“ssh -l root localhost”,可以看到无论我们的

root用户的密码正确与否都无法通过SSH远程登录到系统,可见上面的认证已经生效。在一般情况下,为了服务

器的安全,大家通过PAM认证拒绝root远程登录系统。

6.PAM认证的处理方式

了解了认证类型的工作方式,我们还应该深入的理解认证的处理方式,在图2中看到,它的认证处理方式是

required,表示这一模块的认证是必须成功的,但如果失败,认证过程不会即刻终止,PAM将继续下一个同类型

认证。上面“pam_securetty.so”认证失败了,但认证并没有结束,认证的“指针”还在向下走。如图4中所示

,在root用户SSH登录认证失败的前提下还提示用户输入密码,虽然认证不可能成功。

处理过程中除了required,还有requisite、sufficient和optional,我们再来看看requisite的效果。还用SSH

服务为例,把/etc/pam.d/sshd文件第一行中的“auth required pam_securetty.so”改成“auth requisite

pam_securetty.so”。再次尝试登录,发现和图4没有什么差别,也是输入3次密码后被拒绝了。但是细心的读者

如果一边看文章一边尝试着实验的话,你会发现当你在输入密码时,用required反应的速度要慢一些,并且在系

统日志中是没有记录的,认证同样是失败的。这说明required和requisite类似的地方是认证必须通过,而不同

的是如果失败,认证过程将立即终止,不会去认证下面的条目。

7.限制root登录控制台

我们修改用/etc/pam.d/login来限制root登录控制台,打开login文件删除第二行中的#,取消对“auth

required pam_securetty.so”的注销。然后我们本地登录服务器,通过测试我们发现当用required时,你在输

入root及密码后,你得到了一个拒绝信息,用requisite时,当你输入root回车时同样会得到拒绝信息登录失败

,这是由刚才的认证方式触发的。

8.PAM认证可选模块

在PAM认证中,sufficient表示如果认证成功,那么对这一类型的模块认证是充足的了,其他的同类模块将不会

再检验,当认证失败,它会进行下一条认证,如果下面同类型的认证成功,结果依然成功。optional表示这一模

块认证是可选的,也不会对认证成功或失败产生影响,这个就比较危险了。比如我们在/etc/pam.d/sshd文件内

加入“auth required/lib/security/pam_listfile.so item=user sense=allow file=/etc/sshusers

onerr=succeed”其含义是只允许出现在/etc/sshuser文件内的用户远程登录。然后我们执行命令“ssh -l root

localhost”,当sshusers文件没有root用户时候,登录失败,很明显他被PAM模块拒绝了。那么我们改一下认证

文件,将required改成sufficient,尝试再次登录,结果成功登录。

AM所有的认证函数库存放于/lib/security/pam_*.so,并由/etc/pam.d/目录下对应的文件进行调用。在验证请

求时,应用程序通过libpam函数库来提供服务。具体使用哪些PAM函数库进行验证,则由/etc/pam.d/目录下对应

的设置文件决定。libpam 提供函数共享服务,而且可以动态载入。
详列:

1 PAM工作机制

/lib/security目录下的每一个认证模块都会返回pass或者fail结果,部分程序使用/etc/security目录下的设置

文件决定认证方式。应用程序调用PAM模块认证的配置,存放于/etc/pam.d,文件名与应用程序名对应,文件中

的每一行都会返回一个成验证功还是失败的控制标志,以决定用户是否拥有访问权限。

2 PAM验证类型

* auth 验证使用者身份,提示输入账号和密码
* account 基于用户表、时间或者密码有效期来决定是否允许访问
* password 禁止用户反复尝试登录,在变更密码时进行密码复杂性控制
* session 进行日志记录,或者限制用户登录的次数

libpam函数库会可以调用以上一种服务或者全部。

3 PAM验证控制类型(Control Values)

验证控制类型也可以称做Control Flags,用于PAM验证类型的返回结果。

* required 验证失败时仍然继续,但返回Fail(用户不会知道哪里失败)
* requisite 验证失败则立即结束整个验证过程,返回Fail
* sufficient 验证成功则立即返回,不再继续,否则忽略结果并继续
* optional 无论验证结果如何,均不会影响(通常用于session类型)

代码:
验证结果对照表
┌──────────┬──────┬─────────────┬────────────────


│          │Result│Keep testing?│       Affect   │
├──────────┼──────┼─────────────┼────────────────


│          │Pass  │     Y       │Define by system│
│Required  │Fail  │     Y       │Fail            │
├──────────┼──────┼─────────────┼────────────────


│Requisite │Pass  │     Y       │Define by system│
│          │Fail  │     N       │Fail            │
├──────────┼──────┼─────────────┼────────────────


│Sufficient│Pass  │     N       │Define by system│
│          │Fail  │     Y       │Ignore          │
└──────────┴──────┴─────────────┴────────────────

验证示例1
┌─────┬────────┬───────┬─────┬─────┬─────┐
│     │        │       │user1│user2│user3│
├─────┼────────┼───────┼─────┼─────┼─────┤
│Auth │Required│Module1│Pass │Fail │Pass │
├─────┼────────┼───────┼─────┼─────┼─────┤
│Auth │Required│Module2│Pass │Pass │Fail │
├─────┼────────┼───────┼─────┼─────┼─────┤
│Auth │Required│Module3│Pass │Pass │Fail │
├─────┴────────┴───────┼─────┼─────┼─────┤
│       Result         │Pass │Fail │Fail │
└──────────────────────┴─────┴─────┴─────┘

验证示例2
┌─────┬──────────┬───────┬─────┬─────┬─────┐
│     │          │       │user1│user2│user3│
├─────┼──────────┼───────┼─────┼─────┼─────┤
│Auth │Required  │Module1│Pass │Fail │Pass │
├─────┼──────────┼───────┼─────┼─────┼─────┤
│Auth │Sufficient│Module2│Pass │Pass │Fail │
├─────┼──────────┼───────┼─────┼─────┼─────┤
│Auth │Required  │Module3│ N/A │ N/A │Pass │
├─────┴──────────┴───────┼─────┼─────┼─────┤
│       Result           │  T  │  F  │  T  │
└────────────────────────┴─────┴─────┴─────┘
4 /etc/pam.d目录中的配置文件

每一个配置文件均有四栏:第一栏验证类型,第二栏验证控制标准,第三栏调用的PAM模块,第四栏为使用的参

数。

module_type control_flag module_location arguments

每一行记录均是一个阶段性的测试。
代码:
[root@wardking ~]# cat /etc/pam.d/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 nullok try_first_pass
auth        requisite     pam_succeed_if.so uid >= 500 quiet
auth        required      pam_deny.so

account     required      pam_unix.so
account     sufficient    pam_succeed_if.so uid < 500 quiet
account     required      pam_permit.so

password    requisite     pam_cracklib.so try_first_pass retry=3
password    sufficient    pam_unix.so md5 shadow nullok try_first_pass use_authtok
password    required      pam_deny.so

session     optional      pam_keyinit.so revoke
session     required      pam_limits.so
session     [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session     required      pam_unix.so
auth与account调用的模块直接影响到用户是否可以执行程序。

password是在用户更改密码时使用。

session用于记录用户验证成功以后的操作记录。

5 pam_stack特殊模块

当有多个应用程序需要使用相同的验证模块时,可以编辑一个pam设置文件,定义共同调用的模块,存储

于/etc/pam.d目录中,供应用程序调用。例如system-auth设置文件,可以供不同的应用程序调用,如果对其进

行修改,可以变更系统验证策略。

6 pam_unix模块

可以调用传统的NSS系统,即libnss函数库。可以用于PAM的四种验证方式,使用auth方式可以取得用户的密码,

使用accont方式检查用户的密码是否已经过期,,使用password方式可以检查用户在修改密码时进行控制,使用

session方式记录用户登录登出日志。

7 网络验证

可以通过网络登录方式来验证用户

* pam_krb5(Kerberos V tickets)
* pam_ldap(LDAP binds)
* pam_smb_auth(old SMB authentication)
* pam_winbind(SMB throuth winbind)

某些名称服务也可以通过pam_unix调用libnss函数库中的模块进行验证(NIS, Some LDAP configurations),而

不一定使用以上的四个模块

8 认证模块

pam_security模块只会对root有影响。当root账户登录时,pam_security会参考/etc/securetty目录中的

console列表,以决定root是否可以登录,避免用户从不安全的终端登录。

pam_nologin模块会确认/etc/nologin文件是否存在,如果存在,普通用户则会验证失败,只允许root用户登录

pam_listfile模块会确认要求登录的用户账号与允许的账号名单是否冲突,必须建立一个允许登录或者拒绝登录

的名单。

auth required pam_listfile item=user sense=deny file=/etc/vsftpd/ftpusers onerr=succeed

9 增强用户密码安全性

pam_unix有两个参数,可以增强用户密码安全性

* pam_unix MD5 passwords 使用MD5编码进行加密
* pam_unix shadow passwords 将加密后的密码存放于/etc/shadow文件中,并且限制普通用户访问,而且限制

用户密码有效期

还有其它的模块可以起到类似作用,比如pam_krb5

10 密码安全性原则

可以定义普通用户设置密码时必须遵行一定的策略。

* password history记录用户曾经使用过的密码
pam_unix with remember=N (记录用户使用过的前N个密码,并且禁止再次使用这些密码)

* pasword length 密码长度及复杂性
pam_cracklib模块规定用户必须使用大小写字母、数字、特殊符号做为密码,而且不能是字典中的单词
pam_passwdqc模块与cracklib类似,只是不检查字典中的单词

* failed login monitoring 监控用户登录失败的次数
pam_taily登录失败次数过多,则锁定账号

11 pam_limit

pam_limit 限制用户可以使用的系统资源,调用 /etc/security/limits.conf文件,限制用户使用的内存、可以

启用多少线程
代码:
#*               soft    core            0
#*               hard    rss             10000
#@student        hard    nproc           20
#@faculty        soft    nproc           20
#@faculty        hard    nproc           50
#ftp             hard    nproc           0
#@student        -       maxlogins       4
可以使用ulimit覆盖soft设置项,但是仍然受限于hard

12 pam_console

pam_console模块:当用户登录到console后,将拥有部分特别权限。这些权限在/etc/security/console.apps目

录中定义。

例如:用户登录后拥有重新启动计算机的权限

代码:
[root@wardking ~]# cat /etc/security/console.apps/reboot
FALLBACK=true
也可以用在auth验证类型中,用户在本地成功登录后,就会拒绝其它远程登录请求。

13 其它程序调用PAM

除用户登录验证以外,在普通用户使用系统管理工具时,也需要提供验证,例如su, reboot, system-*工具等。

pam_rootok模块用来确认用户是否是root身份

pam_timestamp模块用于记录用户执行sudo的时间间隔,如果在5分钟之内验证成功,则直接通过验证,而不再需

要输入密码

pam_xauth模块用于将验证的临时文件转发给其它程序

14 实例分析

代码:
[root@wardking ~]# cd /etc/pam.d
[root@wardking pam.d]# cat config-util
#%PAM-1.0
auth            sufficient      pam_rootok.so
auth            sufficient      pam_timestamp.so
auth            include         system-auth
account         required        pam_permit.so
session         required        pam_permit.so
session         optional        pam_xauth.so
session         optional        pam_timestamp.so
/etc/pam.d/config-util是一个pam_stack类型的特殊模块,提供给system-config-*等多个应用程序共同调用。

auth sufficient pam_rootok.so

这一条命令将检查用户的身份,调用pam_rootok.so模块,如果被验证的用户是root,则返回Pass。如果不是

root用户,则返回Fail。由于此条命令使用sufficient控制标志,即使验证失败也将执行后续命令。

auth sufficient pam_timestamp.so

如果第一条命令验证失败,则可以断定当前被验证用户是普通用户。因此在第二条命令中使用pam_timestamp.so

模块,检查该用户是否在5 分钟之内成功运行了sudo命令,如果是返回Pass,否则返回Fail。这条命令同样使用

了sufficient控制标志,因此在验证失败时仍将执行后续命令。

auth include system-auth

第三条命令使用pam_stack.so模块,调用当前目录下的system-auth配置文件。system-auth定义了较多的PAM命

令语句,其主要作用是提示普通用户输入root账号的密码。

account required pam_permit.so

第四条命令以account类型调用pam_permit.so模块,基于当前账户的有效性(账户是否禁用或者过期)来允许或

者拒绝访问。由于该条命令以required控制标志执行,如果验证结果仍然Fail,则整个过程验证失败。

最后三条session命令,将对整个验证过程进行日志记录,写入到/var/log/secure中。