Linux账号与群组系统介绍

一、使用者辨别码:UID与GID

虽然我们使用账号(一个字符串)登入Linux主机,但是Linux主机并不会直接识别我们的账号,而是识别ID(一组数字)。账号仅仅是为了让我们方便记忆,账号与对应的ID存储在/etc/passwd文件中。

在Linux系统中,每个登陆的使用者至少会取得两个ID,一个是使用者ID(UserID,简称UID),而另一个是群组ID(Group ID,简称GID)。每个Linux文件也具有拥有人和拥有群组这两个属性,这利用的就是UID和GID。当我们有要显示文件属性的需求时,系统会依据/etc/passwd与/etc/group的内容,找到UID/GID对应的账号与群组名,然后显示出来。

二、使用者账号

当Linux系统的使用者要登入主机以取得shell的环境来工作时,他首先要通过某个登陆界面输入账号密码(本地的Linux主机一般会提供一个login界面,而远程主机可以使用ssh进行连接)。输入了账号密码后,系统会进行如下的操作:

  1. 先寻找/etc/passwd里面是否有我们要输入的账号,如果没有则跳出,如果有的话将该账号对应的UID与GID(在/etc/group中)读出来,另外,该账号的家目录与shell设定也一并读出来
  2. 接下来核对密码表,这时Linux会进入/etc/shadow里面找出对应的账号与UID,然后核对我们刚刚输入的密码是否相符
  3. 如果一切顺利,就进入shell管理的阶段

由上面的流程我们可以知道,如果我们要登入Linux主机,/etc/passwd和/etc/shadow这两个文件就必须要让系统读取(这是很多攻击者将特殊账号写到/etc/passwd里面的原因)。这两个文件都是和使用者账号有关,且非常重要。/etc/passwd用来管理使用者UID/GID重要参数,/etc/shadow用来管理账号密码资料。接下来简单的介绍这两个文件:

2.1 /etc/passwd文件

这个文件的构造如下:每一行都代表一个账号,有几行就代表有几个账号在我们的系统中。不过需要特别留意的是,里面很多账号是系统正常运作所需要的,我们可以称这些账号为系统账号,例如bin、daemon、adm和nobody等等,这个文件的内容如下:
在这里插入图片描述

以输出内容的第一行(也就是root这行)为例进行解释,可以看到,每一行使用:分开,总共有七个部分,分别是:

  1. 账号名称:这个就是指账号,用来对应UID,例如root的UID对应就是0(在第三部分)
  2. 密码:早期Unix系统的密码就是放在这个位置,但是因为这个文件的特性是所有的程序都能够读取,这样一来很容易造成密码资料被窃取,因此后来将这部分的密码资料放入了/etc/shadow中,所以这里仅显示一个`x`
  3. UID:这个就是使用者辨别码,我们需要了解Linux对于UID的划分:
    id范围该ID使用者特性
    0(系统管理员)当UID为0时,代表这个账号是系统管理员。所以当我们要让其他的账号名称也具有root的权限时,将该账号的UID改为0即可。这也就是说,一个系统上面的管理员并不是只有root。但是,我们并不建议有多个账号的UID为0,这样容易让系统管理员混乱
    1-999(系统账号)保留给系统使用的ID,除了0之外,其他的UID权限与特性都是相同的,预设1000以下的数字让给系统作为保留账号只是一种习惯。

    由于系统上面启动的网络服务或背景服务希望使用较小的权限去运作,所以系统不希望使用root的身份去执行这些服务,因此我们就需要这些权限较小的账号。这些系统账号通常是不可登陆的,所以会有/bin/nologin这个特殊的shell存在

    根据系统账号的由来,可以将它们分为两类:
    1~200:由distributions自行建立的系统账号
    201~999:若使用者有系统账号需求时,可以使用的账号UID
    1000~60000(可登入账号)给一般使用者使用的,事实上,目前的Linux核心已经可以支持到2^32-1这么大的UID号码了
  4. GID:这个与/etc/group有关(其实/etc/group和/etc/passwd差不多,我们用/etc/group来规范群组名称与GID的对应)
  5. 使用者信息说明:这个部分没有什么重要用途,只是用来解释这个账号的意义。但是,当我们使用finger的功能时,这个栏位可以提供很多信息
  6. 家目录:这个是使用者的家目录,以上面为例,root的家目录在/root,所以当root登入后,就会进入/root目录里面了。预设的使用者家目录为/home/yourIDname
  7. Shell:当使用者登入系统后,就会取得一个shell来和系统的核心沟通以进行使用者的操作任务,在这个栏位就指定了预设的shell使用bash。需要注意的是,有一个shell可以用来替代成让账号无法取得shell环境的登陆动作,这就是/sbin/nologin

2.2 /etc/shadow文件

我们知道很多程序的运行都与权限有关,而权限与UID/GID有关。因此各个程序需要读取/etc/passwd来了解不同账号的权限。因此/etc/passwd的权限需要设定为-rw-r--r--,虽然早期的密码也有加密,但是这个密码放在了/etc/passwd的第二部分。这样一来很容易被窃取,加密过的密码也能够通过暴力破解法来找出来。

因为这样的关系,后来发展出将密码移动到/etc/shadow这个文件里面的技术,而且/etc/shadow里面还有很多的密码限制参数。首先我们了解下/etc/shadow文件的结构:
在这里插入图片描述
可以看到/etc/shadow同样以:作为分隔符,仔细数可以发现共有九个部分,这九个部分的用途是这样的:

  1. 账号名称:密码需要和账号进行对应,因此这部分就存储账号,且必须和/etc/passwd相同
  2. 密码:这部分存储的信息就是真正的密码,而且是经过加密后的密码,我们只能看到一些特殊字符。需要注意的是,虽然这些加密后的密码很难被破解,但是很难不等于不会,所以这个文件的预设权限是-rw-------或者是----------,亦即只有root才可以读写。

    另外,由于各种密码编码的技术不一样,因此不同的编码系统会造成这个部分的长度不相同,举例来说,旧式的DES,MD5编码系统产生的密码长度就与目前使用的SHA不同,SHA的密码长度明显比较长,由于固定的编码系统产生的密码长度必须一致,因此,当我们让这个部分的长度改变后,该密码就会失效(算不出来)。很多软件通过这个功能,在这个栏位前加上!或*改变密码部分长度,就会使密码暂时失效了
  3. 最近改动密码的日期:这个部分记录了更改密码那一天的日期,不过需要注意的是,上面显示的是18624,这是因为计算Linux日期的时间是以1970年1月1日作为1而累加的日期,1971年1月1日则为366。
  4. 密码不可被更改的天数:第四部分记录了这个账号的密码在最近一次被更改后需要经过几天才可以再被更改。如果是0的话,表示密码随时可以被更改。这个限制是怕某些用户一再更改密码,如果设定为20天的话,就代表如果我们设定了密码,20天之内都无法改动这个密码
  5. 密码需要重新更改的天数:这个部分可以指定在最近一次更改密码后,在多少天内需要再次的变更密码。我们必须要在这个天数内重新设定我们的密码,否则这个账号的密码将会过期。上面的例子是99999(计算出来大约273年),这代表着密码的变更并不强制。
  6. 密码到期前的警告天数(和第5部分一起使用):当账号的密码有效期快到的时候,系统会依据这个栏位的设定,发出“警告”言论给这个账号,提醒使用者“再过n天密码就要过期了”。上面的例子是7,代表密码到期前的7天之内,系统会警告该用户。
  7. 密码过期后的账号宽限时间(和第5部分一起使用):密码有效日期为更新日期(第三部分)+重新变更日期(第五部分),过了该期限后使用者依旧没有更新密码,那该密码就过期了。虽然密码过期,但是该账号还是可以用来进行其他工作的,包括登入系统取得bash。如果密码过期了,当我们登入系统时,系统会强制要求我们重新设定密码才能继续登陆使用,这就是密码过期特性。

    这个部分的用处就是,在密码过期几天后,如果使用者还是没有登陆更改密码,那么这个账号的密码将会“失效”,亦即该账号再也无法使用这个密码登陆了。要注意密码过期与密码失效是不同的
  8. 账号失效日期:这个日期和第三部分一样,都是使用1970年以来的总日数设定,这个部分表示,这个账号在此部分规定的日期之后,将无法再使用。这就意味着,此时不论我们的密码是否过期,这个账号都不能再被使用,这部分通常被用在收费服务的系统中,我们可以规定一个日期让该账号不能再被使用。
  9. 保留:最后一部分是保留的,看以后有没有新功能加入

举个例子来说明,假如dmtsai这个使用者的密码栏如下所示:

dmtsai:$6$M4IphgNP2TmlXaSS$B418YFroYxxmm....:16559:5:60:7:5:16679:

注意16659代表2015/05/04,所以dmtsai这个使用者的相关信息意义是:

  • 由于密码几乎仅仅能单向运算(由明码计算成为密码,无法由密码反推回明码),因此由上表的信息我们几乎无法得知dmtsai的实际密码
  • 这个账号最近一次更改密码的日期是2015/05/04(16559)
  • 能够再次修改密码的时间是5天后,也就是2015/05/09以前dmtsai不能修改自己的密码;如果使用者还是尝试要更改自己的密码,系统就会出现这样的信息:
    You must wait longer to change your password
    passwd: Authentication token manipulation error
  • 密码过期日期设定为60天后,亦即2015/07/03。这表示使用者必须要在2015/05/09(前五天不能修改)到2015/07/03之间的60天内去修改自己的密码,若2015/07/03之后还是没有更改密码,那么这个密码就过期了
  • 警告日期设定为7天,即密码过期日前的7天,在本例中代表2015/06/26~2015/07/03这七天。如果使用者一直没有更改密码,那么在这七天中,只要dmtsai登入系统就会出现如下的信息:
    Warning: your password will expire in 5 days
  • 如果该账号一直到2015/07/03都没有更改密码,那么密码就过期了。但是由于有五天的宽限天数,因此dmtsai在2015/07/08前都还可以使用旧密码登陆主机。不过登陆的时候会出现强制更改密码的情况,输出类似如下信息:
    You are required to change your password immediately (password aged)
    WARNING: Your password has expired.
    You must change your password now and login again!
    Changing password for user dmtsai.
    Changing password for dmtsai
    (current) UNIX password:
    我们必须要输入一次旧密码及两次新密码后,才能够开始使用系统的各项资源。如果我们在2015/07/08以后尝试以dmtsai登陆的话,那么就会出现如下的错误信息并且无法登陆,因此此时我们的密码已经完全失效:
    Your account has expired; please contact your system administrator
  • 如果使用者在2015/07/03以前变更过密码,那么第三部分的那个16559的天数就会跟着改变,因此,所有的限制日期也会跟着相对变动
  • 无论使用者如何操作,到了16679(大约是2015/09/01左右)账号就失效了

三、有效与初始群组、groups、newgrp

3.1 /etc/group:

这个文件记录了GID与群组名称的对应,测试输出如下:
在这里插入图片描述
这个文件的每一行都代表一个群组,同样以:作为每部分的分隔符,一共分为四部分:

  1. 群组名称:方便人们记忆的群组名,与第三栏位的GID对应
  2. 群组密码:通常不需要设定,群组密码通常是给群组管理员使用的,但是目前已经很少设定群组管理员了。同样这个密码已经移动到/etc/gshadow去了,所以这个栏位仅存在一个x
  3. GID:这个是群组ID
  4. 此群组支持的账号名称:我们知道一个账号可以加入多个群组,某个账号想要加入此群组时,将账号填入这个栏位就可以。举例来说,如果我们想要dmtsai与alex也加入root这个群组,那么就在第一行的后面加上dmtsai,alex(注意不能有空格),变为root:x:0:dmtsai,alex的形式就可以。

我们可以使用一个简单的图示来了解下UID/GID与密码之间的关系:
在这里插入图片描述
可以看到重点是/etc/passwd,其他相关的信息都是根据这个文件去寻找的。下图中,root的UID为0,而GID也是0,去找/etc/group就可以知道GID为0时的群组名称就是root。至于密码的寻找,Linux会找到/etc/shadow与/etc/passwd里面同账号名称的那一行,就是密码相关数据。

在/etc/group里面比较重要的是第四部分,每个使用者都可以拥有多个支持的群组,这就好比我们在学校可以加入多个社团。但这样有一个问题:假如我们同时加入多个群组,那么我们在进行工作时,到底是以哪个群组为准?接下来我们介绍下有效群组的概念。

3.2 初始群组(initial group)

每个使用者在他的/etc/passwd里面的第四部分存储GID,这个GID指代初始群组,也就说,当使用者一登入系统,就立刻拥有这个群组的相关权限(需要注意一点,初始群组的用户不会写在/etc/group的第四部分里面)。举例来说,dmtsai这个使用者的/etc/passwd与/etc/group还有/etc/gshadow相关的内容如下:

[root@study ~]# usermod -a -G users dmtsai  <==先设定好次要群組
[root@study ~]# grep dmtsai /etc/passwd /etc/group /etc/gshadow
/etc/passwd:dmtsai:x:1000:1000:dmtsai:/home/dmtsai:/bin/bash
/etc/group:wheel:x:10:dmtsai    <==次要群组的设定、安裝時指定的
/etc/group:users:x:100:dmtsai   <==次要群组的设定
/etc/group:dmtsai:x:1000:       <==因為是初始群組,所以第四栏位不需要填入账号
/etc/gshadow:wheel:::dmtsai     <==次要群组的设定
/etc/gshadow:users:::dmtsai     <==次要群组的设定
/etc/gshadow:dmtsai:!!::

注意在/etc/passwd里面,dmtsai这个使用者所属的群组的GID为1000,搜索/etc/group可以发现1000就是名为dmtsai的群组,这就是初始群组。因为是初始群组,使用者一登陆就会主动获得,所以不需要在/etc/group的第四部分写入该账号

但是非初始群组的其他群组就不同了,举上面的例子,我们将dmtsai加入users这个群组当中,由于users这个群组并非是dmtsai的初始群组,因此,我们必须要在/etc/group这个文件中,找到users那一行,并且将dmtsai这个账号加入第四部分,这样dmtsai才能够加入users这个群组。

在上面的例子中,dmtsai账号同时支持dmtsai,wheel与usrs这三个群组,因此,在读取/写入/执行文件时,针对群组部分,只要是users,shell与dmtsai这三个群组拥有的功能,dmtsai这个使用者都能够拥有。但是假如我们要建立一个新的文件或者是新的目录,那么这个文件的群组是dmtsai,wheel还是users呢?这时就需要检查下它的有效群组。

3.3 groups:查看有效与支持群组

如果我们以dmtsai这个使用者的身份登入,那么该如何知道所有我们支持的群组呢?这很简单,直接输入groups就可以了,注意s,结果类似这样:

[dmtsai@study ~]$ groups
dmtsai wheel users

在输出的信息中,我们可以知道dmtsai这个用户同时属于dmtsai,wheel及users这三个群组,而且,第一个输出的群组即为有效群组。也就是说,我们的有效群组为dmtsai,此时,如果我们以touch去建立一个新文件,例如touch test,那么这个文件的拥有者为dmtsai,而且群组也是dmtsai:

[dmtsai@study ~]$ touch test
[dmtsai@study ~]$ ll test
-rw-rw-r--. 1 dmtsai dmtsai 0 Jul 20 19:54 test

此时就可以了解什么是有效群组了,通常有效群组的作用是新建文件。

3.4 newgrp:有效群组的切换

使用newgrp可以变更有效群组,但是newgrp是有限制的,那就是我们想要切换的群组必须是账号已经支持的群组。举例来说,dmtsai可以在dmtsai/wheel/users这三个群组间切换有效群组,但是dmtsai无法切换有效群组成为sshd。具体的使用方式如下所示:

[dmtsai@study ~]$ newgrp users
[dmtsai@study ~]$ groups
users wheel dmtsai
[dmtsai@study ~]$ touch test2
[dmtsai@study ~]$ ll test*
-rw-rw-r--. 1 dmtsai dmtsai 0 Jul 20 19:54 test
-rw-r--r--. 1 dmtsai users  0 Jul 20 19:56 test2
[dmtsai@study ~]$ exit   # 离开newgrp的环境

此时dmtsai的有效群组就变成了users了。newgrp指令变更目前使用者的有效群组,是以另外一个shell来提供这个功能的。以上面的例子来说,dmtsai这个使用者目前是以另一个shell登陆的,而且新的shell给予dmtsai有效GID为users。以图示来看如下所示:
在这里插入图片描述
虽然使用者的环境设定(例如环境变量等其他信息)不会有影响,但是使用者的群组权限将会被重新计算。但是需要注意,由于是新取得一个shell,因此如果我们想要回到原本的环境中,要输入exit来回到原本的shell中。

因此,只要账号加入的群组就能够切换为有效群组,现在问题就是如何让一个账号加入群组,这有两个方式:第一种是通过系统管理员(root)利用usermod来帮助我们加入,另一种是通过群组管理员利用gpasswd来帮助我们加入。

3.5 /etc/gshadow

输出文件的部分内容,如下所示:

[root@study ~]# head -n 4 /etc/gshadow
root:::
bin:::
daemon:::
sys:::

可以看到这个文件内部同样使用:来做为分割每部分的标识,而且我们可以发现,这个文件和/etc/group几乎一摸一样。我们需要注意的是第二部分,这里存储密码,如果这部分内容为空或者为!时,表明该群组没有群组管理员。第四部分存储群组支持的账号名称,这四个部分的含义分别是:

  1. 群组名称
  2. 密码
  3. 群组管理员的账号
  4. 加入该群组的账号
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值