内容纲要

🗂 | 查看更多 关于 Linux 的内容


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

/etc/passwd

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

root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
sys:x:3:3:sys:/dev:/usr/sbin/nologin
sync:x:4:65534:sync:/bin:/bin/sync
...

每个用户有 7 个字段表示不同的内容:

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

登录名

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

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

加密密码

在历史上每个用户加密后的密码也被存在 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。

注意,请不要回收重用 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 命令。

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

useradd 命令使用 /etc/default/useradd 文件中的参数来为新用户设置主目录位置、登陆 shell 等信息,如默认情况下登陆 shell 为 sh,若设置为 bash:

# -D 修改预设值
# -s 修改默认 shell
$ sudo useradd -D -s /bin/bash
# 创建名为 tom 的用户
# 使用 -m 参数同时创建主目录
$ sudo useradd -m tom

# 使用选项 -g 在添加用户时将其加入某个组
$ sudo useradd -g sudo -m tom

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

passwd:设置用户密码

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

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

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

# passwd <登录名>
$ sudo passwd tom

chfn:设置用户 GECOS 信息

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

# 如果不带选项则是修改当前用户的GECOS 信息
$ sudo chfn tom

adduser:更好的添加用户方式

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

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

$ sudo adduser jerry

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

id:查看用户

使用 id 命令可以查看指定登录名的 UID、GID 等信息。

$ id root
uid=0(root) gid=0(root) groups=0(root)

使用 id 命令查看新增用户可以看到 UID 值从 1000 开始,如前文所述,每增加一个用户 UID 值就加 1。

userdel:删除用户

删除用户使用 userdel 命令。

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

# -r 选项用于删除被删除用户的主目录
$ sudo userdel -r jerry

usermod:修改用户设置

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

  -c, --comment COMMENT         new value of the GECOS field
  -d, --home HOME_DIR           new home directory for the user account
  -e, --expiredate EXPIRE_DATE  set account expiration date to EXPIRE_DATE
  -f, --inactive INACTIVE       set password inactive after expiration
                                to INACTIVE
  -g, --gid GROUP               force use GROUP as new primary group
  -G, --groups GROUPS           new list of supplementary GROUPS
  -a, --append                  append the user to the supplemental GROUPS
                                mentioned by the -G option without removing
                                him/her from other groups
  -h, --help                    display this help message and exit
  -l, --login NEW_LOGIN         new value of the login name
  -L, --lock                    lock the user account
  -m, --move-home               move contents of the home directory to the
                                new location (use only with -d)
  -o, --non-unique              allow using duplicate (non-unique) UID
  -p, --password PASSWORD       use encrypted password for the new password
  -R, --root CHROOT_DIR         directory to chroot into
  -s, --shell SHELL             new login shell for the user account
  -u, --uid UID                 new UID for the user account
  -U, --unlock                  unlock the user account
  -v, --add-subuids FIRST-LAST  add range of subordinate uids
  -V, --del-subuids FIRST-LAST  remove range of subordinate uids
  -w, --add-subgids FIRST-LAST  add range of subordinate gids
  -W, --del-subgids FIRST-LAST  remove range of subordinate gids
  -Z, --selinux-user SEUSER     new SELinux user mapping for the user account

挑几个常用的:

# 修改用户所属的群组
$ sudo usermod -g sudo tom
# 添加用户到某个群组
$ sudo usermod -G sudo tom

# 修改用户的主目录
$ sudo usermod -d /home/j jerry

# 修改用户的登陆 shell
$ sudo usermod -s /bin/bash tom

# -L 锁定用户密码使其无效,-U 解锁密码锁定
$ sudo usermod -L tom
$ sudo usermod -U tom

su:切换用户

# 切换到用户 tom
$ su tom

groupadd:添加用户组

$ sudo groupadd www-data

groupdel:删除用户组

$ sudo groupdel www-data