Chapter 5 - 管理本地LINUX用户和组
5.1 用户和组
5.1.1 什么是用户?
系统中的每个进程(运行程序)都作为一个特定用户运行。每个文件归一个特定用户所有。对文件和目录的访问受到用户的限制。与运行进程相关联的用户可确定该进程可访问的文件和目录。
id
命令用于显示有关当前已登录用户的信息。关于另一用户的基本信息也可以通过将该用户的用户名作为id
命令的第一个参数的方法来查询。
若要查看与某一文件或目录相关联的用户,则使用ls -l
命令。第三列显示文件的用户所有者。
若要查看进程信息,可使用ps
命令。默认仅显示当前shell中的进程。添加-a
选项可查看与某一终端相关的所有进程。若要查看与进程相关联的用户,可使用-u
选项。第一列显示用户名。
操作系统内部是按UID编号来跟踪用户的。名称到编号的映射在帐户信息数据库中定义。默认情况下,系统使用简单的“Flat File”(即/etc/passwd文件)存储有关本地用户的信息。/etc/passwd采用以下格式(七个冒号分隔字段):
USERNAME:PASSWORD:UID:GID:GECOS:DIRECTORY:SHELL
USERNAME是UID到名称的一种映射,便于用户使用。
PASSWORD以前是以加密格式保存密码的位置。现在,密码存储在/etc/shadow的单独文件中。
UID是用户ID,即在最基本的级别标识用户的编号。
GID是用户的主要组ID编号。
GECOS字段是任意文本,通常包含用户的实际姓名。
DIRECTORY是用户的个人数据和配置文件的位置(即HOME目录)。
SHELL是用户登录时运行的程序。对于普通用户,这通常是提供用户命令提示符的程序。
5.1.2 什么是组?
与用户一样,组也有名称和编号(GID)。本地组在/etc/group中定义。/etc/group采用以下格式(四个冒号分隔字段):
GROUPNAME:PASSWORD:GID:MEMBER1,MEMBER2,MEMBERN
GROUPNAME是GID到名称的一种映射,便于用户使用。
PASSWORD是组密码。
GID是组ID编号。
MEMBER1,MEMBER2,MEMBERN是用逗号分隔的组成员列表,组成员使用其在/etc/passwd文件中的USERNAME代表。
主要组
- 每个用户有且只有一个主要组。
- 对于本地用户,主要组通过/etc/passwd第三个字段中列出的组的GID编号定义。
- 通常,用户创建的新文件归主要组所有(即新文件的默认组所有者是用户的主要组)。
- 通常,新建用户的主要组是名称与用户相同的新建组。用户是此用户专用组(UPG)的唯一成员。
补充组
- 用户可以是零个或多个补充组的成员。
- 属于本地组补充成员的用户列在/etc/group中组条目的最后一个字段中。对于本地组,用户成员身份由/etc/group中组条目的最后一个字段中由逗号分隔的用户列表确定。
- 补充组成员身份用于帮助确保用户具有对系统中文件及其他资源的访问权限。
参考:
man 1 id
man 5 passwd
man 5 group
pinfo libc
5.2 获取超级用户访问权限
5.2.1 root用户
大多数操作系统具有某种类型的超级用户,即具有系统全部权限的用户。在RHEL中,该用户就是root用户。该用户的特权高于文件系统上的一般特权,用于管理系统。要执行诸如安装或删除软件以及管理系统文件和目录等任务,必须将特权升级到root用户。
大多数设备都仅受root控制,但也有些设备并非如此(如USB设备)。虽然非root用户可以添加和删除文件以及管理可移动的设备,但默认情况下,只有root用户可以管理“固定”硬盘。
尽管如此,这种无限制的特权也带来了职责问题。root用户拥有可破坏系统的无限制权限:删除文件和目录、删除用户帐户、添加后门等。如果root帐户泄露,则其他人就有可能拥有系统的管理控制权限。
Linux上的root帐户大致相当于Windows上的本地Administrator帐户。在Linux中,大多数系统管理员都登陆到非特权用户帐户,然后使用各种工具临时获得root权限。
警告:
过去在Windows上的一种常见做法是本地Administrator用户直接登陆系统,以履行系统管理员职责。但是,在Linux上,建议系统管理员不要直接以root身份登陆。取而代之,系统管理员应当以非root用户登录,然后再使用其他机制(例如
su
、sudo
或PolicyKit)临时获得超级用户特权。作为管理员用户登录时,整个桌面环境都不必要地以管理员特权运行。在那种情形中,任何通常仅威胁用户帐户的安全漏洞就有可能威胁整个系统。
最近版本的Microsoft Windows中默认禁用了Administrator帐户,并通过帐户控制(UAC)等功能限制用户的管理特权。在Linux中,PolicyKit系统与UAC最为接近。
5.2.2 利用su
切换用户
su
命令可让用户切换至另一个用户帐户。如果未指定用户名,则意味着使用root帐户。当作为普通用户调用时,系统将提示输入要切换到的帐户的密码;当作为root用户调用时,则无需输入帐户密码。
su [-] [<USERNAME>]
命令su USERNAME
会启动“非登陆shell”,而命令su - USERNAME
则启动“登陆shell”。主要区别是su -
会将shell环境设置为如同以该用户身份完全登陆一样,而su
仅以该用户身份使用当前的环境设置启动shell。
大多数情况下,管理员希望运行su -
以获得用户的常规设置。
注意:
su
命令最常用于获得以另一个用户身份(通常是root)运行的命令行界面(shell提示符)。但是,如果结合-c
选项(该命令的作用将与Windows实用程序runas一样),就能够以另一个用户身份运行任意程序。
5.2.3 通过sudo
以root身份运行命令
从根本上而言,Linux实施非常粗糙的权限模型:root可以执行任何操作,其他用户无法执行任何操作(与系统相关)。前面讨论过的常用解决方案是允许标准用户利用su
命令暂时“成为root”用户。这样做的缺点在于,作为root操作时会被授予root的所有特权(和责任)。用户不仅可以重新启动Web服务器,还可以删除整个/etc目录。此外,需要以这种方式获取超级用户特权的用户都必须知道root用户的密码。
sudo
命令可以使用户根据/etc/sudoers文件中的设置,而被允许以root或其他用户身份运行命令。与su
之类的工具不同,sudo
要求用户输入其自己的密码以进行身份验证,而不是输入他们正尝试访问的帐户的密码。这样可让管理员将细微的权限交给用户来委派系统管理任务,而无需交出root密码。
使用sudo
的另一个优点在于,通过sudo
执行的所有命令都默认为将日志记录到/var/log/secure中。
在RHEL7中,wheel组的所有成员都可使用sudo
以包括root在内的任何用户的身份运行命令。系统将提示用户输入自己的密码。这是与RHEL6和更早版本之间的区别。在RHEL6和更早版本中,属于wheel组成员的用户默认情况下没有这种管理权限。
若要在过去版本的RHEL上实现相似的行为,可使用visudo
编辑相关配置文件,取消注释允许wheel组运行所有命令的那一行。
警告:
RHEL6默认不授予wheel组任何特权。过去一直在使用这个组的网站可能会因为RHEL7自动授予wheel组所有成员完整的
sudo
特权而感到讶异。这可能会导致未经授权的用户获得RHEL7系统的超级用户访问权限。在过去,类Unix系统利用wheel组成员资格授予或控制超级用户访问权限。
大多数具有GUI的系统管理应用使用PolicyKit提示用户进行身份验证,以及管理root访问权限。在RHEL7中,PolicyKit可能也提示wheel组的成员输入自己的密码,以便在使用图形工具时获取root特权。这与他们使用
sudo
在shell提示符获取那些特权的方式类似。PolicyKit根据自己的配置设置(与sudo
无关)授予这些特权。参考:
man 1 su
man 8 sudo
pinfo libc
man 1 pkexec
man 8 polkit
5.3 管理本地用户帐户
5.3.1 管理本地用户
可以使用很多命令行工具来管理本地用户帐户。
useradd
创建用户
- 不带选项运行时,
useradd USERNAME
会为/etc/passwd中的所有字段设置合理的默认值。默认情况下,useradd
命令不设置任何有效的密码,用户也必须要等设定了密码后才能登陆。 useradd --help
将显示可用于覆盖默认值的基本选项。在大多数情形中,可以将相同的选项用于usermod
命令,以修改现有的用户。- 一些默认值从/etc/login.defs文件中读取,如有效UID编号的范围和默认密码过期规则。此文件中的值仅在创建新用户时使用。更改此文件对任何现有用户毫无影响。
usermod
修改现有的用户
usermod --help
将显示可用于修改帐户的基本选项。一些常见的选项包括:
选项 | 说明 |
---|---|
-c ,--comment COMMENT | 向GECOS字段添加值,如全名。 |
-g ,--gid GROUP | 为用户帐户指定主要组。 |
-G ,--groups GROUPS | 为用户帐户指定一个或多个补充组。 |
-a ,--append | 与-G 选项搭配使用,将用户附加到所给的补充组,而不将用户从其他组删除。 |
-d ,--home HOME_DIR | 为用户帐户指定新的主目录。 |
-m ,--move-home | 将用户主目录移到新的位置。必须与-d 选项搭配使用。 |
-s ,--shell SHELL | 为用户帐户指定新的登陆shell。 |
-L ,--lock | 锁定用户帐户。 |
-U ,--unlock | 解锁用户帐户。 |
userdel
删除帐户
userdel USERNAME
可将用户从/etc/passwd中删除,但默认情况下保留/home/USERNAME目录和/var/mail/USERNAME文件不变。userdel -r USERNAME
同时删除用户和其主目录及其邮箱。
警告:
当在未指定
-r
选项的情况下使用userdel
删除某一用户时,系统中将有未分配用户ID编号所拥有的文件。当有由已删除用户创建的且在其主目录外存在的文件时,也会发生这种情况。这种情况将导致信息泄露和其他安全问题。在RHEL7中,
useradd
命令为新用户分配从UID1000或更高值开始的范围内中可用的第一个空闲UID编号(除非使用-u UID
选项明确指定了一个)。以下情形可能会出现信息泄露:如果第一个可用UID编号先前已被分配给了一个从系统删除的用户帐户,那么旧用户的UID编号将被重新分配给新用户,这样就会为新用户提供旧用户遗留文件的所有权。根据上述情况,解决这一问题的一个方案是,在删除创建了文件的用户时,同时从系统删除所有这些“无人拥有的”文件。另一种方案是手动为不同用户分配“无人拥有的”文件。root用户可以通过运行以下命令来查找“无人拥有的”文件和目录:
find / -nouser -o -nogroup 2> /dev/null
。
id
显示用户信息
id
将显示用户信息,包括用户的UID编号和组成员资格。id USERNAME
将显示USERNAME的用户信息,包括用户的UID编号和组成员资格。
passwd
设置密码
passwd USERNAME
可用于设置用户的初始密码或更改该用户的密码。- root用户可以将密码设为任何值。如果密码不符合最低建议标准,系统将显示消息;不过,之后会显示提示要求重新键入该新密码,所有令牌也会成功更新。
- 普通用户必须选择长度至少为8个字符,并且不以字典词语、用户名或之前密码为基础的密码。
UID范围
特定的UID编号和编号范围供RHEL用于特殊的目的。
- UID 0始终分配至超级用户帐户root。
- UID 1-200是一系列“系统用户”,静态分配给红帽的系统进程。
- UID 201-999是一系列“系统用户”,供在文件系统中没有自己的文件的系统进程使用。通常在安装需要它们的软件时,从可用池中动态分配它们。程序以这些“无特权”系统用户身份运行,以便限制它们仅访问正常运行所需的资源。
- UID 1000+是可供分配给普通用户的范围。
注意:
在RHEL7之前的惯例是,UID 1-499是系统用户,而UID 500+则用于普通用户。由
useradd
和groupadd
使用的默认范围可以在/etc/login.defs文件中更改。参考:
man 8 useradd
man 8 usermod
man 8 userdel
5.4 管理本地组帐户
5.4.1 管理补充组
groupadd
创建组
groupadd GROUPNAME
如果不带选项,则使用/etc/login.defs文件中GID_MIN和GID_MAX字段所指定的范围内的下一个可用GID。-g GID
选项用于指定新建组GID值。该值必须唯一,除非使用-o
选项。该值必须为非负整数,默认使用大于等于GID_MIN且大于其他任何现存组的GID的最小值。注意:
由于用户专用组(GID 1000以上)是自动创建的,因此通常建议预备一系列GID编号待用于补充组。较高的范围可以避免与系统组(GID 0-999)产生冲突。
-r
选项将使用/etc/login.defs文件中所列有效SYS_GID_MIN和SYS_GID_MAX字段所指定的范围内的GID创建系统组。
groupmod
修改现有的组
groupmod
命令用于将组名更改为GID映射。-n
选项用于指定新的组名称。-g
选项用于指定新的GID。
groupdel
删除组
groupdel
命令将删除组。- 如果组是任何现有用户的主要组,则它不能被删除。与
userdel
一样,请检查所有文件系统,确保不遗留由该组拥有的任何文件。
usermod
变更组成员资格
组成员资格通过用户管理进行控制。通过
usermod -g GROUPNAME
更改用户的主要组。通过
usermod -aG GROUP1,GROUP2,GROUPN USERNAME
将用户添加到补充组。重要:
使用
-a
选项可使usermod
函数进入“附加”模式。如果不使用此选项,用户将从所有其他补充组中删除。
gpasswd
变更组成员资格
- 组成员资格通过组管理进行控制。
gpasswd -a USERNAME GROUP
选项用于将用户USERNAME添加至组GROUP中。gpasswd -d USERNAME GROUP
选项用于将用户USERNAME从组GROUP中删除。gpasswd -M USER1,USER2,USERN GROUP
选项用于设置组GROUP的组成员列表。
参考:
man 5 group
man 8 groupadd
man 8 groupdel
man 8 usermod
5.5 管理用户密码
5.5.1 阴影密码和密码策略
在遥远的过去,加密的密码存储在全局可读的/etc/passwd文件中。这曾被认为具有合理的安全性,直到对加密密码的字典式攻击变得常见。从那时起,加密密码或“密码哈希”被移到更安全的/etc/shadow文件中。这种新文件也允许实现密码期限和到期功能。
现代密码哈希中存储三段信息:
$1$gCjLa2/Z$6Pu0EK0AzfCjxjv2hoLOB/
- 1:哈希算法。数字1表示MD5哈希。使用SHA-512哈希时会出现数字6。
- gCjLa2/Z:用于加密哈希的salt。这原先是随机选取的。salt和未加密密码组合并加密,创建加密的密码哈希。使用salt可以防止两个密码相同的用户在/etc/shadow文件中拥有相同的条目。
- 6Pu0EK0AzfCjxjv2hoLOB/:已加密哈希。
用户尝试登陆时,系统在/etc/shadow中查询用户的条目,将用户的salt和键入的未加密密码组合,再使用指定的哈希算法加密。如果结果与已加密哈希匹配,则用户键入了正确的密码。如果结果与已加密密码不符,则用户键入了错误的密码,登陆尝试也会失败。这种方式允许系统判断用户是否键入了正确的密码,同时又不以可用于登陆的密码形式存储密码。
注意:
RHEL7支持两种强大的新密码哈希算法:SHA-256(算法5)和SHA-512(算法6)。这些算法的salt字符串和已加密哈希都比较长。root用户可以更改密码哈希所用的默认算法,只要运行
authconfig --passalgo
命令,并从md5
、sha256
或sha512
中选择一个适当的参数。RHEL7默认使用SHA-512加密。
/etc/shadow密码格式
/etc/shadow采用以下格式(九个冒号分隔的字段):
NAME:PASSWORD:LASTCHANGE:MINAGE:MAXAGE:WARNING:INACTIVE:EXPIRE:BLANK
NAME:登陆名称。这必须是系统中的有效帐户名。
PASSWORD:已加密的密码。密码字段的开头为“!”时,表示该密码已被锁定。
LASTCHANGE:最近一次更改密码的日期,以距离1970-1-1的天数表示。
MINAGE:可以更改密码前的最少天数,如果为0则表示“无最短期限要求”。
MAXAGE:必须更改密码前的最多天数。
WARNING:密码即将到期的警告期。以天数表示,0表示“不提供警告”。
INACTIVE:帐户在密码到期后保持活动的天数。在此期限内,用户依然可以登陆系统并更改密码。在指定天数过后,帐户被锁定,变为不活动。
EXPIRE:帐户到期日期,以距离1970-1-1的天数表示。
BLANK:预留字段,供未来使用。
5.5.2 密码过期
下图显示了相关的密码过期参数,可以通过chage
对其调整,以实施密码过期策略。
chage -d 0 USERNAME # 将强制在下次登录时更新密码。
chage -l USERNAME # 将列出用户名的当前设置。
chage -E YYYY-MM-DD # 将在指定的日期使帐户到期。
注意:
date
命令可用于计算未来的日期。
date -d "+45 days"
5.5.3 限制访问
通过chage
命令,可以设置帐户到期日期。到了该日期时,用户无法以交互方式登陆系统。usermod
命令可以通过-L
选项“锁定”帐户密码。
用户离开公司时,管理员可以通过一个usermod
命令锁定帐户并使其到期。必须使用距离1970-1-1的天数来指定该日期。
sudo usermod -L -e 1 USERNAME # 锁定用户USERNAME的帐户和密码。
锁定帐户可防止用户使用密码向系统进行验证。这是预防已离开公司的员工访问某一帐户的推荐方法。如果以后该员工返回,其帐户可通过usermod -U USERNAME
解锁密码。如果帐户也已到期,务必也要更改到期日期。
nologin shell
有时,用户需要一个帐户并通过密码与系统进行身份验证,但不需要在系统上使用交互式shell。例如,邮件服务器可能需要帐户来存储邮件,需要密码供用户通过检索邮件所用的邮件客户端进行身份验证。用户不需要直接登录该系统。
这种情况的常用解决方案是将用户的登陆shell设为/sbin/nologin。如果用户尝试直接登陆系统,nologin shell将直接关闭该连接。
重要:
使用nologin shell可以防止以交互方式使用系统,但不会阻止所有访问。用户依然可以通过身份验证,并使用Web应用、文件传输程序或邮件读取程序等应用上传或检索文件。
参考:
man 1 chage
man 8 usermod
man5 shadow
man 3 crypt