🗂 | 查看 Linux 专题可浏览更多内容


类 Unix 系统是一个多任务多用户,虽然现在常见于家庭的计算机一般都是配备一台显示器和一个键盘(甚至一个用户),但在早期计算机体积巨大且价格昂贵,一般都是集中管理,然后由多个终端连接到中央计算机使用。

Unix 的创始人 Ken Thompson 和 Dennis Ritchie 想让 Unix 成为一个多用户系统,所以这是根植于系统设计的一项特性。

id:查看用户的用户及群组信息

一个用户其实就是一个数字,即 UID(User ID)。有关用户管理的几乎一切内容是围绕着这个数字展开的。

使用 id 命令可以查看用户的 ID 信息:

$ id root
uid=0(root) gid=0(root) groups=0(root)
  • 用户(User ID):uid=0(root)
  • 属组(Group ID):gid=0(root)
  • 附加群组;

另外,直接使用 id 命令可以查看当前用户的信息:

$ id
uid=1000(conners) gid=1000(conners) groups=1000(conners),24(cdrom),25(floppy),29(audio),30(dip),44(video),46(plugdev),109(netdev)

/etc/passwd

用户信息可以在 /etc/passwd 文件中查看,这是一个系统能够识别的用户清单。

属组信息定义在 /etc/group 文件

系统在登录时查询 /etc/passwd 来确定用户的 UID 和主目录,该文件每行描述了一个用户:

$ less /etc/passwd
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
...
conners:x:1000:1000:Conners Hua,,,:/home/conners:/bin/bash
...

对于每一个用户,/etc/passwd文件定义了:

  • 登录名;
  • 加密密码的预留位;
  • UID(User ID);
  • 默认的 GID(Group ID);
  • 可选的「GECOS」信息;
  • 主目录;
  • 登陆 shell;

登录名

登录名(也就是用户名)必须是唯一的。

  • 登录名长度限制在 32 个字符;
  • 不能有冒号或换行符;
  • 建议使用字母、数字和字符作为登录名,登录名区分大小但建议为小写且以字母起始;

加密密码

在历史上每个用户加密后的密码也被存在 /etc/passwd,而这个文件可以被所有用户读取,但随着运算能力的日益增强,破解暴露在外的密码也日渐可行(最初系统使用 DES 加密用户密码,而后使用基于 MD5 加密,在 MD5 发现存在重大缺陷后,使用基于加盐的 SHA-512 的密码散列成为现在的标准)。

为此 Linux 将密码转移到了另一个不再是每个用户都可读取的文件中,也就是 /etc/shadow,而 /etc/passwd 中原先经过加密的口令或口令占位符如今也只是显示形式上的内容,也就是上述示例中的第一个冒号后的 x

UID(user ID)

按照定义,root 的 UID 为 0。大多数系统还定义了写伪用户(如 bindaemon)作为命令或配置文件的属主。这些伪用户通常会在 /etc/passwd 文件的起始位置,并给予较低的 UID 和一个假 shell,以避免有人用这些用户登陆。

为了有足够空间容纳以后添加的非人类用户,通常建议将真实用户分配的 UID 从 1000 开始(新 UID 范围可在 useradd 配置文件中指定)。目前大多发行版的 UID 范围也是如此在 1000 以上,每添加一个用户 UID 值就增加 1。

在一些发行版如 Fedora 中是 500。

注意,请不要回收重用 UID,即便用户离开了组织用户也以及被删除,因为若之后从备份中回复文件,这种防范措施能够防止可能产生的混论,因为这个过程是通过 UID 而不是登录名识别用户身份。

应该始终保持 UID 在整个组织范围内的唯一性,以避免混乱和安全问题。

GID(group ID)

GID 为 0 保留给了 root、system 等组,和 UID 类似也保留了一些预定义组,但值在各发行版中不太一致,如 bin 在 Red Hat 中是 1,Debian 中是 2 等。

GECOS

GECOS 字段用于记录用户的个人信息。主要为:

  • 全名
  • 办公室房间号和楼名
  • 办公室电话分机号
  • 家庭电话号码

主目录

主目录就是用户登录期间的默认目录。登陆 shell 会在主目录中查找特定用户的定制内容,如 shell 别名、环境变量、SSH 密钥、服务器指纹以及其他程序状态信息。

如果主目录是通过网络文件系统挂载的,在出现服务器或网络故障时会造成主目录不可用。如果登录时出现主目录丢失的情况,系统会打印出如「no home directory」这样的信息,然后将用户置入 / 目录。

登陆 shell

登陆 shell 通常是一个命令解释器,在 Linux 上没有指定时默认是 bash。

/etc/shadow

在 Linux 中 /etc/shadow 只能由超级用户读取,以此来保护加密密码的安全。

shadow 文件不是 passwd 文件的超集,passwd 文件也不是从 shadow 文件中生成的。所以必须同时维护这两个文件,或使用 useradd 这样的工具进行维护。

root:$6$rq5iUIz227omxb94$fBgkjP1P.u1c00FAk5r46z5J4SS6DoqUmij/b/sdFsmnCxozSreS4Fun8L9DcDs04hHKgY3g5AFVyE4KYbXA6.:18597:0:99999:7:::
daemon:*:18594:0:99999:7:::
bin:*:18594:0:99999:7:::
sys:*:18594:0:99999:7:::
...

/etc/passwd 文件一样,/etc/shadow 每行对应一个用户,每个用户有 9 个字段表示不同的内容:

  • 登录名(和 /etc/passwd 中一致);
  • 加密密码;
  • 最后一次更改密码的日期(由 passwd 命令负责);
  • 密码更改的最小间隔天数;
  • 密码更改的最大间隔天数;
  • 提前多少天通知用户密码将要过期;
  • 密码过期多少天后禁用该帐户;
  • 帐户过期日期;
  • 备用的保留字段,日期值为空;

只有登录名和密码字段必须指定值。

/etc/shadow 中的绝对日期字段指定的是从 1970 年 1 月 1 日起始的天数(不是秒数),并非 UNIX 或 LInux 系统中计算时间的标准方法。

/etc/shadow 中,MD5 密码以 $1$$md5$ 开头,blowfish 密码以 $2$ 开头,SHA-256 密码以 $5$ 开头,SHA-512 以 $6$ 开头,如果想更换加密算法可以使用命令:

$ sudo authconfig --passalgo=sha512 --update

/etc/group

/etc/group 包含了各个组的名称以及每个组的成员列表。

root:x:0:
daemon:x:1:
bin:x:2:
sys:x:3:
...

每行描述了一个组,每个组有 4 个字段表示不同的内容:

  • 组名;
  • 加密后的密码或占位符;
  • GID 数值;
  • 组成员列表,以逗号隔开;

添加用户

系统需要做的:

  • 编辑 /etc/passwd/etc/shadow 文件,定义用户的帐户;
  • 将用户添加到 /etc/group(非必须,但做了更好);
  • 设置初始密码;
  • 创建用户主目录,使用 chownchmod 设置主目录;
  • 配置角色和权限;

用户需要做的:

  • 将默认的启动文件复制到用户主目录;

系统管理员需要做的:

  • 让新用户在政策协议上签字;
  • 验证帐户设置是否正确;
  • 记录下用户的联系信息和帐户状态;

这些步骤如果手动操作会很繁杂还可能出错,幸好有一些现成的解决方案,如 adduseruseradd

useradd:添加用户

添加新用户可以使用 useradd 命令。

💡 在开始前,如果你使用的是普通用户后续操作会因为权限不够而无法执行,需要使用命令切换到超级用户:su -
💡 因为使用的是超级用户,所以命令开头变成了 # 而不是 $。

默认情况下不会创建属于新用户自己的主目录,所以建议带上 -m 参数自动为其创建主目录。

# 创建名为 tom 的用户
# 使用 -m 参数同时创建主目录
# useradd -m tom

# 使用选项 -g 在添加用户时将其加入某个组,如下示例加入到 sudo 组
# useradd -g sudo -m tom

# 使用选项 -s 可以指定启动 shell
# useradd -s /bin/sh -m tom

useradd 命令使用 /etc/default/useradd 文件中的参数来为新用户设置主目录位置、登陆 shell 等信息。

默认情况下登陆 shell 为 sh,若设置新用户默认使用 bash 可以使用命令设置:

# -D 修改预设值;
# -s 修改默认 shell;
# useradd -Ds /bin/bash

这样之后新建的用户的 shell 就默认为 bash 了。

passwd:设置用户密码

使用 useradd 命令添加的用户因为没有设置密码所以默认会禁用帐户。

虽然可以使用 vipw 命令编辑 passwdshadow 文件,但这样容易出错,效率也低。

可以使用 passwd 命令设置指定用户的密码。

# passwd <用户名>

chfn:设置用户 GECOS 信息

如果有需要,可以使用 chfn 命令为没有设置 GECOS 信息的用户进行设置

# 如果不带选项则是修改当前用户的GECOS 信息
# chfn <用户名>

adduser:更好的添加用户方式

使用 useradd 添加用户后还需要专门对其设置密码、GECOS 信息甚至登陆 shell(如果没有配置 useradd 的配置文件),实在是有些繁琐,幸好 Debian 谱系还提供了 adduser 命令。

adduser 命令是一种更友好的添加用户方式,这是一个更为高级的包程序,它可以通过交互的方式让你在添加新用户时配置密码、GECOS 信息:

# adduser <用户名>

除此之外还可以通过配置 /etc/adduser.conf 来指定选项。

userdel:删除用户

删除用户使用 userdel 命令。

默认情况下仅会删除用户而不会删除其主目录,要连带删除其主目录可以使用选项 -r

# -r 选项用于删除被删除用户的主目录
# userdel -r <用户名>

su:切换用户

# 切换到用户
# su <用户名>

su 命令会有一个 -l 选项,可以进一步简写成连字符 -,使用该选项会加载用户环境并将工作目录更改为该用户的主目录。

# 切换到 root 用户并加载用户环境及将工作目录更改为该用户的主目录
$ su -

groupadd 及 groupdel:添加或删除用户群组

使用命令 groupadd 添加用户组:

# groupadd <用户组>

使用命令 groupdel 删除用户组:

# groupdel <用户组>

usermod:修改用户设置

usermod 命令可用来修改用户帐号的各项设定。

举例几个实用的,你可以使用 usermod --help 查看更多:

可以使用 -g 选项强制修改用户的属组或使用 -G 选项将用户添加到目标群众:

# 强制修改用户到新的属组
# usermod -g <群组名> <用户名>

# 添加用户到某个群组
# usermod -G <群组名> <用户名>

使用 -d 选项修改用户的主目录:

# usermod -d /home/<目录名> <用户名>

使用 -d 选项修改用户的登陆 shell,如修改为 bash:

# usermod -s /bin/bash <用户名>

使用 -L 选项锁定用户密码使其无效及使用 -U 选项解锁密码锁定:

# usermod -L tom
# usermod -U tom