Linux用户管理

一、为什么需要权限分割

我们在使用个人计算机的时候,不管执行什么操作,都以管理员账户登录,而从来没有添加和使用过其他普通用户。这样做对个人计算机来讲问题不大,但在服务器上是行不通的。Linux 是多用户多任务操作系统,换句话说,Linux 系统支持多个用户在同一时间内登陆(前面讲的系统痕迹命令可以映证),不同用户可以执行不同的任务,并且互不影响。

如果不同团队共同使用一组服务器,每个人都能够被赋予管理员权限是不行的,因为不是所有的数据都可以对每位管理员公开,如果在团队中有某位管理员对 Linux 不熟悉,那么赋予他管理员权限的后果可能是灾难性的。因此,越是对安全性要求高的服务器,越需要建立合理的用户权限等级制度和服务器操作规范。

不同用户具有不问的权限,毎个用户在权限允许的范围内完成不间的任务,Linux 正是通过这种权限的划分与管理,实现了多用户多任务的运行机制。

二、用户与用户组

2.1 用户(user)的概念

我们能在Linux系统中建若干用户(user)。比如我们的同事想用我的计算机,但我不想让他用我的用户名登录,因为我的用户名下有自己的隐私内容,这时我就可以给他建一个新的用户名,让他用我所开的用户名登录,这从计算机安全角度来说是符合操作规则的;

当然用户(user)的概念理解还不仅仅于此,在Linux系统中还有一些用户是用来完成特定任务的,比如nobody和ftp 等,我们访问LinuxSir.Org 的网页程序,就是nobody用户;我们匿名访问ftp 时,会用到用户ftp或nobody ;如果想了解Linux系统的一些帐号,请查看 /etc/passwd(后面几期讲)

2.2 用户组(group)的概念

用户组(group)就是具有相同特征的用户(user)的集合体,简单的理解,有时我们需要让多个用户具有相同的权限,比如查看、修改某一个文件的权限,一种方法是分别对多个用户进行文件访问授权,一种方式是建立一个组,让这个组具有查看、修改此文件的权限,然后将所有需要访问此文件的用户放入这个组中。那么,所有用户就具有了和组一样的权限,这就是用户组。

2.3 用户与用户组管理

用户和用户组管理,顾名思义就是添加用户和用户组、更改密码和设定权限等操作(权限分割)。每个用户都有唯一的用户名和密码。在登录系统时,只有正确输入用户名和密码,才能进入系统和自己的主目录。

将用户分组是 Linux 系统中对用户进行管理及控制访问权限的一种手段,通过定义用户组,很多程序上简化了对用户的管理工作。

用户和用户组的对应关系有以下 4 种:

  • 1:1 :一个用户存在一个组中,是组中的唯一成员
  • 1:n :一个用户存在多个用户组中,此用户具有这多个组的共同权限
  • n:1 :多个用户存在一个组中,这些用户具有和组相同的权限
  • n:n :多个用户存在多个组中,其实多对多的关系是前面三条的扩展

三、用户相关文件

3.1 /etc/passwd 用户信息文件

Linux 系统中的 /etc/passwd 文件,是系统用户信息文件,存储了系统中所有用户的基本信息,并且所有用户都可以对此文件执行读操作。首先我们来打开这个文件,看看到底包含哪些内容。

可以看到,/etc/passwd 文件中的内容非常规律,每行记录对应一个用户。这些用户中的绝大多数是系统或服务正常运行所必需的用户,这种用户通常称为系统用户或伪用户。系统用户无法用来登录系统,但也不能删除,因为一旦删除,依赖这些用户运行的服务或程序就不能正常执行,会导致系统问题。

每行用户信息都以 ":" 作为分隔符,划分为 7 个字段。

root​ : x : ​0 : 0 : root : /root : /bin/bash为例:

  • 第一列: 用户名,用户名仅是为了方便用户记忆,Linux 系统是通过 UID 来识别用户身份,分配用户权限的。/etc/passwd 文件中定义了用户名和 UID 之间的对应关系。
  • 第二列: 密码位,"x" 表示此用户设有密码,但不是真正的密码,真正的密码保存在 /etc/shadow 文件中。
  • 第三列: 用户ID
    • 0 超级用户UID。如果用户UID为0,代表这个账号是管理员账号。那Linux中如何把普通用户升级成为管理员呢?就是把其他用户的UID修改为0就可以了,这点和Windows是不同的。不过不建议建立多个管理员账号。
    • 1-499 系统用户(伪用户)UID。这些UID账号是系统保留给系统用户的UID,也就是说UID是1-499范围内的用户是不能登录系统的,而是用来运行系统或服务的。其中1-99是系统保留的账号,系统自动创建。100-499 是预留给用户创建系统账号的。
    • 500-65535 普通用户UID。建立的普通用户UID从500开始,最大到65535。这些用户足够使用了,但是如果不够也不用害怕,2.6.x内核以后的Linux系统用户UID已经可以支持2的32次方这么多了。
  • 第四列:组ID,GID 添加用户时,如果不指定用户所属的初始组,那么会建立和用户名相同的组。
  • 第五列:用户说明,解释这个用户的意义。
  • 第六列:用户家目录 ,也就是用户登录后有操作权限的访问目录。root 超级管理员账户的主目录为 /root
  • 第七列:登录shell,shell 就是 Linux 的命令解释器,是用户和 Linux 内核之间沟通的桥梁(后面shell编程再讲shell)。Linux 系统默认使用的命令解释器是 bash(/bin/bash)。可以理解为用户登录过后所拥有的权限。

注意:如何把普通用户变成超级用户:把用户UID改为0即可。

3.2 /etc/shadow 影子文件

/etc/shadow 文件,用于存储 Linux 系统中用户的密码信息,又称为“影子文件”。/etc/shadow 文件只有 root 用户拥有读权限,其他用户没有任何权限,这样就保证了用户密码的安全性。我们来打开这个文件,看看到底包含哪些内容。

同 /etc/passwd 文件一样,文件中每行代表一个用户,同样使用 ":" 作为分隔符,不同之处在于,每行用户信息被划分为 9 个字段。每个字段的含义如下:

  • 第一列: 用户名
  • 第二列: 加密密码
    • 我们也可以在密码前人为的加入“!”或“*”改变加密值让密码暂时失效,使这个用户无法登陆,达到暂时禁止用户登录的效果。
    • 所有伪用户的密码都是“!!”或“*”,代表没有密码是不能登录的。当然我新创建的用户如果不设定密码,它的密码项也是“!!”,代表这个用户没有密码,不能登录。
  • 第三列: 密码最近更改时间距离1970年1月1日作为标准时间的时间戳(单位:天)
  • 第四列: 两次密码的修改间隔时间(和第3字段相比),如果是 0,则密码可以随时修改;如果是 10,则代表密码修改后 10 天之内不能再次修改密码。
  • 第五例: 密码有效期(和第3字段相比),默认值为 99999,也就是 273 年,可认为是永久生效。如果改为 90,则表示密码被修改 90 天之后必须再次修改,否则该用户即将过期。管理服务器时,通过这个字段强制用户定期修改密码。
  • 第六列: 密码修改到期前的警告天数(和第5字段相比),默认值是 7,也就是说,距离密码有效期的第 7 天开始,每次登录系统都会向该账户发出 "修改密码" 的警告信息。
  • 第七列: 密码过期后的宽限天数(和第5字段相比),在密码过期后,用户如果还是没有修改密码,则在此字段规定的宽限天数内,用户还是可以登录系统的;如果过了宽限天数,系统将不再让此账户登陆,也不会提示账户过期,是完全禁用。如果是 -1,则代表密码永远不会失效。
  • 第八列: 密码失效时间,这里同样要写时间戳,也就是用1970年1月1日进行时间换算。如果超过了失效时间,就算密码没有过期,用户也就失效无法使用了
  • 第九列: 保留

注意:目前 Linux 的密码采用的是 SHA512 散列加密算法,原来采用的是 MD5 或 DES 加密算法。SHA512 散列加密算法的加密等级更高,也更加安全。

3.3 /etc/group 组信息文件

/ect/group 文件是用户组配置文件,即用户组的所有信息都存放在此文件中。前面讲过,etc/passwd 文件中每行用户信息的第四个字段记录的是用户的初始组 ID,那么,此 GID 的组名到底是什么呢?就要从 /etc/group 文件中查找。

各用户组中,还是以 ":" 作为字段之间的分隔符,分为 4 个字段,每个字段对应的含义为:

  • 第一列: 组名
  • 第二列: 组密码位,和 /etc/passwd 文件一样,这里的 "x" 仅仅是密码标识,真正加密后的组密码默认保存在 /etc/gshadow 文件中。
  • 第三列: GID,就是群组的 ID 号,Linux 系统就是通过 GID 来区分用户组的,同用户名一样,组名也只是为了便于管理员记忆。
  • 第四列: 此组中支持的其他用户,附加组是此组的用户,如果该用户组是这个用户的初始组,则该用户不会写入这个字段,可以这么理解,该字段显示的用户都是这个用户组的附加用户。

注意

初始组:每个用户初始组只能有一个,且必须有一个,一般都是和用户名相同的组作为初始组。

附加组:每个用户可以属于多个附加组。要把用户加入组,都是加入附加组。

每个用户都可以加入多个附加组,但是只能属于一个初始组。

3.4 /etc/gshadow 组密码文件

组用户信息存储在 /etc/group 文件中,而将组用户的密码信息存储在 /etc/gshadow 文件中。如果我给用户组设定了组管理员,并给该用户组设定了组密码,组密码就保存在这个文件当中。组管理员就可以利用这个密码管理这个用户组了。

文件中,每行代表一个组用户的密码信息,各行信息用 ":" 作为分隔符分为 4 个字段,每个字段的含义如下:

  • 第一列: 组名
  • 第二列: 加密密码
  • 第三列: 组管理员
  • 第四列: 组附加用户列表,该字段显示这个用户组中有哪些附加用户,和 /etc/group 文件中附加组显示内容相同。

3.5 用户的家目录

/home/用户名

3.6 用户邮箱目录

这个邮箱在/var/spool/mail目录当中,例如user1用户的邮箱就是/var/spool/mail/user1文件

3.7 /etc/skel/ 用户模板目录

/etc/skel/目录里的文件内容为每新建一个用户,其家目录里所包含的内容。

四、用户管理命令

4.1 添加用户

4.1.1 手工删除用户

首先为了测试之前讲的用户相关文件,我们进行测试手工删除用户试验,如果可以正常建立用户,证明用户删除干净。以下为用户相关文件。

  • /etc/passwd
  • /etc/shadow
  • /etc/group
  • /etc/gshadow
  • /home/user1
  • /var/spool/mail/user1

测试结果:当这些文件部分修改和删除后,user1用户从系统消失,可以利用useradd命令重新添加user1用户。

4.1.2 useradd命令

可以使用 useradd 命令新建用户,此命令的基本格式如下:

[root@localhost ~]#useradd [选项] 用户名
选项:
-u UID,指定UID-g 组名,指定初始组 不要手工指定
-G 组名,指定附加组,把用户加入组,使用附加组
-c 说明,添加说明
-d 目录,手工指定家目录,目录不需要事先建立
-s shell, 指定登录shell

4.1.3 useradd默认值

useradd添加用户时参考的默认值文件主要有两个,分别是/etc/default/useradd/etc/login.defs

4.1.3.1 /etc/default/useradd文件

其每行含义如下:

  • GROUP=100
    • 这个选项是建立用户的默认组,也就是说添加每个用户时,用户的初始组就是GID为100的这个用户组。目前我们采用的机制私有用户组机制。
  • HOME=/home
    • 这个选项是用户的家目录的默认位置,所以所有的新建用户的家目录默认都在/home/下。
  • INACTIVE=-1
    • 这个选项就是密码过期后的宽限天数,也就是/etc/shadow文件的第七个字段。如果是天数,比如10代表密码过期后10天后失效;如果是0,代表密码过期后立即失效;如果是-1,则代表密码永远不会失效。这里默认值是-1,所以所有新建立的用户密码都不会失效。
  • EXPIRE=
    • 这个选项是密码失效时间,也就是/etc/shadow文件的第八个字段。也就说用户到达这个日期后就会直接失效。当然这里也是使用时间戳来表示日期的。默认值是空,所以所有新建用户没有失效时间,永久有效。
  • SHELL=/bin/bash
    • 这个选项是用户的默认shell的。/bin/bash是Linux的标志shell,所以所有新建立的用户默认都具备shell赋予的权限。
  • SKEL=/etc/skel
    • 这个选项就是定义用户的模板目录的位置,/etc/skel/目录中的文件都会复制到新建用户的家目录当中。
  • CREATE_MAIL_SPOOL=yes
    • 这个选项定义是否给新建用户建立邮箱,默认是创建,也就是说所有的新建用户系统都会新建一个邮箱,放在/var/spool/mail/下和用户名相同。
4.1.3.2 /etc/login.defs文件

其每行含义如下:

  • MAIL_DIR /var/spool/mail
    • 这行指定了新建用户的默认邮箱位置。比如user1用户的邮箱是就是/var/spool/mail/user1。
  • PASS_MAX_DAYS 99999
    • 这行指定的是密码的有效期,也就是/etc/shadow文件的第五字段。代表多少天之后必须修改密码,默认值是99999。
  • PASS_MIN_DAYS 0
    • 这行指定的是两次密码的修改间隔时间,也就是/etc/shadow文件的第四字段。代表第一次修改密码之后,几天后才能再次修改密码。默认值是0。
  • PASS_MIN_LEN 5
  • 这行代表密码的最小长度,默认不小于5位。但是我们现在用户登录时验证已经被PAM模块取代,所以这个选项并不生效。
  • PASS_WARN_AGE 7
    • 这行代表密码修改到期前的警告天数,也就是/etc/shadow文件的第六字段。代表密码到底有效期前多少天开始进行警告提醒,默认值是7天。
  • UID_MIN 500
  • UID_MAX 60000
    • 这两行代表创建用户时,最小UID和最大的UID的范围。我们2.6.x内核开始,Linux用户的UID最大可以支持232这么多,但是真正使用时最大范围是60000。还要注意如果我手工指定了一个用户的UID是550,那么下一个创建的用户的UID就会从551开始,哪怕500-549之间的UID没有使用(小于500的UID是给伪用户预留的)。
  • GID_MIN 500
  • GID_MAX 60000
    • 这两行指定了GID的最小值和最大值之间的范围。
  • CREATE_HOME yes
    • 这行指定建立用户时是否自动建立用户的家目录,默认是建立
  • UMASK 077
    • 这行指定的是建立的用户家目录的默认权限,因为umask值是077,所以新建的用户家目录的权限是700,umask的具体作用和修改方法我们可以参考下一章权限设定章节。
  • USERGROUPS_ENAB yes
    • 这行指定的是使用命令userdel删除用户时,是否删除用户的初始组,默认是删除。
  • ENCRYPT_METHOD SHA512
    • 这行指定Linux用户的密码使用SHA512散列模式加密,这是新的密码加密模式,原先的Linux只能用DES或MD5方式加密

4.2 设定密码

可以使用 passwd 命令给新建用户添加密码,此命令的基本格式如下:

[root@localhost ~]#passwd [选项] 用户名
选项:
-l: 暂时锁定用户。仅root用户可用
-u: 解锁用户。仅root用户可用
--stdin: 可以将通过管道符输出的数据作为用户的密码。主要在批量添加用户时使用
[root@localhost ~]#passwd
#passwd直接回车代表修改当前用户的密码

也可以使用字符串作为密码:

[root@localhost ~]# echo "123" | passwd --stdin user1
更改用户 user1 的密码 。
注意:此命令可以结合脚本批量给用户设定密码。

可以通过命令,把密码修改日期归零(shadow第3字段).这样用户一登陆就要修改密码,例如:

[root@localhost ~]# chage -d 0 user1

注意:用户自身只能修改和设定自身的密码,不能修改其他用户的密码。超级管理员用户root可以修改和设定所有用户的密码。

4.3 用户信息修改

usermod命令是修改已经添加的用户的信息的,命令如下:

[root@localhost ~]#usermod [选项] 用户名
选项:
-u UID: 修改用户的UID
-d 家目录: 修改用户的家目录。家目录必须写绝对路径
-c 用户说明: 修改用户的说明信息,就是/etc/passwd文件的第五个字段
-g 组名: 修改用户的初始组,就是/etc/passwd文件的第四个字段
-G 组名: 修改用户的附加组,其实就是把用户加入其他用户组
-s shell: 修改用户的登录Shell。默认是/bin/bash
-e 日期: 修改用户的失效日期,格式为“YYYY-MM-DD”。也就是/etc/shadow 文件的第八个字段
-L: 临时锁定用户(Lock)
-U: 解锁用户(Unlock)

仔细观察会发现,其实 usermod 命令提供的选项和 useradd 命令的选项相似,因为 usermod 命令就是用来调整使用 useradd 命令添加的用户信息的。

4.4 删除用户

通过前面的章节我们知道,用户的相关数据包含如下几项:

  • 用户基本信息:存储在 /etc/passwd 文件中;
  • 用户密码信息:存储在 /etc/shadow 文件中;
  • 用户群组基本信息:存储在 /etc/group 文件中;
  • 用户群组信息信息:存储在 /etc/gshadow 文件中;
  • 用户个人文件:主目录默认位于 /home/用户名,邮箱位于 /var/spool/mail/用户名。

其实,userdel 命令的作用就是从以上文件中,删除与指定用户有关的数据信息。

[root@localhost ~]# userdel [-r] 用户名
选项:
-r: 在删除用户的同时删除用户的家目录

4.5 临时切换用户身份

su 是最简单的用户切换命令,通过该命令可以实现任何身份的切换,包括从普通用户切换为 root 用户、从 root 用户切换为普通用户以及普通用户之间的切换。

[root@localhost ~]# su [选项] 用户名
选项:
-:当前用户不仅切换为指定用户的身份,同时所用的工作环境也切换为此用户的环境(包括 PATH 变量、MAIL 变量等),使用 - 选项可省略用户名,默认会切换为 root 用户。
-l:同 - 的使用类似,也就是在切换用户身份的同时,完整切换工作环境,但后面需要添加欲切换的使用者账号。
-p:表示切换为指定用户的身份,但不改变当前的工作环境(不使用切换用户的配置文件)。
-m:和 -p 一样;
-c 命令:仅切换用户执行一次命令,执行后自动切换回来,该选项后通常会带有要执行的命令。

注意:使用 su 命令时,有 - 和没有 - 是完全不同的,- 选项表示在切换用户身份的同时,连当前使用的环境变量也切换成指定用户的。我们知道,环境变量是用来定义操作系统环境的,因此如果系统环境没有随用户身份切换,很多命令无法正确执行。

4.6 查看用户的UID和GID

id 命令可以查询用户的UID、GID 和附加组的信息。命令比较简单,格式如下:

[root@localhost ~]# id 用户名

例如:

[root@localhost ~]# id lamp
uid=501(lamp) gid=501(lamp) groups=501(lamp)
#能看到uid(用户ID)、gid(初始组ID), groups是用户所在组,这里既可以看到初始组,如果有附加组,则也能看到附加组

五、组管理命令

5.1 添加用户组:groupadd

添加用户组的命令是 groupadd,命令格式如下:

[root@localhost ~]# groupadd [选项] 组名
选项:
-g GID: 指定组ID

添加用户组的命令比较简单,举个例子:

[root@localhost ~]# groupadd group1
#添加group1组
[root@localhost ~]# grep "group1" /etc/group
group1:x:502:
#查看group1是否添加成功

5.2 删除用户组:groupdel

groupdel命令用于删除用户组,命令格式如下:

[root@localhost ~]#groupdel 组名
例子:
[root@localhost ~]#groupdel testgrp
#删除testgrp组

注意:要删除的组不能是其他用户的初始组,也就是说这个组中没有初始用户才可以删除。如果组中有附加用户,则删除组时不受影响。

5.3 把用户添加进组或从组中删除:gpasswd

其实gpasswd命令是用来设定组密码并指定组管理员的,不过我们在前面已经说了,组密码和组管理员功能很少使用,gpasswd命令现在主要用于把用户添加进组或从组中删除。命令格式如下:

[root@localhost ~]# gpasswd [选项] 组名
选项:
-a 用户名: 把用户加入组
-d 用户名: 把用户从组中删除

举例:

[root@localhost ~]# groupadd grouptest
#添加组grouptest
[root@localhost ~]# gpasswd -a user1 grouptest
Adding user user1 to group grouptest
#把用户user1加入grouptest组
[root@localhost ~]# grep "user1" /etc/group
user1:x:501:
grouptest:x:505:user1
#查看一下,user1用户已经作为附加用户加入grouptest组
[root@localhost ~]# gpasswd -d user1 grouptest
Removing user user1 from group grouptest
#把用户user1从组中删除
[root@localhost ~]# grep "grouptest" /etc/group
grouptest:x:505:
#组中没有user1用户了

注意:也可以使用usermod命令把用户加入某个组,不过usermod命令的操作对象是用户,命令是“usermod -G grouptest user1”,把用户名作为参数放在最后;而gpasswd命令的操作对象是组,命令是“gpasswd -a user1 grouptest”,把组名作为参数放在最后。

5.4 改变有效组:newgrp

每个用户可以属于一个初始组(用户是这个组的初始用户),也可以属于多个附加组(用户是这个组的附加用户)。既然用户可以属于这么多用户组,那么用户在创建文件后,默认生效的组身份是哪个呢?

当然是初始用户组的组身份生效了,因为初始组是用户一旦登录就直接获得的组身份。也就是说,用户在创建文件后,文件的属组是用户的初始组,因为用户的有效组默认是初始组。既然用户属于多个用户组,那么能不能改变用户的有效组呢?使用命令newgrp就可以切换用户的有效组。命令格式如下:

[root@localhost ~]# newgrp 组名

举例

1.我们已经有了普通用户user1,默认会建立user1用户组,user1组是user1用户的初始组。

2.我们再把user1用户加入group1组,那么group1组就是user1用户的附加组。

3.当user1用户创建文件test1时,test1文件的属组是user1组,因为user1组是user1用户的有效组。

4.通过newgrp命令就可以把user1用户的有效组变成group1组,当user1用户创建文件test2时,就会发现test2文件的属组就是group1组。

[root@localhost ~]# groupadd group1
#添加组group1
[root@localhost ~]# gpasswd -a user1 group1
Adding user user1 to group group1
#把user1用户加入group1组
[root@localhost ~]# grep "user1" /etc/group
user1:x:501:
group1:x:503:user1
#user1用户既属于user1组,也属于group1组
[root@localhost ~]# su – user1
#切换成user1身份,超级用户切换成普通用户不用密码
[user1@localhost ~]$ touch test1
#创建文件test1
[user1@localhost ~]$ ll test1
-rw-rw-r-- 1 user1 user1 0 114 05:43 test1
#test1文件的默认属组是user1组
[user1@localhost ~]$ newgrp group1
#切换user1用户的有效组为group1组
[user1@localhost ~]$ touch test2
#创建文件test2
[user1@localhost ~]$ ll test2
-rw-r--r-- 1 user1 group1 0 114 05:44 test2
#test2文件的默认属组是group1组

其实就是当用户属于多个组时,在创建文件时哪个组身份生效。使用newgrp命令可以在多个组身份之间切换。