Linux 中用户与用户组
用户标识符
每个用户至少都有两个 ID,用户 ID(UID,User ID)和用户组 ID(GID,Group ID)。
当显示文件属性时,系统会根据 /etc/passwd
与 /etc/group
文件的内容找到 UID/GID 对应的账号与组名再显示出来。
用户账号
用户通过终端或 SSH 登录时,系统的处理过程如下:
- 首先在
/etc/passwd
中查找是否存在输入的账户,如果存在,则读取对应的 UID、GID、主目录和 shell 设置。 - 核对输入的密码是否与
/etc/shadow
记录匹配。 - 如果账户和密码都正确,就可以进入 shell。
/etc/passwd 文件结构
passwd
文件中以行为单位记录系统中所有账号,各字段之间用冒号分隔开:
[root@101c7 bin]$ head -4 /etc/passwd
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
以上以第一条为例,总共七个字段,说明如下:
编号 | 内容 | 说明 |
---|---|---|
1 | root | 账号名称,用来对应 UID。 |
2 | x | 密码,早期 UNIX 用来存放加密过的密码字段。 |
3 | 0 | UID,其中 0 固定为 root 用,1-499 号留给系统账号用,500 之后为一般用户。 |
4 | 0 | GID,组信息保存在 /etc/group 中。 |
5 | root | 用户信息说明列,只是用来解释账号意义。 |
6 | /root | 用户主文件夹位置。 |
7 | /bin/bash | 默认使用的 shell。如果是 /sbin/nologin 代表不能登录。 |
/etc/shadow 文件结构
shadow
文件中保存了密码和相关限制设置:
[root@101c7 bin]$ cat /etc/shadow
root:$6$A7YdIFXQJ47yq0::0:99999:7:::
bin:*:17632:0:99999:7:::
以第一条记录为例,总共有九个字段,说明如下:
编号 | 内容 | 说明 |
---|---|---|
1 | root | 账户名。 |
2 | 7YdIFXQJ47yq0 | 编码过的密码,使用不同编码方式产生的长度不同。 |
3 | 13400 | 最近改动密码的日期,以 1970/01/01 作为基准计算经过时间。 |
4 | 0 | 密码不可被改动的天数,0 无限制,11 表示每次修改密码的等待间隔为 11 天。 |
5 | 99999 | 密码过期的期限天数,如果超过这个限制天数没改密码,密码会变为已过期。 |
6 | 7 | 密码过期前发出警告的提前天数。 |
7 | 14 | 密码过期后的账号宽限时间。 |
8 | 14800 | 账号失效日期,过了限制日期后账号无法再使用。 |
9 | - | 保留字段。 |
用户组
用户组可以将账户集中在一起组成一个逻辑排列,从而简化特权管理。和用户组有关的文件记录在 /etc/group
与 /etc/gshadow
中。
/etc/group 文件结构
group
文件记录 GID 与组名的对应:
[root@101c7 bin]$ cat /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
以第一条记录为例,总共有四个字段,说明如下:
编号 | 内容 | 说明 |
---|---|---|
1 | root | 用户组名。 |
2 | x | 用户组密码,不再使用。 |
3 | 0 | 用户组 ID。 |
4 | - | 此用户组支持的账号名称。 |
初始用户组(initial group)与有效用户组(effective group):
- 保存在
/etc/passwd
中的用户对应 GID 就是初始用户组。 - 保存在
/etc/group
中的用户名说明用户在此组中,该组是组内用户的有效用户组。
/etc/gshadow 文件结构
gshadow
文件用来设定组密码:
[root@101c7 bin]$ cat /etc/gshadow
root:::
bin:::
文件内容和 /etc/group
差不多,除了第二列用来记录组密码。
两种群组机制
针对创建用户时是否创建私有组的策略有两种机制:
-
私有群组机制
系统会创建一个与账号同名的群组作为初始群组,且主文件夹权限设置为 700,这样对用户来说保密性较好。使用这一机制的代表有 RHEL、Fedora、CentOS 等。
-
公共群组机制
新建账户时若未指定组,系统会自动将 GID=100 分配给用户作为初始群组。此组为 users 公共组,主文件夹权限为 755,同一组内的用户可以共享主文件夹内的数据。SuSE 等发行版使用这一机制。
新增用户
使用默认设置新建用户时,系统所进行的操作如下:
- 在
/etc/passwd
中创建一行与账号相关的数据,包括创建 UID、GID、主文件夹等; - 在
/etc/shadow
中将账号密码相关参数填入,默认无密码; - 在
/etc/group
中加入一个与账户名相同的组名; - 在
/home
目录下创建与账户同名的目录作为用户主文件夹,权限设置为 700。
可以通过 useradd -D
命令查看创建用户时使用的默认值:
[root@101c7 bin]$ useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
实际上,这是调用了 /etc/default/useradd
文件的内容。各变量的说明如下:
行 | 设置 | 说明 |
---|---|---|
1 | GROUP=100 | 设置新用户的初始组为 users,在 CentOS 中不适用。 |
2 | HOME=/home | 用户主文件夹的基准目录(basedir)。 |
3 | INACTIVE=-1 | 密码过期后是否会失效的设置值。 |
4 | EXPIRE= | 账号失效的日期,YYYY-MM-DD 格式。 |
5 | SHELL=/bin/bash | 新用户默认的 shell 路径。 |
6 | SKEL=/etc/skel | 新用户主目录里默认的内容参考来源。 |
7 | CREATE_MAIL_SPOOL=yes | 创建用户的邮件信箱。 |
其他一些设置,如密码策略、邮箱目录等,存放在 /etc/login.defs
文件中:
[root@101c7 bin]$ cat /etc/login.defs | grep -v -E "^$|^#"
MAIL_DIR /var/spool/mail
PASS_MAX_DAYS 99999
PASS_MIN_DAYS 0
在 /etc/login.defs
文件中,一些重要参数的说明如下:
行 | 选项 | 说明 |
---|---|---|
1 | MAIL_DIR | 用户邮箱所在位置 |
2-6 | PASS_, WARN_AGE | 密码设置相关 |
7-14 | UID, SYS_UID, GID, SYS_GID | 设置 UID/GID 号相关参数 |
15 | CREATE_HOME | 建立用户主文件夹 |
16 | UMASK | 用户主文件夹的权限设置 |
17 | USERGROUPS_ENAB | 删除用户时,如果同名组是空组,也一并删除 |
18 | ENCRYPT_METHOD | 密码加密方式 |
修改密码
root 在修改密码时不需要输入旧密码,可以忽略密码规则。通常,普通用户在修改密码时需要输入旧密码,且密码需要符合复杂性要求。
密码管理机制由 /etc/pam.d/passwd
控制,密码测试模块使用 pam_cracklib.so
。
可以使用 authconfig
命令查看密码哈希使用的算法:
[root@101c7 ~]$ authconfig --test | grep hashing
password hashing algorithm is sha512
假设作为一般用户,原始密码为 A2345678b,则修改密码时的错误示例如下:
密码规则 | 错误示例 |
---|---|
长度>8 | b2345C |
不是回文(即上次密码的倒置) | b8765432A |
不能和上次密码只有大小写区别 | a2345678B |
至少包含字母和数字 | abababab |
简单的轮询检查 | 2345678bA |
PAM 模块
PAM(可插拔身份验证模块)是一套应用程序编程接口(API),用于提供一系列身份验证机制。通过告知 PAM 验证阶段的要求,PAM 能够返回验证结果(成功或失败)给用户。
PAM 只是一套验证机制,并可供其他程序调用,因此无论使用哪个程序,都可以使用 PAM 进行身份验证。
例如,passwd
命令调用 PAM 的过程如下:
- 用户执行
/usr/bin/passwd
程序并输入密码; passwd
调用 PAM 模块进行验证;- PAM 模块在
/etc/pam.d/
中查找与passwd
程序同名的配置文件; - 根据
/etc/pam.d/passwd
中的设置,逐步引用相关的 PAM 模块进行验证分析; - 将验证结果返回给
passwd
程序; passwd
根据 PAM 返回的结果决定下一步操作(通过或要求重试)。
查看 /etc/pam.d/passwd
文件内容如下:
[root@101c7 ~]$ cat /etc/pam.d/passwd
#%PAM-1.0
auth include system-auth
account include system-auth
password substack system-auth
-password optional pam_gnome_keyring.so use_authtok
password substack postlogin
每一行都包含三个字段,分别是验证类别(type)、控制标志(flag)以及相应的 PAM 模块及其参数。
验证类型
验证类型(Type)有四种,分别为:
-
auth
authentication(认证)的缩写,主要用于检验用户的身份信息,通常需要密码来进行验证,因此后续接的模块用于验证用户的身份。
-
account
account(账号)主要用于授权,用于检验用户是否具有正确的授权。例如,在使用一个过期的密码进行登录时,将无法成功登录。
-
session
session(会话)管理用户在登录期间(或使用特定命令期间)PAM 提供的环境设置。该类型通常用于记录用户登录和注销的信息。例如,在使用
sudo
命令时,会在安全日志中记录与 PAM 相关的信息,如 session open、session close 等信息。 -
password
password(密码)用于进行密码验证和修改密码等相关操作。
这四种验证类型通常按照顺序进行。首先进行身份验证(auth),然后进行授权(account),接着记录会话信息(session),最后进行密码相关的操作(password)。
控制标志
控制标志(Control Flag)用于控制验证的方式。该字段指定了验证的通过标准,有以下四种控制标志:
-
required
若验证成功,则返回 success 标志;若验证失败,则返回 failure 标志。无论成功或失败,都将继续后续的验证流程。由于后续的验证流程可以继续进行,因此这是最常用的标志之一,也方便记录日志。
-
requisite
验证失败会立即返回原始程序,并带有 failure 标志,同时终止后续的验证流程。验证成功则带有 success 标志,并继续后续的验证流程。与 required 标志的最大区别在于,遇到失败时立即终止验证流程,因此无法记录失败产生的 PAM 信息。
-
sufficient
若验证成功,则立即返回 success 给原始程序,并终止后续的验证流程。验证失败则带有 failure 标志,并继续后续的验证流程。与 requisite 标志正好相反。
-
optional
optional 标志通常用于显示信息,而不是用于验证。
如果控制标志字段中出现 include,表示调用后面的文件作为该类别的验证配置。
模块
模块存放路径:
路径 | 说明 |
---|---|
/etc/pam.d/* |
每个程序单独的 PAM 配置文件。 |
/lib/security/* |
PAM 模块文件实际放置位置。 |
/etc/security/* |
其他 PAM 环境配置文件。 |
/usr/share/doc/pam-*/ |
详细的 PAM 说明文件。 |
一些比较常用的模块:
模块名 | 说明 |
---|---|
pam_securetty.so | 限制系统管理员 root 只能从安全的终端机登录,例如 tty1-7(由 /etc/securetty 设定)。 |
pam_nologin.so | 限制一般用户能否登录主机。当 /etc/nologin 文件存在时,所有一般用户均无法登录。 |
pam_selinux.so | SELinux 是针对程序来进行详细管理权限的功能。 |
pam_console.so | 需要使用特殊的终端接口登录主机时,这个模块帮助处理一些文件权限的问题。 |
pam_loginuid.so | 验证用户的 UID 数值,可以使用这个模块来规范。 |
pam_env.so | 用来设置环境变量的一个模块。 |
pam_unix.so | 用于验证阶段的认证功能,可以用于授权阶段的账号许可证管理、日志记录等。 |
pam_pwquality.so | 用来验证密码的强度,包括密码是否在字典中、密码最大重试次数等。 |
pam_cracklib.so | 用来检验密码强度,已被 pam_pwquality.so 取代。 |
pam_limits.so | ulimit 命令用到了这个模块。 |
另外一个比较常用的是 /etc/security/limits.conf
这个配置文件,可以直接修改这个文件来对用户的系统使用配额做一些设置。
例如修改用户 user1 只能新建小于 100MB 的文件(hard),且大于 80MB 会警告(soft):
[root@101c7 ~]$ vim /etc/security/limits.conf
#<domain> <type> <item> <value>
#
#* 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
user1 soft fsize 80000
user1 hard fsize 100000
"/etc/security/limits.conf" 64L, 2499C written
使用 ulimit
查询,并使用 dd
命令测试:
[user1@101c7 ~]$ ulimit -a | grep 'file size'
core file size (blocks, -c) 0
file size (blocks, -f) 80000
[user1@101c7 ~]$ dd if=/dev/zero of=filetest bs=1M count=200
File size limit exceeded
[user1@101c7 ~]$ ll -k filetest
-rw-rw-r--. 1 user1 user1 81920000 Sep 13 11:23 filetest
例如限制用户组 group1 每次只能有一个用户登录系统(maxlogins):
[root@101c7 ~]$ vim /etc/security/limits.conf
#<domain> <type> <item> <value>
@group1 hard maxlogins 1
登录相关日志文件存放目录有 /var/log/secure
和 /var/log/messages
。如果发生任何无法登录或是产生意外错误,由 PAM 模块将数据记录在 /var/log/secure
中。