目录
8.1 Linux用户和用户组
Linux用户和组的关系
8.2 Linux UID和GID
8.3 Linux /etc/passwd
用户名
密码
UID
GID
描述性信息
主目录
默认的Shell
8.4 Linux /etc/shadow
用户名
加密密码
最后一次修改时间
最小修改时间间隔
密码有效期
密码需要变更前的警告天数
密码过期后的宽限天数
账号失效时间
保留
忘记密码怎么办
8.5 Linux /etc/group
组名
组密码
组ID (GID)
组中的用户
8.6 Linux /etc/gshadow
组名
组密码
组管理员
组中的附加用户
8.7 Linux初始组和附加组
8.8 Linux /etc/login.defs
8.9 Linux系统添加新用户(useradd命令)
/etc/default/useradd 文件
8.10 Linux修改系统用户密码(passwd命令)
用户和用户组管理,顾名思义就是添加用户和用户组、更改密码和设定权限等操作。可能有很多人觉得用户管理没有意义,因为我们在使用个人计算机的时候,不管执行什么操作,都以管理员账户登录,而从来没有添加和使用过其他普通用户。这样做对个人计算机来讲问题不大,但在服务器上是行不通的。
大家想象一下,我们是一个管理团队,共同维护一组服务器,难道每个人都能够被赋予管理员权限吗?显然是不行的,因为不是所有的数据都可以对每位管理员公开,而且如果在运维团队中有某位管理员对 Linux 不熟悉,那么赋予他管理员权限的后果可能是灾难性的。
因此,越是对安全性要求高的服务器,越需要建立合理的用户权限等级制度和服务器操作规范。
Linux 是多用户多任务操作系统,换句话说,Linux 系统支持多个用户在同一时间内登陆,不同用户可以执行不同的任务,并且互不影响。
例如,某台 Linux 服务器上有 4 个用户,分别是 root、www、ftp 和 mysql,在同一时间内,root 用户可能在查看系统日志、管理维护系统;www 用户可能在修改自己的网页程序;ftp 用户可能在上传软件到服务器;mysql 用户可能在执行自己的 SQL 查询,每个用户互不干扰,有条不紊地进行着自己的工作。与此同时,每个用户之间不能越权访问,比如 www 用户不能执行 mysql 用户的 SQL 查询操作,ftp 用户也不能修改 www 用户的网页程序。
不同用户具有不问的权限,毎个用户在权限允许的范围内完成不间的任务,Linux 正是通过这种权限的划分与管理,实现了多用户多任务的运行机制。
因此,如果要使用 Linux 系统的资源,就必须向系统管理员申请一个账户,然后通过这个账户进入系统(账户和用户是一个概念)。通过建立不同属性的用户,一方面可以合理地利用和控制系统资源,另一方面也可以帮助用户组织文件,提供对用户文件的安全性保护。
每个用户都有唯一的用户名和密码。在登录系统时,只有正确输入用户名和密码,才能进入系统和自己的主目录。
用户组是具有相同特征用户的逻辑集合。简单的理解,有时我们需要让多个用户具有相同的权限,比如查看、修改某一个文件的权限,一种方法是分别对多个用户进行文件访问授权,如果有 10 个用户的话,就需要授权 10 次,那如果有 100、1000 甚至更多的用户呢?
显然,这种方法不太合理。最好的方式是建立一个组,让这个组具有查看、修改此文件的权限,然后将所有需要访问此文件的用户放入这个组中。那么,所有用户就具有了和组一样的权限,这就是用户组。
将用户分组是 Linux 系统中对用户进行管理及控制访问权限的一种手段,通过定义用户组,很多程序上简化了对用户的管理工作。
用户和用户组的对应关系有以下 4 种:
用户和组之间的关系可以用图 1 来表示:
登陆 Linux 系统时,虽然输入的是自己的用户名和密码,但其实 Linux 并不认识你的用户名称,它只认识用户名对应的 ID 号(也就是一串数字)。Linux 系统将所有用户的名称与 ID 的对应关系都存储在 /etc/passwd 文件中。
说白了,用户名并无实际作用,仅是为了方便用户的记忆而已。
要论证 "Linux系统不认识用户名" 也很简单,在前面章节,我们曾经在网络上下载过 ".tar.gz" 或 ".tar.bz2" 格式的文件,在解压缩之后的文件中,你会发现文件拥有者的属性显示的是一串数字,这很正常,就是因为系统只认识代表你身份的 ID,这串数字就是用户的 ID(UID)号。
Linux 系统中,每个用户的 ID 细分为 2 种,分别是用户 ID(User ID,简称 UID)和组 ID(Group ID,简称 GID),这与文件有拥有者和拥有群组两种属性相对应(如图 1 所示)。
从图 1 中可以看到,该文件的拥有者是超级管理员 root,拥有群组也是 root。读者可能会问,既然 Linux 系统不认识用户名,文件是如何判别它的拥有者名称和群组名称的呢?
每个文件都有自己的拥有者 ID 和群组 ID,当显示文件属性时,系统会根据 /etc/passwd 和 /etc/group 文件中的内容,分别找到 UID 和 GID 对应的用户名和群组名,然后显示出来。
/etc/passwd 文件和 /etc/group 文件,后续文章会做详细讲解,这里只需要知道,在 /etc/passwd 文件中,利用 UID 可以找到对应的用户名;在 /etc/group 文件中,利用 GID 可以找到对应的群组名。
做个小实验,笔者所用的 Linux 系统中,常用的有两个账户,分别为 root 超级管理员账户和 c.biancheng.net 普通账户,我们先使用 root 账号登陆并 Vim /etc/passwd,在该文件中找到 c.biancheng.net 账户并将其 UID 随意改一个数字,这时当你查看普通账户拥有的文件时,你会发现所有文件的拥有者不再是 c.biancheng.net,而是数字。
具体执行过程如下所示:
#查看系统中是否存在c.biancheng.net这个用户
[root@livecd ~]#grep 'c.biancheng.net' /etc/passwd
c.biancheng.net:x:500:500:c.biancheng.net:/home/centoslive:/bin/bash
[root@livecd ~]#ll -d /home/centoslive
drwx------. 23 c.biancheng.net centoslive 4096 Apr 9 09:37 /home/centoslive
[root@livecd ~]#vim /etc.passwd
#修改c.biancheng.net账户中的UID(第一个 500)为 2000
[root@livecd ~]#ll -d /home/centoslive
drwx------. 23 500 centoslive 4096 Apr 9 09:37 /home/centoslive
#可以看到,之前的 c.biancheng.net 变为了 500,因为修改了UID,导致 500 找不到对应的账号,因此显示数字
#记得最后将其再手动改正过来
[root@livecd ~]#vim /etc.passwd
#修改c.biancheng.net账户中的UID从 2000 改为 500
由于 c.biancheng.net 账户的 UID 已经改为 2000,但其 home 目录却记录的是 500,会导致此用户再次登录时无法进入自己的home目录。
注意,本节为了说明 ID 和用户名的对应关系,所以才将 /etc/passwd 文件中用户的 UID 做了更改。此操作很可能会导致某些程序无法进行,因此 /etc/passwd 文件不能随意修改。
Linux 系统中的 /etc/passwd 文件,是系统用户配置文件,存储了系统中所有用户的基本信息,并且所有用户都可以对此文件执行读操作。
首先我们来打开这个文件,看看到底包含哪些内容,执行命令如下:
[root@localhost ~]# vi /etc/passwd
#查看一下文件内容
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
...省略部分输出...
可以看到,/etc/passwd 文件中的内容非常规律,每行记录对应一个用户。
读者可能会问,Linux 系统中默认怎么会有这么多的用户?这些用户中的绝大多数是系统或服务正常运行所必需的用户,这种用户通常称为系统用户或伪用户。系统用户无法用来登录系统,但也不能删除,因为一旦删除,依赖这些用户运行的服务或程序就不能正常执行,会导致系统问题。
不仅如此,每行用户信息都以 ":" 作为分隔符,划分为 7 个字段,每个字段所表示的含义如下:
用户名:密码:UID(用户ID):GID(组ID):描述性信息:主目录:默认Shell
接下来,给大家逐个介绍这些字段。
用户名,就是一串代表用户身份的字符串。
前面讲过,用户名仅是为了方便用户记忆,Linux 系统是通过 UID 来识别用户身份,分配用户权限的。/etc/passwd 文件中就定义了用户名和 UID 之间的对应关系。
"x" 表示此用户设有密码,但不是真正的密码,真正的密码保存在 /etc/shadow 文件中(下一节做详细介绍)。
在早期的 UNIX 中,这里保存的就是真正的加密密码串,但由于所有程序都能读取此文件,非常容易造成用户数据被窃取。
虽然密码是加密的,但是采用暴力破解的方式也是能够进行破解的。
因此,现在 Linux 系统把真正的加密密码串放置在 /etc/shadow 文件中,此文件只有 root 用户可以浏览和操作,这样就最大限度地保证了密码的安全。
需要注意的是,虽然 "x" 并不表示真正的密码,但也不能删除,如果删除了 "x",那么系统会认为这个用户没有密码,从而导致只输入用户名而不用输入密码就可以登陆(只能在使用无密码登录,远程是不可以的),除非特殊情况(如破解用户密码),这当然是不可行的。
UID,也就是用户 ID。每个用户都有唯一的一个 UID,Linux 系统通过 UID 来识别不同的用户。
实际上,UID 就是一个 0~65535 之间的数,不同范围的数字表示不同的用户身份,具体如表 1 所示。
UID 范围 | 用户身份 |
---|---|
0 | 超级用户。UID 为 0 就代表这个账号是管理员账号。在 Linux 中,如何把普通用户升级成管理员呢?只需把其他用户的 UID 修改为 0 就可以了,这一点和 Windows 是不同的。不过不建议建立多个管理员账号。 |
1~499 | 系统用户(伪用户)。也就是说,此范围的 UID 保留给系统使用。其中,1~99 用于系统自行创建的账号;100~499 分配给有系统账号需求的用户。 其实,除了 0 之外,其他的 UID 并无不同,这里只是默认 500 以下的数字给系统作为保留账户,只是一个公认的习惯而已。 |
500~65535 | 普通用户。通常这些 UID 已经足够用户使用了。但不够用也没关系,2.6.x 内核之后的 Linux 系统已经可以支持 232 个 UID 了。 |
全称“Group ID”,简称“组ID”,表示用户初始组的组 ID 号。这里需要解释一下初始组和附加组的概念。
初始组,指用户登陆时就拥有这个用户组的相关权限。每个用户的初始组只能有一个,通常就是将和此用户的用户名相同的组名作为该用户的初始组。比如说,我们手工添加用户 lamp,在建立用户 lamp 的同时,就会建立 lamp 组作为 lamp 用户的初始组。
附加组,指用户可以加入多个其他的用户组,并拥有这些组的权限。每个用户只能有一个初始组,除初始组外,用户再加入其他的用户组,这些用户组就是这个用户的附加组。附加组可以有多个,而且用户可以有这些附加组的权限。
举例来说,刚刚的 lamp 用户除属于初始组 lamp 外,我又把它加入了 users 组,那么 lamp 用户同时属于 lamp 组和 users 组,其中 lamp 是初始组,users 是附加组。
当然,初始组和附加组的身份是可以修改的,但是我们在工作中不修改初始组,只修改附加组,因为修改了初始组有时会让管理员逻辑混乱。
需要注意的是,在 /etc/passwd 文件的第四个字段中看到的 ID 是这个用户的初始组。
这个字段并没有什么重要的用途,只是用来解释这个用户的意义而已。
也就是用户登录后有操作权限的访问目录,通常称为用户的主目录。
例如,root 超级管理员账户的主目录为 /root,普通用户的主目录为 /home/yourIDname,即在 /home/ 目录下建立和用户名相同的目录作为主目录,如 lamp 用户的主目录就是 /home/lamp/ 目录。
Shell 就是 Linux 的命令解释器,是用户和 Linux 内核之间沟通的桥梁。
我们知道,用户登陆 Linux 系统后,通过使用 Linux 命令完成操作任务,但系统只认识类似 0101 的机器语言,这里就需要使用命令解释器。也就是说,Shell 命令解释器的功能就是将用户输入的命令转换成系统可以识别的机器语言。
通常情况下,Linux 系统默认使用的命令解释器是 bash(/bin/bash),当然还有其他命令解释器,例如 sh、csh 等。
在 /etc/passwd 文件中,大家可以把这个字段理解为用户登录之后所拥有的权限。如果这里使用的是 bash 命令解释器,就代表这个用户拥有权限范围内的所有权限。例如:
[root@localhost ~]# vi /etc/passwd
lamp:x:502:502::/home/lamp:/bin/bash
用户名:密码:UID(用户ID):GID(组ID):描述性信息:主目录:默认Shell
我手工添加了 lamp 用户,它使用的是 bash 命令解释器,那么这个用户就可以使用普通用户的所有权限。
如果我把 lamp 用户的 Shell 命令解释器修改为 /sbin/nologin,那么,这个用户就不能登录了,例如:
[root@localhost ~]# vi /etc/passwd
lamp:x:502:502::/home/lamp:/sbin/nologin
因为 /sbin/nologin 就是禁止登录的 Shell。同样,如果我在这里放入的系统命令,如 /usr/bin/passwd,例如:
[root@localhost ~]#vi /etc/passwd
lamp:x:502:502::/home/lamp:/usr/bin/passwd
那么这个用户可以登录,但登录之后就只能修改自己的密码。但是,这里不能随便写入和登陆没有关系的命令(如 ls),系统不会识别这些命令,同时也就意味着这个用户不能登录。
/etc/shadow 文件,用于存储 Linux 系统中用户的密码信息,又称为“影子文件”。
前面介绍了 /etc/passwd 文件,由于该文件允许所有用户读取,易导致用户密码泄露,因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中分离出来,并单独放到了此文件中。
/etc/shadow 文件只有 root 用户拥有读权限,其他用户没有任何权限,这样就保证了用户密码的安全性。
注意,如果这个文件的权限发生了改变,则需要注意是否是恶意攻击。
介绍此文件之前,我们先打开看看,执行如下命令:
[root@localhost ~]#vim /etc/shadow
root: $6$9w5Td6lg
$bgpsy3olsq9WwWvS5Sst2W3ZiJpuCGDY.4w4MRk3ob/i85fl38RH15wzVoom ff9isV1 PzdcXmixzhnMVhMxbvO:15775:0:99999:7:::
bin:*:15513:0:99999:7:::
daemon:*:15513:0:99999:7:::
…省略部分输出…
同 /etc/passwd 文件一样,文件中每行代表一个用户,同样使用 ":" 作为分隔符,不同之处在于,每行用户信息被划分为 9 个字段。每个字段的含义如下:
用户名:加密密码:最后一次修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留字段
接下来,给大家分别介绍这 9 个字段。
同 /etc/passwd 文件的用户名有相同的含义。
这里保存的是真正加密的密码。目前 Linux 的密码采用的是 SHA512 散列加密算法,原来采用的是 MD5 或 DES 加密算法。SHA512 散列加密算法的加密等级更高,也更加安全。
注意,这串密码产生的乱码不能手工修改,如果手工修改,系统将无法识别密码,导致密码失效。很多软件透过这个功能,在密码串前加上 "!"、"*" 或 "x" 使密码暂时失效。
所有伪用户的密码都是 "!!" 或 "*",代表没有密码是不能登录的。当然,新创建的用户如果不设定密码,那么它的密码项也是 "!!",代表这个用户没有密码,不能登录。
此字段表示最后一次修改密码的时间,可是,为什么 root 用户显示的是 15775 呢?
这是因为,Linux 计算日期的时间是以 1970 年 1 月 1 日作为 1 不断累加得到的时间,到 1971 年 1 月 1 日,则为 366 天。这里显示 15775 天,也就是说,此 root 账号在 1970 年 1 月 1 日之后的第 15775 天修改的 root 用户密码。
那么,到底 15775 代表的是哪一天呢?可以使用如下命令进行换算:
[root@localhost ~]# date -d "1970-01-01 15775 days"
2013年03月11日 星期一 00:00:00 CST
可以看到,通过以上命令,即可将其换算为我们习惯的系统日期。
最小修改间隔时间,也就是说,该字段规定了从第 3 字段(最后一次修改密码的日期)起,多长时间之内不能修改密码。如果是 0,则密码可以随时修改;如果是 10,则代表密码修改后 10 天之内不能再次修改密码。
此字段是为了针对某些人频繁更改账户密码而设计的。
经常变更密码是个好习惯,为了强制要求用户变更密码,这个字段可以指定距离第 3 字段(最后一次更改密码)多长时间内需要再次变更密码,否则该账户密码进行过期阶段。
该字段的默认值为 99999,也就是 273 年,可认为是永久生效。如果改为 90,则表示密码被修改 90 天之后必须再次修改,否则该用户即将过期。管理服务器时,通过这个字段强制用户定期修改密码。
与第 5 字段相比较,当账户密码有效期快到时,系统会发出警告信息给此账户,提醒用户 "再过 n 天你的密码就要过期了,请尽快重新设置你的密码!"。
该字段的默认值是 7,也就是说,距离密码有效期的第 7 天开始,每次登录系统都会向该账户发出 "修改密码" 的警告信息。
也称为“口令失效日”,简单理解就是,在密码过期后,用户如果还是没有修改密码,则在此字段规定的宽限天数内,用户还是可以登录系统的;如果过了宽限天数,系统将不再让此账户登陆,也不会提示账户过期,是完全禁用。
比如说,此字段规定的宽限天数是 10,则代表密码过期 10 天后失效;如果是 0,则代表密码过期后立即失效;如果是 -1,则代表密码永远不会失效。
同第 3 个字段一样,使用自 1970 年 1 月 1 日以来的总天数作为账户的失效时间。该字段表示,账号在此字段规定的时间之外,不论你的密码是否过期,都将无法使用!
该字段通常被使用在具有收费服务的系统中。
这个字段目前没有使用,等待新功能的加入。
经常有读者会忘记自己的账户密码,该怎么处理呢?
对于普通账户的密码遗失,可以通过 root 账户解决,它会重新给你配置好指定账户的密码,而不需知道你原有的密码(利用 root 的身份使用 passwd 命令即可)。
如果 root 账号的密码遗失,则需要重新启动进入单用户模式,系统会提供 root 权限的 bash 接口,此时可以用 passwd 命令修改账户密码;也可以通过挂载根目录,修改 /etc/shadow,将账户的 root 密码清空的方法,此方式可使用 root 无法密码即可登陆,建议登陆后使用 passwd 命令配置 root 密码。
/ect/group 文件是用户组配置文件,即用户组的所有信息都存放在此文件中。
此文件是记录组 ID(GID)和组名相对应的文件。前面讲过,etc/passwd 文件中每行用户信息的第四个字段记录的是用户的初始组 ID,那么,此 GID 的组名到底是什么呢?就要从 /etc/group 文件中查找。
/etc/group 文件的内容可以通过 Vim 看到:
[root@localhost ~]#vim /etc/group
root:x:0:
bin:x:1:bin,daemon
daemon:x:2:bin,daemon
…省略部分输出…
lamp:x:502:
可以看到,此文件中每一行各代表一个用户组。在前面章节中,我们曾创建 lamp 用户,系统默认生成一个 lamp 用户组,在此可以看到,此用户组的 GID 为 502,目前它仅作为 lamp 用户的初始组。
各用户组中,还是以 ":" 作为字段之间的分隔符,分为 4 个字段,每个字段对应的含义为:
组名:密码:GID:该用户组中的用户列表
接下来,分别介绍各个字段具体的含义。
也就是是用户组的名称,有字母或数字构成。同 /etc/passwd 中的用户名一样,组名也不能重复。
和 /etc/passwd 文件一样,这里的 "x" 仅仅是密码标识,真正加密后的组密码默认保存在 /etc/gshadow 文件中。
不过,用户设置密码是为了验证用户的身份,那用户组设置密码是用来做什么的呢?用户组密码主要是用来指定组管理员的,由于系统中的账号可能会非常多,root 用户可能没有时间进行用户的组调整,这时可以给用户组指定组管理员,如果有用户需要加入或退出某用户组,可以由该组的组管理员替代 root 进行管理。但是这项功能目前很少使用,我们也很少设置组密码。如果需要赋予某用户调整某个用户组的权限,则可以使用 sudo 命令代替。
就是群组的 ID 号,Linux 系统就是通过 GID 来区分用户组的,同用户名一样,组名也只是为了便于管理员记忆。
这里的组 GID 与 /etc/passwd 文件中第 4 个字段的 GID 相对应,实际上,/etc/passwd 文件中使用 GID 对应的群组名,就是通过此文件对应得到的。
此字段列出每个群组包含的所有用户。需要注意的是,如果该用户组是这个用户的初始组,则该用户不会写入这个字段,可以这么理解,该字段显示的用户都是这个用户组的附加用户。
举个例子,lamp 组的组信息为 "lamp:x:502:",可以看到,第四个字段没有写入 lamp 用户,因为 lamp 组是 lamp 用户的初始组。如果要查询这些用户的初始组,则需要先到 /etc/passwd 文件中查看 GID(第四个字段),然后到 /etc/group 文件中比对组名。
每个用户都可以加入多个附加组,但是只能属于一个初始组。所以我们在实际工作中,如果需要把用户加入其他组,则需要以附加组的形式添加。例如,我们想让 lamp 也加入 root 这个群组,那么只需要在第一行的最后一个字段加入 lamp,即 root:x:0:lamp 就可以了。
一般情况下,用户的初始组就是在建立用户的同时建立的和用户名相同的组。
到此,我们已经学习了/etc/passwd、/etc/shadow、/etc/group,它们之间的关系可以这样理解,即先在 /etc/group 文件中查询用户组的 GID 和组名;然后在 /etc/passwd 文件中查找该 GID 是哪个用户的初始组,同时提取这个用户的用户名和 UID;最后通过 UID 到 /etc/shadow 文件中提取和这个用户相匹配的密码。
前面讲过,/etc/passwd 文件存储用户基本信息,同时考虑到账户的安全性,将用户的密码信息存放另一个文件 /etc/shadow 中。本节要将的 /etc/gshadow 文件也是如此,组用户信息存储在 /etc/group 文件中,而将组用户的密码信息存储在 /etc/gshadow 文件中。
首先,我们借助 Vim 命令查看一下此文件中的内容:
[root@localhost ~]#vim /etc/gshadow
root:::
bin:::bin, daemon
daemon:::bin, daemon
...省略部分输出...
lamp:!::
文件中,每行代表一个组用户的密码信息,各行信息用 ":" 作为分隔符分为 4 个字段,每个字段的含义如下:
组名:加密密码:组管理员:组附加用户列表
同 /etc/group 文件中的组名相对应。
对于大多数用户来说,通常不设置组密码,因此该字段常为空,但有时为 "!",指的是该群组没有组密码,也不设有群组管理员。
从系统管理员的角度来说,该文件最大的功能就是创建群组管理员。那么,什么是群组管理员呢?
考虑到 Linux 系统中账号太多,而超级管理员 root 可能比较忙碌,因此当有用户想要加入某群组时,root 或许不能及时作出回应。这种情况下,如果有群组管理员,那么他就能将用户加入自己管理的群组中,也就免去麻烦 root 了。
不过,由于目前有 sudo 之类的工具,因此群组管理员的这个功能已经很少使用了。
该字段显示这个用户组中有哪些附加用户,和 /etc/group 文件中附加组显示内容相同。
通过学习用户和群组我们知道,群组可以让多个用户具有相同的权限,同时也可以这样理解,一个用户可以所属多个群组,并同时拥有这些群组的权限,这就引出了初始组(有时也称主组)和附加组。
《Linux etc/passwd》一节中,已经对用户所属初始组和附加组的概念进行了简单介绍,本节对初始组和附加组做更详细的介绍。
/etc/passwd 文件中每个用户信息分为 7 个字段,其中第 4 字段(GID)指的就是每个用户所属的初始组,也就是说,当用户一登陆系统,立刻就会拥有这个群组的相关权限。
举个例子,我们新建一个用户 lamp,并将其加入 users 群组中,执行命令如下:
[root@localhost ~]# useradd lamp <--添加新用户
[root@localhost ~]# groupadd users <--添加新群组
[root@localhost ~]# usermod -G users lamp <--将用户lamp加入 users群组
[root@localhost ~]# grep "lamp" /etc/passwd /etc/group /etc/gshadow
/etc/passwd:lamp:x:501:501::/home/lamp:/bin/bash
/etc/group:users:x:100:lamp
/etc/group:lamp:x:501:
/etc/gshadow:users:::lamp
/etc/gshadow:lamp:!::
useradd 和 groupadd 分别是添加用户和群组的命令,后续章节会做详细讲解。
可以看到,在 etc/passwd 文件中,lamp 用户所属的 GID(群组 ID)为 501,通过搜索 /etc/group 文件得知,对应此 GID 的是 lamp 群组,也就是说,lamp 群组是 lamp 用户的初始组。
lamp 群组是添加 lamp 用户时默认创建的群组,在 root 管理员使用 useradd 命令创建新用户时,若未明确指定该命令所属的初始组,useradd 命令会默认创建一个同用户名相同的群组,作为该用户的初始组。
正因为 lamp 群组是 lamp 用户的初始组,该用户一登陆就会自动获取相应权限,因此不需要在 /etc/group 的第 4 个字段额外标注。
但是,附加组就不一样了,从例子中可以看到,我们将 lamp 用户加入 users 群组中,由于 users 这个群组并不是 lamp 的初始组,因此必须要在 /etc/group 这个文件中找到 users 那一行,将 lamp 这个用户加入第 4 段中(群组包含的所有用户),这样 lamp 用户才算是真正加入到 users 这个群组中。
在这个例子中,因为 lamp 用户同时属于 lamp 和users 两个群组,所在,在读取\写入\运行文件时,只要是 user 和 lamp 群组拥有的功能,lamp 用户都拥有。
一个用户可以所属多个附加组,但只能有一个初始组。那么,如何知道某用户所属哪些群组呢?使用 groups 命令即可。
例如,我们现在以 lamp 用户的身份登录系统,通过执行如下命令即可知晓当前用户所属的全部群组:
[root@localhost ~]# groups
lamp users
通过以上输出信息可以得知,lamp 用户同时属于 lamp 群组和 users 群组,而且,第一个出现的为用户的初始组,后面的都是附加组,所以 lamp 用户的初始组为 lamp 群组,附加组为 users 群组。
/etc/login.defs 文件用于在创建用户时,对用户的一些基本属性做默认设置,例如指定用户 UID 和 GID 的范围,用户的过期时间,密码的最大长度,等等。
需要注意的是,该文件的用户默认配置对 root 用户无效。并且,当此文件中的配置与 /etc/passwd 和 /etc/shadow 文件中的用户信息有冲突时,系统会以/etc/passwd 和 /etc/shadow 为准。
读者可自行使用 vim /etc/login.defs
命令查看该文件中的内容,表 1 中对文件中的各个选项做出了具体的解释。
设置项 | 含义 |
---|---|
MAIL_DIR /var/spool/mail | 创建用户时,系统会在目录 /var/spool/mail 中创建一个用户邮箱,比如 lamp 用户的邮箱是 /var/spool/mail/lamp。 |
PASS_MAX_DAYS 99999 | 密码有效期,99999 是自 1970 年 1 月 1 日起密码有效的天数,相当于 273 年,可理解为密码始终有效。 |
PASS_MIN_DAYS 0 | 表示自上次修改密码以来,最少隔多少天后用户才能再次修改密码,默认值是 0。 |
PASS_MIN_LEN 5 | 指定密码的最小长度,默认不小于 5 位,但是现在用户登录时验证已经被 PAM 模块取代,所以这个选项并不生效。 |
PASS_WARN_AGE 7 | 指定在密码到期前多少天,系统就开始通过用户密码即将到期,默认为 7 天。 |
UID_MIN 500 | 指定最小 UID 为 500,也就是说,添加用户时,默认 UID 从 500 开始。注意,如果手工指定了一个用户的 UID 是 550,那么下一个创建的用户的 UID 就会从 551 开始,哪怕 500~549 之间的 UID 没有使用。 |
UID_MAX 60000 | 指定用户最大的 UID 为 60000。 |
GID_MIN 500 | 指定最小 GID 为 500,也就是在添加组时,组的 GID 从 500 开始。 |
GID_MAX 60000 | 用户 GID 最大为 60000。 |
CREATE_HOME yes | 指定在创建用户时,是否同时创建用户主目录,yes 表示创建,no 则不创建,默认是 yes。 |
UMASK 077 | 用户主目录的权限默认设置为 077。 |
USERGROUPS_ENAB yes | 指定删除用户的时候是否同时删除用户组,准备地说,这里指的是删除用户的初始组,此项的默认值为 yes。 |
ENCRYPT_METHOD SHA512 | 指定用户密码采用的加密规则,默认采用 SHA512,这是新的密码加密模式,原先的 Linux 只能用 DES 或 MD5 加密。 |
Linux 系统中,可以使用 useradd 命令新建用户,此命令的基本格式如下:
[root@localhost ~]#useradd [选项] 用户名
该命令常用的选项及各自的含义,如表 1 所示。
选项 | 含义 |
---|---|
-u UID | 手工指定用户的 UID,注意 UID 的范围(不要小于 500)。 |
-d 主目录 | 手工指定用户的主目录。主目录必须写绝对路径,而且如果需要手工指定主目录,则一定要注意权限; |
-c 用户说明 | 手工指定/etc/passwd文件中各用户信息中第 5 个字段的描述性内容,可随意配置; |
-g 组名 | 手工指定用户的初始组。一般以和用户名相同的组作为用户的初始组,在创建用户时会默认建立初始组。一旦手动指定,则系统将不会在创建此默认的初始组目录。 |
-G 组名 | 指定用户的附加组。我们把用户加入其他组,一般都使用附加组; |
-s shell | 手工指定用户的登录 Shell,默认是 /bin/bash; |
-e 曰期 | 指定用户的失效曰期,格式为 "YYYY-MM-DD"。也就是 /etc/shadow 文件的第八个字段; |
-o | 允许创建的用户的 UID 相同。例如,执行 "useradd -u 0 -o usertest" 命令建立用户 usertest,它的 UID 和 root 用户的 UID 相同,都是 0; |
-m | 建立用户时强制建立用户的家目录。在建立系统用户时,该选项是默认的; |
-r | 创建系统用户,也就是 UID 在 1~499 之间,供系统程序使用的用户。由于系统用户主要用于运行系统所需服务的权限配置,因此系统用户的创建默认不会创建主目录。 |
其实,系统已经帮我们规定了非常多的默认值,在没有特殊要求下,无需使用任何选项即可成功创建用户。例如:
[root@localhost ~]# useradd lamp
此行命令就表示创建 lamp 普通用户。
不要小看这条简单的命令,它会完成以下几项操作:
[root@localhost ~]# grep "lamp" /etc/passwd
lamp:x:500:500::/home/lamp:/bin/bash
[root@localhost ~]# grep "lamp" /etc/shadow
lamp:!!:15710:0:99999:7:::
[root@localhost ~]# grep "lamp" /etc/group
lamp:x:500:
[root@localhost ~]# grep "lamp" /etc/gshadow
lamp:!::
[root@localhost ~]#ll -d /home/lamp/
drwx------ 3 lamp lamp 4096 1月6 00:19 /home/lamp/
[root@localhost ~]#ll /var/spod/mail/lamp
-rw-rw---- 1 lamp mail 0 1月6 00:19 /var/spool/mail/lamp
可以看到,useradd 命令创建用户的过程,其实就是修改了与用户相关的几个文件或目录,前面章节已经对这些文件做了详细介绍。
除了默认创建用户,我们还可以利用 useradd 命令的各种选项亲自定制要创建的用户,例如:
[root@localhost ~]# groupadd lamp1
#先手工添加lamp1用户组,因为我一会儿要把lamp1用户的初始迎指定过来,如果不事先建立,则会报告用户组不存在
[root@localhost ~]# useradd -u 550 -g lamp1 -G root -d /home/lamp1 -c "test user" -s /bin/bash lamp1
#在建立用户lamp1的同时,指定了UID(550)、初始组(lamp1)、附加组(root)、家目录(/home/lamp1/)、用户说明(test user)和用户登录Shell(/bin/bash)
[root@localhost ~]# grep "lamp1" /etc/passwd /etc/shadow /etc/group
#同时查看三个文件
/etc/passwd:lamp1:x:550:502:test user:/home/lamp1:/bin/bash
#用户的UID、初始组、用户说明、家目录和登录Shell都和命令手工指定的一致
/etc/shadow:lamp1:!!:15710:0:99999:7:::
#lamp1用户还没有设定密码
/etc/group:root:x:0:lamp1
#lamp1用户加入了root组,root组是lamp1用户的附加组
/etc/group:lampl:x:502:
#GID为502的组是lamp1组
[root@localhost ~]#ll -d /home/lamp1/
drwx------ 3 lamp1 lamp1 4096 1月6 01:13 /home/lamp1/
#家目录也建立了,不需要手工建立
通过以上 2 种方式,都可以成功创建用户。通常情况下,根本不需要手工指定任何内容,因为使用默认值就可以满足我们的要求。那你有没有想过,useradd 命令的这些默认值保存哪里,能否手工修改呢?
答案是肯定的。useradd 命令在添加用户时参考的默认值文件主要有两个,分别是 /etc/default/useradd 和 /etc/login.defs。前面我们已经详细介绍了 /etc/login.defs,这里不再过多赘述,本节带大家详细了解 /etc/default/useradd 文件。
首先,使用 Vim 命令查看 /etc/default/useradd 文件中包含哪些内容:
[root@localhost ~]#vim /etc/default/useradd
# useradd defaults file
GR0UP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
另外,也可以直接通过命令进行查看,结果是一样的:
[root@localhost ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/bash
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
-D 选项指的就是查看新建用户的默认值。
表 2 对此文件中的各项做了详细的解释。
参数 | 含义 |
---|---|
GR0UP=100 | 这个选项用于建立用户的默认组,也就是说,在添加每个用户时,用户的初始组就是 GID 为 100 的这个用户组。但 CentOS 并不是这样的,而是在添加用户时会自动建立和用户名相同的组作为此用户的初始组。也就是说这个选项并不会生效。 Linux 中默认用户组有两种机制:一种是私有用户组机制,系统会创建一个和用户名相同的用户组作为用户的初始组;另一种是公共用户组机制,系统用 GID 是 100 的用户组作为所有新建用户的初始组。目前我们采用的是私有用户组机制。 |
HOME=/home | 指的是用户主目录的默认位置,所有新建用户的主目录默认都在 /home/下,刚刚新建的 lamp1 用户的主目录就为 /home/lamp1/。 |
INACTIVE=-1 | 指的是密码过期后的宽限天数,也就是 /etc/shadow 文件的第七个字段。这里默认值是 -1,代表所有新建立的用户密码永远不会失效。 |
EXPIRE= | 表示密码失效时间,也就是 /etc/shadow 文件的第八个字段。默认值是空,代表所有新建用户没有失效时间,永久有效。 |
SHELL=/bin/bash | 表示所有新建立的用户默认 Shell 都是 /bin/bash。 |
SKEL=/etc/skel | 在创建一个新用户后,你会发现,该用户主目录并不是空目录,而是有 .bash_profile、.bashrc 等文件,这些文件都是从 /etc/skel 目录中自动复制过来的。因此,更改 /etc/skel 目录下的内容就可以改变新建用户默认主目录中的配置文件信息。 |
CREATE_MAIL_SPOOL=yes | 指的是给新建用户建立邮箱,默认是创建。也就是说,对于所有的新建用户,系统都会新建一个邮箱,放在 /var/spool/mail/ 目录下,和用户名相同。例如,lamp1 的邮箱位于 /var/spool/mail/lamp1。 |
注意,此文件中各选项值的修改方式有 2 种,一种是通过 Vim 文本编辑器手动修改,另一种就是使用文章开头介绍的 useradd 命令,不过所用的命令格式发生了改变:
useradd -D [选项] 参数
用此命令修改 /etc/default/useradd 文件,可使用的选项如表 3 所示。
选项+参数 | 含义 |
---|---|
-b HOME | 设置所创建的主目录所在的默认目录,只需用目录名替换 HOME 即可,例如 useradd -D -b /gargae。 |
-e EXPIRE | 设置密码失效时间,EXPIRE 参数应使用 YYYY-MM-DD 格式,例如 useradd -D -e 2019-10-17。 |
-f INACTIVE | 设置密码过期的宽限天数,例如 useradd -D -f 7。 |
-g GROUP | 设置新用户所在的初始组,例如 useradd -D -g bear。 |
-s SHELL | 设置新用户的默认 shell,SHELL 必须是完整路径,例如 useradd -D -s /usr/bin/csh。 |
例如,要修改新用户的默认 Shell 为 /bin/csh,可以使用如下方式:
[root@localhost ~]# useradd -D -s /bin/csh
[root@localhost ~]# useradd -D
GROUP=100
HOME=/home
INACTIVE=-1
EXPIRE=
SHELL=/bin/csh
SKEL=/etc/skel
CREATE_MAIL_SPOOL=yes
通过 /etc/default/useradd 文件,大家仅能修改有关新用户的部分默认值,有一些内容并没有在这个文件中,例如修改用户默认的 UID、GID,以及对用户密码的默认设置,对这些默认值的修改就需要在 /etc/login.defs 文件中进行。
有关 /etc/login.defs 文件,可阅读《Linux /etc/login.defs》一节。
其实,useradd 命令创建用户的过程是这样的,系统首先读取 /etc/login.defs 和 /etc/default/useradd,根据这两个配置文件中定义的规则添加用户,也就是向 /etc/passwd、/etc/group、/etc/shadow、/etc/gshadow 文件中添加用户数据,接着系统会自动在 /etc/default/useradd 文件设定的目录下建立用户主目录,最后复制 /etc/skel 目录中的所有文件到此主目录中,由此,一个新的用户就创建完成了。
当然,如果你能彻底掌握 useradd 命令创建用户的整个过程,完全可以手动创建用户。
学习 useradd 命令我们知道,使用此命令创建新用户时,并没有设定用户密码,因此还无法用来登陆系统,本节就来学习 passwd 密码配置命令 。
passwd 命令的基本格式如下:
[root@localhost ~]#passwd [选项] 用户名
选项:
例如,我们使用 root 账户修改 lamp 普通用户的密码,可以使用如下命令:
[root@localhost ~]#passwd lamp
Changing password for user lamp.
New password: <==直接输入新的口令,但屏幕不会有任何反应
BAD PASSWORD: it is WAY too short <==口令太简单或过短的错误!这里只是警告信息,输入的密码依旧能用
Retype new password: <==再次验证输入的密码,再输入一次即可
passwd: all authentication tokens updated successfully. <==提示修改密码成功
当然,也可以使用 passwd 命令修改当前系统已登录用户的密码,但要注意的是,需省略掉 "选项" 和 "用户名"。例如,我们登陆 lamp 用户,并使用 passwd 命令修改 lamp 的登陆密码,执行过程如下:
[root@localhost ~]#passwd
#passwd直接回车代表修改当前用户的密码
Changing password for user vbird2.
Changing password for vbird2
(current) UNIX password: <==这里输入『原有的旧口令』
New password: <==这里输入新口令
BAD PASSWORD: it is WAY too short <==口令检验不通过,请再想个新口令
New password: <==这里再想个来输入吧
Retype new password: <==通过口令验证!所以重复这个口令的输入
passwd: all authentication tokens updated successfully. <==成功修改用户密码
注意,普通用户只能使用 passwd 命令修改自己的密码,而不能修改其他用户的密码。
可以看到,与使用 root 账户修改普通用户的密码不同,普通用户修改自己的密码需要先输入自己的旧密码,只有旧密码输入正确才能输入新密码。不仅如此,此种修改方式对密码的复杂度有严格的要求,新密码太短、太简单,都会被系统检测出来并禁止用户使用。
很多Linux 发行版为了系统安装,都使用了 PAM 模块进行密码的检验,设置密码太短、与用户名相同、是常见字符串等,都会被 PAM 模块检查出来,从而禁止用户使用此类密码。有关 PAM 模块,后续章节会进行详细介绍。
而使用 root 用户,无论是修改普通用户的密码,还是修改自己的密码,都可以不遵守 PAM 模块设定的规则,就比如我刚刚给 lamp 用户设定的密码是 "123",系统虽然会提示密码过短和过于简单,但依然可以设置成功。当然,在实际应用中,就算是 root 身份,在设定密码时也要严格遵守密码规范,因为只有好的密码规范才是服务器安全的基础。
passwd 命令还提供了一些选项,接下来给大家介绍各个选项的具体用法。
【例 1】
#查看用户密码的状态
[root@localhost ~]# passwd -S lamp
lamp PS 2013-01-06 0 99999 7 -1 (Password set, SHA512 crypt.)
#上面这行代码的意思依次是:用户名 密码 设定时间(2013*01-06) 密码修改间隔时间(0) 密码有效期(99999) 警告时间(7) 密码不失效(-1),密码已使用
"-S"选项会显示出密码状态,这里的密码修改间隔时间、密码有效期、警告时间、密码宽限时间其实分别是 /etc/shadow 文件的第四、五、六、七个字段的内容。 当然,passwd 命令是可以通过命令选项修改这几个字段的值的,例如:
#修改 lamp的密码,使其具有 60 天变更、10 天密码失效
[root@localhost ~]# passwd -x 60 -i 10 lamp
[root@localhost ~]# passwd -S lamp
lamp PS 2013-01-06 0 60 7 10 (Password set, SHA512 crypt.)
但我个人认为,还是直接修改 /etc/shadow 文件简单一些。
这里显示 SHA512 为密码加密方式,CentOS 6.3 加密方式已经从 MD5 加密更新到 SHA512 加密,我们不用了解具体的加密算法,只要知道这种加密算法更加可靠和先进就足够了。
【例 2】
#锁定 lamp 用户
[root@localhost ~]# passwd -I lamp
Locking password for user lamp.
passwd:Successg
#用"-S"选项査看状态,很清楚地提示密码已被锁定
[root@localhost ~]# passwd -S lamp
lamp LK 2013-01-06 0 99999 7 -1 (Password locked.)
[root@localhost ~]# grep "lamp" /etc/shadow
lamp:!! $6$ZTq7o/9o $lj07iZ0bzW.D1zBa9CsY43d04onskUCzjwiFMNt8PX4GXJoHX9zA1S C9.i Yzh9LZA4fEM2lg92hM9w/p6NS50.:15711:0:99999:7:::
#可以看到,锁定其实就是在加密密码之前加入了"!!",让密码失效而已
暂时锁定 lamp 用户后,此用户就不能登录系统了。那么,怎么解锁呢?也一样简单,使用如下命令即可:
#解锁 lamp 用户
[root@localhost ~]# passwd -u lamp
Unlocking password for user lamp.
passwd:Success
[root@localhost ~]# passwd -S lamp
lamp PS 2013-01-06 0 99999 7 -1 (Password set, SHA512 crypt.)
#可以看到,锁定状态消失
[root@localhost ~]# grep "lamp" /etc/shadow
lamp: $6$ZTq7cV9o $lj07iZ0bzW.D1zBa9CsY43d04onskUCzjwiFMNt8PX4GXJoHX9zA1S C9.iYz h9LZA4fEM2lg92hM9w/p6NS50.:15711:0:99999:7:::
#密码前面的 "!!" 删除了
【例 3】
#调用管道符,给 lamp 用户设置密码 "123"
[root@localhost ~]# echo "123" | passwd --stdin lamp
Changing password for user lamp.
passwd: all authentication tokens updated successfully.
为了方便系统管理,passwd 命令提供了 --stdin 选项,用于批量给用户设置初始密码。
使用此方式批量给用户设置初始密码,当然好处就是方便快捷,但需要注意的是,这样设定的密码会把密码明文保存在历史命令中,如果系统被攻破,别人可以在 /root/.bash_history 中找到设置密码的这个命令,存在安全隐患。
因此,读者如果使用这种方式修改密码,那么应该记住两件事情:第一,手工清除历史命令;第二,强制这些新添加的用户在第一次登录时必须修改密码(具体方法参考 "chage" 命令)。
注意,并非所有 Linux 发行版都支持使用此选项,使用之前可以使用 man passwd 命令确认当前系统是否支持。