跳到主要内容

用户管理

前言

LinuxLinux 是一个多用户多线程的操作系统。因此,管理系统账户就是很考验管理员的能力。管理系统账号呢,主要包括用户的创建、修改以及删除了,当然了还有权限数据。本文呢,就介绍下系统账号的创建、修改以及删除:

创建系统账号(useradd 命令)

创建系统用户使用 useradd 命令,它的语法如下:

useradd [options] [account_name]
useradd -D

[option]useradd 命令的可选参数。这里需要说明的一点是:它的可选参数很多,这里仅仅列出其中常用的一些参数,更多的参数以及使用方式可以使用 man 命令查看,或直接 useradd --help 命令查看。

主要可选参数如下:

-b,--base-dir       指定基础目录
-d,--home-dir 指定Home目录, 不要与 -b 一起使用

-c,--comment 用户注释信息

-u,--uid 指定 UID(不推荐)
-o,--non-unique 设置允许 UID 重复(不推荐)

-U,--user-group 指定创建一个同名的用户组(默认)
-N,--no-user-group 不创建同名用户组(与 -U 相反)

-g,--gid 指定主要组(GID 或 组名称)
-G,--groups 添加普通组, 多个组使用英文 "," 分隔

-m,--create-home 指定创建 Home 目录(通常默认)
-M,--no-create-home 指定不创建 Home 目录

-r,--system 设置为系统用户
-s,--shell SHELL 指定登录 Shell
-k,--skel SKEL_DIR 指定 Home 目录骨架

-D,--defaults 输出默认设置信息

-K,--key KEY=VALUE 指定 Key=Val 键值对, 用户覆盖 /etc/login.defs 默认配置

创建一个示例用户

想要了解一个命令的如何使用最简单直接的方式就是上示例,现在就直接创建一个示例用户 exampleuser 康康:

$ sudo useradd exampleuser

多简单?一个用户就创建完成了!来使用 id 命令查看下这个新用户的主要信息:

$ id exampleuser
uid=1001(exampleuser) gid=1001(exampleuser) groups=1001(exampleuser)

好了,创建的新用户的 UID 是 1001,并且有一个同名的主要组 exampleuser (这个默认会自动创建),主要组的 ID 也是 1001,这是我们能看到的基础信息。

接下来,我们来看下在系统的用户数据中存储了哪些数据信息:

$ sudo grep exampleuser /etc/passwd

输出信息如下:

exampleuser:x:1001:1001::/home/exampleuser:/bin/sh
[---------] - [--] [--]- [---------------] [-----]
| | | | | | |
| | | | | | +------> 操作 Shell
| | | | | +--------------------> Home 目录
| | | | +-----------------------------> 注释信息
| | | +--------------------------------> GID
| | +-------------------------------------> UID
| +----------------------------------------> 密码
+-----------------------------------------------> 用户名

注意看输出的用户数据,我们可以得到几个信息:

  • 默认分配一个 UID
  • 默认分配一个主要组 GID
  • 默认的用户 Home 目录是 /home/exampleuser
  • 默认给用户分配的操作 Shell 是 /bin/sh

--

再来看下系统的组数据信息:

$ sudo grep exampleuser /etc/group
exampleuser:x:1001:
[---------] - [--] -
| | | |
| | | +----> 组成员
| | +-------> 组ID
| +-----------> 组密码
+------------------> 组名

通过查看用户组数据我们也可以得到一个信息:当创建一个用户时,默认会创建一个同名的用户组,并且这个组就是新用户的主要组。

--

需要特别提一点是,虽然一个用户创建完成了,但是用户处于锁定状态,还无法用于系统登录,因为我们还没有给这个新用户设置密码(不可用户系统登录但是可以使用 su 命令切换到该用户)。

可选参数

上面我们创建了一个示例用户,你可能很好奇我们明明就简单的执行了一个 useradd 命令为什么会出现这么多 “默认的” 用户信息呢?其实这都与用户的可选参数以及默认参数有关。下面就来说下可选参数问题:

指定基础目录

什么是基础目录?基础目录呢就是你的 Home 目录的前缀目录。比如当你创建一个用户时如果不明确指定 Home 目录的位置,那么它的默认 Home 就会是 /home/${user} 。之所以是在 /home 目录下的原因即使因为系统默认的基础目录是 /home

这个基础目录的配置信息在 /etc/default/useradd 文件中,你可以使用下面的命令查看:

$ grep HOME /etc/default/useradd
## The default home directory. Same as DHOME for adduser
## HOME=/home

在实际中除非必要,否则不推荐你去修改这个配置。如果你想要指定用户的基础目录的话,可以在创建用户时通过 -b 参数进行指定:

-b,--base-dir: 用于创建用户时指定用户的基础目录

现在来使用这个参数创建一个用户康康,创建一个用户 example ,指定基础目录为 /tmp

$ sudo useradd -b /tmp -m example

来看下用户的数据信息:

$ sudo grep example /etc/passwd
example:x:1003:1003::/tmp/example:/bin/sh
[--]
|
+------------------> 基础目录

现在这个新创建的用户的 Home 目录就是 /tmp/example 了,看下 /tmp 目录下有没有这个目录:

$ ls /tmp/
example
注意
接下来的操作都是基于用户 example 做演示,如果你跟着步骤来在每次执行之前注意先使用 userdel 命令将用户删除。

指定Home目录

参数 -b 的作用是指定基础目录( $Prefix ),实际上生成的 Home 目录就为 $Prefix/${user} 。也就是说我们虽然能够灵活指定基础目录,但是却无法控制具体的目录,因为默认的目录名为用户名。

如果想要指定任意一个目录作为用户的 Home 目录,可以使用 -d 参数进行进行指定具体的 Home 目录:

-d,--home-dir       使用绝对路径指定具体Home目录(目录可以不存在, 会自动创建), -b 参数无效

创建一个用户 example ,并指定具体的 Home 目录:

$ sudo useradd -d /tmp/examplehome -m example

看下用户数据:

$ grep example /etc/passwd
example:x:1003:1003::/tmp/examplehome:/bin/sh
[--------------]
|
+------------------> Home 目录

可以看到用户名虽然是 example ,但是 Home 目录名却是 examplehome。

需要额外说明一点是,不要与 -b 参数同时使用。如果使用 -d 参数指定具体目录后又使用 -b 参数指定基础目录,则 -b 参数无效!

用户注释信息

注意看前面创建的用户 example 的存储数据,其实没有注释信息:

example:x:1003:1003::/tmp/examplehome:/bin/sh
-
|
+-------------------------> 注释信息

如果你想要增加一些用户说明可以使用 -c 参数进行指定:

-c,--comment        指定用户注释信息

示例:

$ sudo useradd -c "useradd example,,,," example

$ grep example /etc/passwd
example:x:1003:1003:useradd example,,,,:/home/example:/bin/sh
[------------------]
|
+------------------------------> 注释信息

指定 UID(不推荐)

Linux 系统采用无符号整形作为用户的 UID 数据类型,这也是为什么你看到的 UID 都是数值的原因。UID 是用户的唯一标识,当你创建一个用户时默认会分配一个 UID。而且在实际使用中,UID 与用户名是等效的。

现代计算机 UID 理论上的可分配的范围是:0<UIDrange<2320 < UID_{range} < 2^{32},但实际上不同的 Linux 发行版都会对允许分配的 UID 做一定的限制。这些限制被定义在 /etc/login.defs 配置文件中,比如我当前的操作系统:

$ grep UID /etc/login.defs
UID_MIN 1000
UID_MAX 60000
#SYS_UID_MIN 100
#SYS_UID_MAX 999

也就是说,在 “普通模式” 下我实际上能分配的 UID 的范围是:1000<UIDrange<600001000 < UID_{range} < 60000。除了让系统自动分配外,在创建用户时,我们还可以借助 -u 参数进行指定 UID:

-u,--uid            指定 UID

看下示例:

$ sudo useradd -u 6000 example
$ grep example /etc/passwd
example:x:6000:6000::/home/example:/bin/sh
[--] [--]
| |
| +-----------------------------> GID
+----------------------------------> UID

可以看到,UID 确实变成我们指定的了,但是 GID 也默认是 6000。虽然在 /etc/login.defs 配置文件中显示 UIDmax=60000UID_{max}=60000,但是我测试发现使用超级管理员账户分配的 UID 不受这个限制,这我就不理解了~

如果将 UID 指定为 70000 会怎样?看下:

$ sudo useradd -u 70000 example
$ id example
uid=70000(example) gid=1006(example) groups=1006(example)

虽然在创建用户是可以指定 UID,但是并不推荐去使用这个参数,建议还是直接使用系统默认分批的好。

允许UID重复(不推荐)

默认情况下,UID 不是允许重复的。不过我们可以使用 -o 参数设置允许 UID 重复,这个参数经常配合参数 -u指定 UID) 一起使用:

-o,--non-unique     设置允许 UID 重复(不推荐)

示例:

$ sudo useradd -o -u 1003 example
$ sudo useradd -o -u 1003 NonUniqueExample

$ grep 1003 /etc/passwd
example:x:1003:1003::/home/example:/bin/sh
NonUniqueExample:x:1003:1006::/home/NonUniqueExample:/bin/sh

虽然创建出了两个用户,但是:

$ id example
uid=1003(example) gid=1003(example) groups=1003(example)

$ id NonUniqueExample
uid=1003(example) gid=1003(example) groups=1003(example)

所以我就不知道这个在实际中有啥用了~

指定创建一个同名的用户组(默认)

这个是默认参数,比如之前我们创建用户时都会创建一个同名的用户组。需要特别强调的一点是,这个同名用户组会是该用户的主要组,有关主要组和普通组的区别可以参考下 主要组与普通组的区别

不过如果你在创建用户是没有自动创建同名的用户组的话可以显示使用参数 -U 进行自动创建:

-U,--user-group     指定创建一个同名的用户组(默认)

来看下示例:

先检查下用户和组 example 是否存在,如果存在的话先删除:

$ id example
id: ‘example’: no such user ## <== 用户不存在

$ egrep ^example /etc/group
$ echo $?
1 ## <== 输出非0, 说明组不存在

如果存在先使用下面的命令删除:

$ sudo userdel -r example
$ groupdel -f example

现在重新创建用户 example

$ sudo useradd -U example

自动创建了一个同名的用户组,实际上这个组也是该用户的主要组:

$ egrep ^example /etc/group
example:x:1003:

当然了,实际上即使你不加该参数默认也是会创建的。你可以看下配置文件 /etc/default/useradd ,在其中有下面一段描述说明:

The default behavior (when -n and -g are not specified) is to create a primary user group with the same name as the user being added to the system.

不创建同名用户组

默认情况下,当我们创建一个用户时会同时创建一个同名的用户组作为该用户的主要组。如果不想要创建一个同名的用户组在创建用户时可以使用下面的参数:

-N,--no-user-group  不创建同名用户组(与 -U 相反)

示例:

## 创建用户
$ sudo useradd -N example

## 查看同名组是否存在
$ egrep ^example: /etc/group
$ echo $?
1 ## <=== 输出非 0, 说明不存在

## 看下用户信息
$ id example
uid=1005(example) gid=100(users) groups=100(users)

可以看到,虽然不会创建一个同名的用户组作为该用户的主要组,但是系统还是会选取一个系统组(GID=100GID=100)作为该用户的主要组。当然了,在实际中除非需要否则还是不推荐使用该参数的。

指定主要组

这个很有意思,默认情况下在创建用户时会自动创建一个同名的用户组作为该用户的主要组。不过我们也可以通过手动指定主要组来达到不创建同名用户组的目的,参数如下:

-g,--gid            指定主要组(GID 或 组名称)

-g 参数后面跟具体的组,可以是 GID 也可以是组名。

示例:

## 创建一个组
$ sudo groupadd primarygroup

## 创建用户, 并使用 -g 参数指定主要租
$ useradd -g primarygroup example

## 查看用户信息
$ id example
uid=1003(example) gid=1006(primarygroup) groups=1006(primarygroup)

可以看到,用户的主要组变成了我们手动创建的组 primarygroup 了。并且,系统中也不会存在同名的用户组:

$ egrep ^example: /etc/group
$ echo $?
1 ## <=== 输出非0, 说明用户组不存在

添加普通组

当我们创建一个用户时,默认会创建一个同名的用户组作为该用户的主要组。如果你同时想将该用户添加到系统中已存在的某个组可以使用下面的参数:

-G,--groups         添加普通组, 多个组使用英文 "," 分隔

还是以上面创建的组 primarygroup 为例,新创建一个用户并且将使这个组作为新创建的用户的普通组:

$ sudo useradd -G primarygroup someone
$ id someone
uid=1004(someone) gid=1007(someone) groups=1007(someone),1006(primarygroup)

可以看到,组 primarygroup 此时就是该用户的普通组了。还可以查看下组数据文件来确认下:

$ egrep ^primarygroup: /etc/group
primarygroup:x:1006:someone
[-----]
|
+-----------------> 组成员

指定创建 Home 目录

这个通常是系统的默认选项,即创建用户时会自动给该用户创建一个 Home 目录(目录名为 /home/${user} )。但这不是所有的 Linux 发行版的默认选项,比如在 Debian 中就不会自动创建 Home 目录。因此,如果你想要自动创建用户的 Home 目录可以在创建用户时指定下面的参数:

-m,--create-home    指定创建 Home 目录(通常默认)

示例:

$ sudo useradd -m exampleuser
$ ls /home/
exampleuser ## <== Home 目录

指定不创建 Home 目录

这个与 指定创建 Home 目录 正好相反,在创建用户时可以明确指定不创建对应的 Home 目录。参数如下:

-M,--no-create-home 指定不创建 Home 目录

示例:

$ sudo useradd -M exampleuser
$ ls /home/exampleuser
ls: cannot access '/home/exampleuser': No such file or directory ## <== 目录不存在

需要特别强调的一点是,虽然 Home 目录没有创建但是在用户数据中依然显示 Home 目录是 /home/exampleuser 。如下:

$ grep ^exampleuser: /etc/passwd
exampleuser:x:1003:1003::/home/exampleuser:/bin/sh
[---------------]
|
+----------------------> Home 目录

所以这里需要特别注意下,这里之所以会显示 Home 目录的原因与 基础目录 有关。这里记录的只是数据,实际上会不会创建还是看你的参数的。

设置为系统用户

当我们使用 useradd 命令创建用户时,其实分为普通用户与系统用户。怎么区分一个用户是系统用户还是普通用户呢?看用户的ID即可!

在 Linux 标准中,1 ~ 99 范围的 UID 是由系统静态分配,100 ~ 1000 则是保留给超级管理员分配以及用于安装脚本自动分配,自 1000 开始的 UID 才是可用于我们创建的普通用户使用的 UID。

简单点,就记住 UID<1000UID<1000 的就是系统用户,UID1000UID≥1000 的就是普通用户。

其实前面我们创建的都是普通用户,如果想要创建系统用户需要使用 -r 参数:

-r,--system         设置为系统用户

示例:

$ sudo useradd -r systemuser
$ id systemuser
uid=998(systemuser) gid=997(systemuser) groups=997(systemuser)

再比如创建一个普通用户:

$ sudo useradd normaluser
$ id normaluser
uid=1005(normaluser) gid=1007(normaluser) groups=1007(normaluser)

除了 UID 的区别之外,在使用上普通用户与系统用户一点区别都没有,至于权限都是可以使用超级管理员角色设置。而唯一的别就在于系统用户永不过期,关于这个可以看下 /etc/shadow 数据信息:

$ sudo egrep "normaluser|systemuser" /etc/shadow
normaluser:!:18978:0:99999:7:::
systemuser:!:18978::::::

可以很明显的看出普通用户 normaluser 有密码更改和过期限制,而系统用户 systemuser 就完全没有,这就是普通用户与系统用户的唯一区别。

登录 Shell

先看下前面创建的用户的数据信息:

$ grep normaluser /etc/passwd
normaluser:x:1005:1007::/home/normaluser:/bin/sh

注意看最后的 /bin/sh ,这就是该用户的默认 Shell,而这个 Shell 就是在创建用户时通过参数 -s 指定的:

-s,--shell SHELL    指定登录 Shell

当然了,一般在系统的 /etc/default/useradd 配置文件中都会设置创建用户时的默认 Shell,这也是为什么在创建创建用户时没有明确指定,也有默认 Shell 的原因:

$ grep SHELL /etc/default/useradd | grep -v ^#
SHELL=/bin/sh

先看下系统有哪些 Shell:

$ cat /etc/shells
/bin/sh
/bin/bash
/usr/bin/bash
/bin/rbash
/usr/bin/rbash
/bin/dash
/usr/bin/dash

现在创建一个用户,并指定 Shell 为 /usr/bin/bash

$ sudo useradd -s /usr/bin/bash shuser
$ grep shuser /etc/passwd
shuser:x:1006:1008::/home/shuser:/usr/bin/bash

需要特别提一嘴的是,在系统中还有一个称为 nologin 的Shell,它的位置通常是:

/usr/sbin/nologin
/usr/bin/nologin

凡是指定 Shell 为 nologin 的用户都不可使用 SSH 进行远程登录,这点需要注意(不能使用 SSH 远程不等不代表不能使用 su 命令切换)。

Home 目录骨架

Home 骨架用于定制 Home 目录中的默认内容。这个在实际中很有用,每个公司肯定都有自己的定制化数据,因此当给新员工创建账号时肯定都希望能够直接使用这些数据而不需要特意再拷贝一份出去。如果有这样的需要的话,那么就少不了使用目录骨架。

实际上当我们创建账号时已经使用了默认的骨架,这个骨架目录是 /etc/skel 。这个是在 /etc/default/useradd 配置文件中配置的:

$ grep SKEL /etc/default/useradd
## The SKEL variable specifies the directory containing "skeletal" user
## SKEL=/etc/skel

默认情况下,该目录是空的,没有任何数据。而在创建用户时如果不想使用默认的骨架目录那么我们就可以使用下面的参数指定默认骨架目录:

-k,--skel SKEL_DIR  指定 Home 目录骨架

比如我在 /opt 目录下创建一个骨架目录,同时添加一个员工须知文件,这样新员工在登录时看到这份员工须知文件就会自觉地阅读了,是不是很方便?

示例:

## 创建目录骨架
$ sudo mkdir -p /opt/skel
$ sudo touch /opt/skel/readme ## 创建员工须知文件

## 创建账号
$ sudo useradd -m -k /opt/skel/ xiaoming

## 看下 Home 目录有没有员工须知文件
$ ls /home/xiaoming/
readme ## <== 员工须知

是不是很方便?

提示

使用目录骨架参数时一定要明确指定 创建Home目录 才行,否则命令无法执行。

Useradd 命令的默认配置信息

上面基本上给 useradd 命令的参数都介绍了一遍,参数的用户以及示例也都做了说明。这里呢还有最后一个问题,就是前面创建用户时你会发现大多数参数都会有默认的配置信息。比如默认的 Shell、默认的基础 Home 目录等等。

其实呢,这些默认的配置都是在 /etc/default/useradd 配置文件中配置的,如果你想要配置 useradd 命令的默认数据信息修改该配置文件即可。修改之后呢就可以直接使用下面的命令查看默认的配置信息:

$ useradd -D
# 或
$ useradd --defaults

比如我当前系统的默认配置:

$ useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/sh
SKEL=/etc/skel
CREATE_MAIL_SPOOL=no

一目了然,所以当你不知道当前 useradd 命令会有哪些默认信息时就可以直接使用该命令进行查看了。或者修改配置文件后不知道有没有生效也可以使用该命令进行验证。

除此之外呢,还有一个参数可用户在创建新账号时覆盖默认的参数配置,如下:

-K,--key KEY=VALUE  指定 Key=Val 键值对, 用户覆盖 /etc/login.defs 默认配置

比如说,当前默认的 SHELL 是 /bin/sh 。那么就可以通过该参数进行覆盖设置:

$ sudo useradd -K SHELL=/bin/bash example

当然了,这么看似乎意义不大。所以呢,了解一下即可~

修改系统账号(usermod 命令)

usermod 则是用户账号数据的修改,当然了实际上只是微调而已。它的参数与 useradd 命令完全一致,只是多了一些可选参数:

usermod [options] [account_name]

多出的可选参数:

-a,--append                    给用户添加新用户组, 需要配合 -G 使用

-l,--login NEW_ACCOUNT_NAME 修改账号名
-m,--move-home Home 目录迁移, 需要配合 -d 参数

-L,--lock 锁定账号
-U,--unlock 取消锁定

修改普通组

在创建账号时说过可以使用 -G 参数添加普通用户组,而 usermod 命令可以继续添加普通组,但是需要借助 -a 参数。如果不加该参数就是重新设置普通组的意思了,所以这里需要注意下。

示例:

$ sudo usermod -a -G normalgrp exampleuser

修改账号名

这个可以个人玩的话用户比较多,比如说你在使用 useradd 命令时创建的账号名是 wangerdan。但是之后你发觉这个账号名不太符合你的气质,咋办呢?使用 usermod 命令修改下你的账号名不就得了?

参数如下:

-l,--login         修改账号名

比如你想将账号名修改成 erha,命令示例:

$ sudo usermod -l erha wangerdan

Home 目录迁移

嗯,账号都修改了。Home 目录岂能不改?

比如你之前的账号名是 wangerdan,对应的 Home 目录是 /home/wangerdan 。现在你讲账号名修改成 erha 了?难道还是用之前的 Home 目录?不太好吧?

因此呢,就可以使用下面的命令将原来的 Home 目录整体坐下迁移了:

-m,--move-home     Home 目录迁移, 需要配合 -d 参数

命令示例:

$ sudo usermod -m -d /home/erha erha

这样你就感觉仅仅是将原来的目录修改个名字而已,数据啥的完全没变化。是不是很棒?

命令虽然很好用,但是一定要记住配合 -d 参数使用才行。

锁定账号

作为系统管理员,看到某个用户偷偷摸摸的使用账号下载一些不可描述的视频怎么办?当然是一起分享了!啊不,是当然限制使用了!

现在使用最简单暴力的当时就是锁定账号,不让他登录即可!参数如下:

-L,--lock          锁定账号

当使用该参数锁定账号时,你就会发下 /etc/shadow 中的数据密码位前面会有个 ! 。这个就表示锁定的意思,具体的话可以看到 系统密码信息存储文件/etc/shadow 的介绍了。

命令示例:

$ sudo usermod -L exampleuser

取消锁定

既然能说明很定就能解锁了,参数如下:

-U,--unlock        取消锁定

命令示例:

$ sudo usermod -U exampleuser

删除系统账号(userdel 命令)

userdel 命令使用起来比较危险,在使用该命令之前要先进行确认才行!该命令使用起来计较简单,语法如下:

userdel [-rf] [账号]

参数说明:

-f,--force        强制删除账户
-r,--remove 同时删除 Home 数据和 Mail 数据

默认情况下,删除账号是不会删除 Home 目录和 Mail 数据的,不过可以只用 -r 参数进行指定同步删除。

命令示例:

$ sudo userdel -f exampleuser

--

完结,撒花🎉🎉🎉~