第14章、 Linux 账号管理与 ACL 权限设定

14.1. Linux 的账号与群组
管理员的工作中,相当重要的一环就是『管理账号』!因为整个系统都是你在管理的, 并且所有一般用户的账号申请,都必须要透过你的协助才行!所以你就必须要了解一下如何管理好一个服务器主机的账号! 在管理 Linux 主机的账号时,我们必须先来了解一下 Linux 到底是如何辨别每一个使用的!

14.1.1. 使用者标识符: UID 与 GID
虽然我们登入 Linux 主机的时候,输入的是我们的账号,但是其实 Linux 主机并不会直接认识你的『账号名称』的,他仅认识 ID (ID 就是一组号码)。 由于计算机仅认识 0 与 1,所以主机对于数字比较有概念的;至于账号只是为了让人们容易记忆而已。 而你的 ID 与账号的对应就在 /etc/passwd 当中。
那么到底有几种 ID 呢?还让得我们在第六章内有提到过, 每一个档案都具有『拥有人与拥有群组』的属性吗?每个登入的使用者至少都会取得两个 ID ,一个是使用者 ID (User ID ,简称 UID)、一个是群组 ID (Group ID ,简称 GID)。
那么档案如何判别他的拥有者与群组呢?其实就是利用 UID 与 GID !每一个档案都会有所谓的拥有者 ID 与拥有群组 ID ,当我们有要显示文件属性的需求时,系统会依据 /etc/passwd 与 /etc/group 的内容, 找到UID / GID 对应的账号与组名再显示出来!我们可以作个小实验,你可以用 root 的身份 vi /etc/passwd ,然后将你的一般身份的使用者的 ID 随便改一个号码,然后再到你的一般身份的目录下看看原先该账号拥有的档案,你会发现该档案的拥有人变成了 『数字了』!这样可以理解了吗?来看看底下的例子:
这里写图片描述
你一定要了解的是,上面的例子仅是在说明 UID 与账号的对应性,在一部正常运作的 Linux 主机环境下,上面的动作不可随便进行, 这是因为系统上已经有很多的数据被建立存在了,随意修改系统上某些账号的 UID 很可能会导致某些程序无法进行,这将导致系统无法顺利运作的结果。 因为权限的问题!所以,了解了之后,请赶快回到 /etc/passwd 里面,将数字改回来!

14.1.2. 使用者账号:/etc/passwd 档案结构, /etc/shadow 档案结构
Linux 系统上面的用户如果需要登入主机以取得 shell 的环境来工作时,他需要如何进行呢? 首先,他必须要在计算机前面利用 tty1~tty7 的终端机提供的 login 接口,并输入账号与密码后才能够登入。 如果是透过网络的话,那至少使用者就得要学习 ssh 这个功能了 (服务器篇再来谈)。 那么你输入账号密码后,系统帮你处理了什么呢?

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

大致上的情况就像这样,所以当你要登入你的 Linux 主机的时候,那个 /etc/passwd 与 /etc/shadow 就必须要让系统读取 (这也是很多攻击者会将特殊账号写到 /etc/passwd 里头去的缘故),所以如果你要备份 Linux 的系统的账号的话,那么这两个档案就一定需要备份才行!
由上面的流程我们也知道,跟使用者账号有关的有两个非常重要的档案,一个是管理使用者 UID/GID 重要参数的 /etc/passwd ,一个则是与门管理密码相关数据的 /etc/shadow !那这两个档案的内容就非常值得进行研究! 底下我们会简单的介绍这两个档案,详细的说明可以参考 man 5 passwd 及 man 5 shadow (注1)。

一、/etc/passwd 档案结构
这个档案的构造是这样的:每一行都代表一个账号,有几行就代表有几个账号在你的系统中! 不过需要特别留意的是,里头很多账号本来就是系统正常运作所必须要的,我们可以简称他为系统账号, 例如 bin, daemon, adm, nobody 等等,这些账号请不要随意的杀掉他! 这个档案的内容有点像这样:
这里写图片描述
我们先来看一下每个 Linux 系统都会有的第一行,就是 root 这个系统管理员那一行好了, 你可以明显的看出来,每一行使用『:』分隔开,共有七个咚咚,分别是:

  1. 账号名称: 就是账号!用来对应 UID 的。例如 root 的 UID 对应就是 0 (第三字段);
  2. 密码: 早期 Unix 系统的密码就是放在这字段上!但是因为这个档案的特性是所有的程序都能够读取,这样一来很容易造成密码数据被窃取, 因此后来就将这个字段的密码数据给他改放到 /etc/shadow 中了。所以这里你会看到一个『 x 』!
  3. UID: 这个就是使用者标识符!通常 Linux 对于 UID 有几个限制需要说给您了解一下:
    这里写图片描述
  4. 上面这样说明可以了解了吗?是的, UID 为 0 的时候,就是 root !所以请特别留意一下你的 /etc/passwd 档案!
  5. GID: 这个与 /etc/group 有关!其实 /etc/group 的观念与 /etc/passwd 差不多,只是他是用来规范组名与 GID 的对应而已!
  6. 用户信息说明栏: 这个字段基本上并没有什么重要用途,只是用来解释这个账号的意义而已!不过,如果您提供使用 finger 的功能时, 这个字段可以提供很多的讯息!本章后面的 chfn 指令会来解释这里的说明。
  7. 家目录: 这是用户的家目录,以上面为例, root 的家目录在 /root ,所以当 root 登入之后,就会立刻跑到 /root 目录里头! 如果你有个账号的使用空间特别的大,你想要将该账号的家目录移动到其他的硬盘去该怎么作?可以在这个字段进行修改!默认的用户家目录在 /home/yourIDname;
  8. Shell: 我们在第十一章 BASH 提到很多次,当用户登入系统后就会取得一个 Shell 来与系统的核心沟通以进行用户的操作任务。那为何预设 shell 会使用 bash 呢?就是在这个字段指定的! 这里比较需要注意的是,有一个 shell 可以用来替代成让账号无法取得 shell 环境的登入动作!那就是 /sbin/nologin 这个东西!这也可以用来制作纯 pop 邮件账号者的数据!

二、/etc/shadow 档案结构
我们知道很多程序的运作都与权限有关,而权限与 UID/GID 有关!因此各程序当然需要读取 /etc/passwd 来了解不同账号的权限。 因此 /etc/passwd 的权限需设定为 -rw-r–r– 这样的情况, 虽然早期的密码也有加密过,但即放置到 /etc/passwd 的第二个字段上!这样一来很容易被有心人士所窃取的, 加密过的密码也能够透过暴力破解法去 try and error (试误) 找出来!
因为这样的关系,所以后来发展出将密码移动到 /etc/shadow 这个档案分隔开来的技术, 而且还加入很多的密码限制参数在 /etc/shadow 里头!在这里,我们先来了解一下这个档案的构造! /etc/shadow 档案有点像这样:
这里写图片描述
基本上, shadow 同样以『:』作为分隔符,如果数一数,会发现共有九个字段,这九个字段的用途是这样的:

  1. 账号名称:
    由于密码也需要与账号对应啊。因此,这个档案的第一栏就是账号,必须要与 /etc/passwd 相同才行!

  2. 密码:
    这个字段内的数据才是真正的密码,而且是经过编码的密码 (加密) ! 你只会看到有一些特殊符号的字母就是了!需要特别留意的是,虽然这些加密过的密码很难被解出来, 但是『很难』不等于『不会』,所以,这个档案的预设权限是『-rw——-』或者是『-r——–』,亦即只有 root 才可以读写就是了!你得随时注意,不要不小心更动了这个档案的权限! 另外,由于各种密码编码的技术不一样,因此不同的编码系统会造成这个字段的长度不相同。 举例来说,旧式的 DES 编码系统产生的密码长度就与目前惯用的 MD5 不同(注2) !MD5 的密码长度明显的比较长些。由于固定的编码系统产生的密码长度必须一致,因此『当你让这个字段的长度改变后,该密码就会失效(算不出来)』。 很多软件透过这个功能,在此字段前加上 ! 或 * 改变密码字段长度,就会让密码『暂时失效』了。

  3. 最近更动密码的日期:
    这个字段记录了『更加密码那一天』的日期,不过,很奇怪!在我的例子中怎么会是 14126 呢?这个是因为计算 Linux 日期的时间是以 1970 年 1 月 1 日作为 1 而累加的日期,1971 年 1 月 1 日则为 366 ! 得注意一下这个资料!上述的 14126 指的就是 2008-09-04 那一天! 而想要了解该日期可以使用本章后面 chage 指令的帮忙!至于想要知道某个日期的累积日数, 可使用如下的程序计算:
    这里写图片描述
    上述指令中,2008/09/04 为你想要计算的日期,86400 为每一天的秒数, %s 为 1970/01/01 以来的累积总秒数。 由于 bash 仅支持整数,因此最终需要加上 1 补齐 1970/01/01 当天。

  4. 密码不可被更动的天数:(与第 3 字段相比)
    第四个字段记录了:这个账号的密码在最近一次被更改后需要经过几天才可以再被变更!如果是 0 的话, 表示密码随时可以更动的意思。这的限制是为了怕密码被某些人一改再改而设计的!如果设定为 20 天的话,那么当你设定了密码之后, 20 天之内都无法改变这个密码!

  5. 密码需要重新变更的天数:(与第 3 字段相比)
    经常变更密码是个好习惯!为了强制要求用户变更密码,这个字段可以指定在最近一次更改密码后, 在多少天数内需要再次的变更密码才行。你必须要在这个天数内重新设定你的密码,否则这个账号的密码将会『变为过期特性』。 而如果像上面的 99999 (计算为 273 年) 的话,那就表示,密码的变更没有强制性之意。

  6. 密码需要变更期限前的警告天数:(与第 5 字段相比)
    当账号的密码有效期限快要到的时候 (第 5 字段),系统会依据这个字段的设定,发出『警告』言论给这个账号,提醒他『再过 n 天你的密码就要过期了,请尽快重新设定你的密码!』,如上面的例子,则是密码到期之前的 7 天之内,系统会警告该用户。

  7. 密码过期后的账号宽限时间(密码失效日):(与第 5 字段相比)
    密码有效日期为『更新日期(第3字段)』+『重新变更日期(第5字段)』,过了该期限后用户依旧没有更新密码,那该密码就算过期了。 虽然密码过期但是该账号还是可以用来进行其他工作的,包括登入系统取得 bash 。不过如果密码过期了, 那当你登入系统时,系统会强制要求你必须要重新设定密码才能登入继续使用,这就是密码过期特性。 那这个字段的功能是什么呢?是在密码过期几天后,如果使用者还是没有登入更改密码,那么这个账号的密码将会『失效』, 亦即该账号再也无法使用该密码登入了。要注意密码过期与密码失效并不相同。

  8. 账号失效日期:
    这个日期跟第三个字段一样,都是使用 1970 年以来的总日数设定。这个字段表示: 这个账号在此字段规定的日期之后,将无法再使用。 就是所谓的『账号失效』,此时不论你的密码是否有过期,这个『账号』都不能再被使用! 这个字段会被使用通常应该是在『收费服务』的系统中,你可以规定一个日期让该账号不能再使用!

  9. 保留:
    最后一个字段是保留的,看以后有没有新功能加入。

举个例子来说好了,假如我的 dmtsai 这个用户的密码栏如下所示:
这里写图片描述
这表示什么呢?先要注意的是 14299 是 2009/02/24 。所以 dmtsai 这个用户的密码相关意义是:

  • 由于密码几乎仅能单向运算(由明码计算成为密码,无法由密码反推回明码),因此由上表的数据我们无法得知 dmstai 的实际密码明文;
  • 此账号最近一次更动密码的日期是 2009/02/24 (14299);
  • 能够再次修改密码的时间是 5 天以后,也就是 2009/03/01 以前 dmtsai 不能修改自己的密码;如果用户还是尝试要更动自己的密码,系统就会出现这样的讯息:
    这里写图片描述
    画面中告诉我们:你必须要等待更久的时间才能够变更密码之意啦!
  • 由于密码过期日期定义为 60 天后,亦即累积日数为: 14299+60=14359,经过计算得到此日数代表日期为 2009/04/25。 这表示:『使用者必须要在 2009/03/01 到 2009/04/25 之间的 60 天限制内去修改自己的密码,若 2009/04/25 之后还是没有变更密码时,该密码就宣告为过期』了!
  • 警告日期设为 7 天,亦即是密码过期日前的 7 天,在本例中则代表 2009/04/19 ~ 2009/04/25 这七天。 如果用户一直没有更改密码,那么在这 7 天中,只要 dmtsai 登入系统就会发现如下的讯息:
    这里写图片描述
  • 如果该账号一直到 2009/04/25 都没有更改密码,那么密码就过期了。但是由于有 5 天的宽限天数, 因此 dmtsai 在 2009/04/30 前都还可以使用旧密码登入主机。 不过登入时会出现强制更改密码的情况,画面有点像底下这样:
    这里写图片描述
  • 你必须要输入一次旧密码以及两次新密码后,才能够开始使用系统的各项资源。如果你是在 2009/04/30 以后尝试以 dmtsai 登入的话,那么就会出现如下的错误讯息且无法登入,因为此时你的密码就失效了!
    这里写图片描述
  • 如果使用者在 2009/04/25 以前变更过密码,那么第 3 个字段的那个 14299 的天数就会跟着改变,因此, 所有的限制日期也会跟着相对变动!
  • 无论使用者如何动作,到了 14419 (大约是 2009/07/24 左右) 该账号就失效了~

透过这样的说明,您应该会比较容易理解了吧?由于 shadow 有这样的重要性,因此可不能随意修改! 但在某些情况底下你得要使用各种方法来处理这个档案的!举例来说,常常听到人家说:『我的密码忘记了』, 或者是『我的密码不晓得被谁改过,跟原先的不一样了』,这个时候怎么办?

  • 一般用户的密码忘记了:这个最容易解决,请系统管理员帮忙, 他会重新设定好你的密码而不需要知道你的旧密码!利用 root 的身份使用 passwd 指令来处理即可。
  • root 密码忘让了:这就麻烦了!因为你无法使用 root 的身份登入了! 但我们知道 root 的密码在 /etc/shadow 当中,因此你可以使用各种可行的方法开机进入 Linux 再去修改。 例如重新启动进入单人维护模式(第二十章)后,系统会主动的给予 root 权限的 bash 接口, 此时再以 passwd 修改密码即可;或以 Live CD 开机后挂载根目录去修改 /etc/shadow,将里面的 root 的密码字段清空, 再重新启动后 root 将不用密码即可登入!登入后再赶快以 passwd 指令去设定 root 密码即可。

14.1.3. 关于群组: /etc/group 档案结构, 有效与初始群组, groups, newgrp, /etc/gshadow
认识了账号相关的两个档案 /etc/passwd 与 /etc/shadow 之后,你或许还是会觉得奇怪, 那么群组的配置文件在哪里?还有,在 /etc/passwd 的第四栏不是所谓的 GID 吗?此时就需要了解 /etc/group 与 /etc/gshadow 了。

一、/etc/group 档案结构
这个档案就是在记录 GID 与组名的对应了,我的测试机的 /etc/group 内容有点像这样:
这里写图片描述
这个档案每一行代表一个群组,也是以冒号『:』作为字段的分隔符,共分为四栏,每一字段的意义是:

  1. 组名:
    就是组名!
  2. 群组密码:
    通常不需要设定,这个设定通常是给『群组管理员』使用的,目前很少有这个机会设定群组管理员! 同样的,密码已经移动到 /etc/gshadow 去,因此这个字段只会存在一个『x』而已;
  3. GID:
    就是群组的 ID 。我们 /etc/passwd 第四个字段使用的 GID 对应的群组名,就是由这里对应出来的!
  4. 此群组支持的账号名称:
    我们知道一个账号可以加入多个群组,那某个账号想要加入此群组时,将该账号填入这个字段即可。 举例来说,如果我想要让 dmtsai 也加入 root 这个群组,那么在第一行的最后面加上『,dmtsai』,注意不要有空格, 使成为『 root:x:0:root,dmtsai 』就可以了~

谈完了 /etc/passwd, /etc/shadow, /etc/group 之后,我们可以使用一个简单的图示来了解一下 UID / GID 与密码之间的关系, 图示如下。其实重点是 /etc/passwd ,其他相关的数据都是根据这个档案的字段去找寻出来的。 下图中, root 的 UID 是 0 ,而 GID 也是 0 ,去找 /etc/group 可以知道 GID 为 0 时的组名就是 root 。 至于密码的寻找中,会找到 /etc/shadow 与 /etc/passwd 内同账号名称的那一行,就是密码相关数据。
这里写图片描述
至于在 /etc/group 比较重要的特色在于第四栏,因为每个使用者都可以拥有多个支持的群组。不过这里你或许会觉得奇怪的,那就是:『假如我同时加入多个群组,那么我在作业的时候,到底是以那个群组为准?』 底下我们就来谈一谈这个『有效群组』的概念。

二、有效群组(effective group)与初始群组(initial group)
还记得每个使用者在他的 /etc/passwd 里面的第四栏有所谓的 GID 吧?那个 GID 就是所谓的『初始群组 (initial group) 』!也就是说,当用户一登入系统,立刻就拥有这个群组的相关权限的意思。 举例来说,我们上面提到 dmtsai 这个使用者的 /etc/passwd 与 /etc/group 还有 /etc/gshadow 相关的内容如下:
这里写图片描述
仔细看到上面这个表格,在 /etc/passwd 里面,dmtsai 这个使用者所属的群组为 GID=504 ,搜寻一下 /etc/group 得到 504 是那个名为 dmtsai 的群组!这就是 initial group。因为是初始群组, 使用者一登入就会主动取得,不需要在 /etc/group 的第四个字段写入该账号的!
但是非 initial group 的其他群组可就不同了。举上面这个例子来说,我将 dmtsai 加入 users 这个群组当中,由于 users 这个群组并非是 dmtsai 的初始群组,因此, 我必须要在 /etc/group 这个档案中,找到 users 那一行,并且将 dmtsai 这个账号加入第四栏, 这样 dmtsai 才能够加入 users 这个群组。
那么在这个例子当中,因为我的 dmtsai 账号同时支持 dmtsai 与 users 这两个群组, 因此,在读取/写入/执行档案时,针对群组部分,只要是 users 与 dmtsai 这两个群组拥有的功能, 我 dmtsai 这个使用者都能够拥有!不过,这是针对已经存在的档案而言, 如果今天我要建立一个新的档案或者是新的目录,请问一下,新档案的群组是 dmtsai 还是 users ?这就得要检查一下当时的有效群组了 (effective group)。

三、groups: 有效与支持群组的观察
如果我以 dmtsai 这个使用者的身份登入后,该如何知道我所有支持的群组呢? 直接输入 groups 就可以了!注意,是 groups 有加 s 呢!结果像这样:
这里写图片描述
在这个输出的讯息中,可知道 dmtsai 这个用户同时属于 dmtsai 及 users 这个两个群组,而且, 第一个输出的群组即为有效群组 (effective group) 了。 也就是说,我的有效群组为 dmtsai 。此时,如果我以 touch 去建立一个新档,例如: 『 touch test 』,那么这个档案的拥有者为 dmtsai ,而且群组也是 dmtsai 的。
这里写图片描述
这样是否可以了解什么是有效群组了?通常有效群组的作用是在新建档案!

四、newgrp: 有效群组的切换
那么如何变更有效群组呢?就使用 newgrp !不过使用 newgrp 是有限制的,那就是你想要切换的群组必须是你已经有支持的群组。举例来说, dmtsai 可以在 dmtsai/users 这两个群组间切换有效群组,但是 dmtsai 无法切换有效群组成为 sshd !使用的方式如下:
这里写图片描述
此时,dmtsai 的有效群组就成为 users 了。 newgrp 这个指令可以变更目前用户的有效群组, 而且是另外以一个 shell 来提供这个功能的,所以,以上面的例子来说, dmtsai 这个使用者目前是以另一个 shell 登入的,而且新的 shell 给予 dmtsai 有效 GID 为 users 就是了。如果以图示来看就是如下所示:
这里写图片描述
虽然用户的环境设定(例如环境变量等等其他数据)不会有影响,但是使用者的『群组权限』将会重新被计算。 但是需要注意,由于是新取得一个 shell ,因此如果你想要回到原本的环境中,请输入 exit 回到原本的 shell !
既然如此,也就是说,只要我的用户有支持的群组就是能够切换成为有效群组!好了, 那么如何让一个账号加入不同的群组就是问题的所在了。你要加入一个群组有两个方式,一个是透过系统管理员 (root) 利用 usermod 帮你加入,如果 root 太忙了而且你的系统有设定群组管理员,那么你可以透过群组管理员以 gpasswd 帮你加入他所管理的群组中!详细的作法留待下一小节再来介绍!

五、/etc/gshadow
刚刚讲了很多关于『有效群组』的概念,另外,也提到 newgrp 这个指令的用法, 但是,如果 /etc/gshadow 这个设定没有搞懂得话,那么 newgrp 是无法动作的! 我测试机的 /etc/gshadow 的内容有点像这样:
这里写图片描述
这个档案内同样还是使用冒号『:』来作为字段的分隔字符,而且你会发现,这个档案几乎与 /etc/group 一模一样啊!是这样没错~不过,要注意的大概就是第二个字段吧~第二个字段是密码栏, 如果密码栏上面是『!』时,表示该群组不具有群组管理员!至于第四个字段也就是支持的账号名称。 这四个字段的意义为:

  1. 组名
  2. 密码栏,同样的,开头为 ! 表示无合法密码,所以无群组管理员
  3. 群组管理员的账号 (相关信息在 gpasswd 中介绍)
  4. 该群组的所属账号 (与 /etc/group 内容相同!)

以系统管理员的角度来说,这个 gshadow 最大的功能就是建立群组管理员! 那么什么是群组管理员呢?由于系统上面的账号可能会很多,但是我们 root 可能平时太忙碌,所以当有使用者想要加入某些群组时, root 或许会没有空管理。此时如果能够建立群组管理员的话,那么该群组管理员就能够将那个账号加入自己管理的群组中 ! 可以免去 root 的忙碌!不过,由于目前有类似 sudo 之类的工具, 所以这个群组管理员的功能已经很少使用了。我们会在后续的 gpasswd 中介绍这个实作。

14.2. 账号管理
既然要管理账号,当然是由新增与移除使用者开始的了。

14.2.1. 新增与移除使用者: useradd, useradd 参考档, passwd, chage, usermod, userdel
要如何在 Linux 的系统新增一个用户啊?我们登入系统时会输入 (1)账号与 (2)密码, 所以建立一个可用的账号同样的也需要这两个数据。那账号可以使用 useradd 来新建用户,密码的给予则使用 passwd 这个指令!这两个指令下达方法如下:

一、useradd
这里写图片描述
这里写图片描述
其实系统已经帮我们规定好非常多的默认值了,所以我们可以简单的使用『 useradd 账号 』来建立使用者即可。 CentOS 这些默认值主要会帮我们处理几个项目:

  • 在 /etc/passwd 里面建立一行与账号相关的数据,包括建立 UID/GID/家目录等;
  • 在 /etc/shadow 里面将此账号的密码相关参数填入,但是尚未有密码;
  • 在 /etc/group 里面加入一个与账号名称一模一样的组名;
  • 在 /home 底下建立一个与账号同名的目录作为用户家目录,且权限为 700

由于在 /etc/shadow 内仅会有密码参数而不会有加密过的密码数据,因此我们在建立使用者账号时, 还需要使用『 passwd 账号 』来给予密码才算是完成了用户建立的流程。如果由于特殊需求而需要改变使用者相关参数时, 就得要透过上述表格中的选项来进行建立了,参考底下的案例:
这里写图片描述
在这个范例中,我们建立的是指定一个已经存在的群组作为使用者的初始群组,因为群组已经存在, 所以在 /etc/group 里面就不会主动的建立与账号同名的群组了! 此外,我们也指定了特殊的 UID 来作为使用者的专属 UID !了解了一般账号后,我们来瞧瞧那啥是系统账号 (system account) 吧!
这里写图片描述
我们在谈到 UID 的时候曾经说过一般账号应该是 500 号以后,那用户自己建立的系统账号则一般是由 100 号以后起算的。 所以在这里我们加上 -r 这个选项以后,系统就会主动将账号与账号同名群组的 UID/GID 都指定小于 500 以下, 在本案例中则是使用 100(UID) 与 103(GID) !此外,由于系统账号主要是用来进行运作系统所需服务的权限设定, 所以系统账号默认都不会主动建立家目录的 !
由这几个范例我们也会知道,使用 useradd 建立使用者账号时,其实会更改不少地方,至少我们就知道底下几个档案:

  • 用户账号与密码参数方面的档案:/etc/passwd, /etc/shadow
  • 使用者群组相关方面的档案:/etc/group, /etc/gshadow
  • 用户的家目录:/home/账号名称

为何『 useradd vbird1 』会主动在 /home/vbird1 建立起用户的家目录?家目录内有什么数据且来自哪里?为何预设使用的是 /bin/bash 这个 shell ?为何密码字段已经都规范好了 (0:99999:7 那一串)?这就得要说明一下 useradd 所使用的参考档案了!

二、useradd 参考档
其实 useradd 的默认值可以使用底下的方法呼叫出来:
这里写图片描述
这个数据其实是由 /etc/default/useradd 呼叫出来的!你可以自行用 vim 去观察该档案的内容。搭配上头刚刚谈过的范例一的运作结果,上面这些设定项目所造成的行为分别是:

  • GROUP=100:新建账号的初始群组使用 GID 为 100 者
    系统上面 GID 为 100 者即是 users 这个群组,此设定项目指的就是让新设使用者账号的初始群组为 users 这一个的意思。 但是我们知道 CentOS 上面并不是这样的,在 CentOS 上面预设的群组为与账号名相同的群组。 举例来说, vbird1 的初始群组为 vbird1 。怎么会这样啊?这是因为针对群组的角度有两种不同的机制所致, 这两种机制分别是:
    o 私有群组机制:
    系统会建立一个与账号一样的群组给使用者作为初始群组。 这种群组的设定机制会比较有保密性,这是因为使用者都有自己的群组,而且家目录权限将会设定为 700 (仅有自己可进入自己的家目录) 之故。使用这种机制将不会参考 GROUP=100 这个设定值。代表性的 distributions 有 RHEL, Fedora, CentOS 等;
    o 公共群组机制:
    就是以 GROUP=100 这个设定值作为新建账号的初始群组,因此每个账号都属于 users 这个群组, 且默认家目录通常的权限会是『 drwxr-xr-x … username users … 』,由于每个账号都属于 users 群组,因此大家都可以互相分享家目录的数据之故。代表 distributions 如 SuSE等。
    由于我们的 CentOS 使用私有群组机制,因此这个设定项目是不会生效的!

  • HOME=/home:用户家目录的基准目录(basedir)
    用户的家目录通常是与账号同名的目录,这个目录将会摆放在此设定值的目录后。所以 vbird1 的家目录就会在 /home/vbird1/ 了!

  • INACTIVE=-1:密码过期后是否会失效的设定值
    我们在 shadow 档案结构当中谈过,第七个字段的设定值将会影响到密码过期后, 在多久时间内还可使用旧密码登入。这个项目就是在指定该日数!如果是 0 代表密码过期立刻失效, 如果是 -1 则是代表密码永远不会失效,如果是数字,如 30 ,则代表过期 30 天后才失效。

  • EXPIRE=:账号失效的日期
    就是 shadow 内的第八字段,你可以直接设定账号在哪个日期后就直接失效,而不理会密码的问题。 通常不会设定此项目,但如果是付费的会员制系统,或许这个字段可以设定!

  • SHELL=/bin/bash:默认使用的 shell 程序文件名
    系统默认的 shell 就写在这里。假如你的系统为 mail server ,你希望每个账号都只能使用 email 的收发信件功能, 而不许用户登入系统取得 shell ,那么可以将这里设定为 /sbin/nologin ,如此一来,新建的使用者预设就无法登入! 也免去后续使用 usermod 进行修改的手续!

  • SKEL=/etc/skel:用户家目录参考基准目录
    这个咚咚就是指定用户家目录的参考基准目录。举我们的范例一为例, vbird1 家目录 /home/vbird1 内的各项数据,都是由 /etc/skel 所复制过去的~所以未来如果我想要让新增使用者时,该用户的环境变量 ~/.bashrc 就设定妥当的话,您可以到 /etc/skel/.bashrc 去编辑一下,也可以建立 /etc/skel/www 这个目录,那么未来新增使用者后,在他的家目录下就会有 www 那个目录了!

  • CREATE_MAIL_SPOOL=yes:建立使用者的 mailbox
    你可以使用『 ll /var/spool/mail/vbird1 』看一下,会发现有这个档案的存在!这就是使用者的邮件信箱!

除了这些基本的账号设定值之外, UID/GID 还有密码参数又是在哪里参考的呢?那就得要看一下 /etc/login.defs ! 这个档案的内容有点像底下这样:
这里写图片描述
这个档案规范的数据则是如下所示:

  • mailbox 所在目录:
    用户的默认 mailbox 档案放置的目录在 /var/spool/mail,所以 vbird1 的 mailbox 就是在 /var/spool/mail/vbird1 !

  • shadow 密码第 4, 5, 6 字段内容:
    透过 PASS_MAX_DAYS 等等设定值来指定的!所以你知道为何预设的 /etc/shadow 内每一行都会有『 0:99999:7 』的存在了吗?!不过要注意的是,由于目前我们登入时改用 PAM 模块来进行密码检验,所以那个 PASS_MIN_LEN 是失效的!

  • UID/GID指定数值:
    虽然 Linux 核心支持的账号可高达 2**32 这么多个,不过一部主机要作出这么多账号在管理上也是很麻烦的! 所以在这里就针对 UID/GID 的范围进行规范就是了。上表中的 UID_MIN 指的就是可登入系统的一般账号的最小 UID ,至于 UID_MAX 则是最大 UID 之意。
    要注意的是,系统给予一个账号 UID 时,他是 (1)先参考 UID_MIN 设定值取得最小数值; (2)由 /etc/passwd 搜寻最大的 UID 数值, 将 (1) 与 (2) 相比,找出最大的那个再加一就是新账号的 UID 了。我们上面已经作出 UID 为 700 的 vbird2 , 如果再使用『 useradd vbird4 』时,你猜 vbird4 的 UID 会是多少?答案是: 701 。 所以中间的 505~699 的号码就空下来!
    而如果我是想要建立系统用的账号,所以使用 useradd -r sysaccount 这个 -r 的选项时,就会找『比 500 小的最大的那个 UID + 1 』就是了。

  • 用户家目录设定值:
    为何我们系统默认会帮用户建立家目录?就是这个『CREATE_HOME = yes』的设定值!这个设定值会让你在使用 useradd 时, 主动加入『 -m 』这个产生家目录的选项!如果不想要建立用户家目录,就只能强制加上『 -M 』的选项在 useradd 指令执行时!至于建立家目录的权限设定呢?就透过 umask 这个设定值啊!因为是 077 的预设设定,因此用户家目录默认权限才会是『 drwx—— 』哩!

  • 用户初除与密码设定值:
    使用『USERGROUPS_ENAB yes』这个设定值的功能是: 如果使用 userdel 去删除一个账号时,且该账号所属的初始群组已经没有人隶属于该群组了, 那么就初删除掉该群组,举例来说,我们刚刚有建立 vbird4 这个账号,他会主动建立 vbird4 这个群组。 若 vbird4 这个群组并没有其他账号将他加入支持的情况下,若使用 userdel vbird4 时,该群组也会被删除的意思。 至于『MD5_CRYPT_ENAB yes』则表示使用 MD5 来加密密码明文,而不使用旧式的 DES(注2) 。

现在你知道,使用 useradd 这支程序在建立 Linux 上的账号时,至少会参考:

  • /etc/default/useradd
  • /etc/login.defs
  • /etc/skel/*

这些档案,不过,最重要的其实是建立 /etc/passwd, /etc/shadow, /etc/group, /etc/gshadow 还有用户家目录就是了~所以,如果你了解整个系统运作的状态,也是可以手动直接修改这几个档案就是了。 OK !账号建立了,接下来处理一下用户的密码吧!

三、passwd
刚刚我们讲到了,使用 useradd 建立了账号之后,在预设的情况下,该账号是暂时被封锁的, 也就是说,该账号是无法登入的,你可以去瞧一瞧 /etc/shadow 内的第二个字段就晓得~ 那该如何是好?怕什么?直接给他设定新密码就好了!设定密码就使用 passwd !
这里写图片描述
这里写图片描述
root 果然是最伟大的人物!当我们要给予用户密码时,透过 root 来设定即可。 root 可以设定各式各样的密码,系统几乎一定会接受!所以您瞧瞧,如同上面的范例一,明明鸟哥输入的密码太短了, 但是系统依旧可接受 vbird2 这样的密码设定。这个是 root 帮忙设定的结果,那如果是用户自己要改密码呢? 包括 root 也是这样修改的!
这里写图片描述
passwd 的使用真的要很注意,尤其是 root 先生啊!在课堂上每次讲到这里,说是要帮自己的一般账号建立密码时, 有一小部分的学生就是会忘记加上账号,结果就变成改变 root 自己的密码,最后…. root 密码就这样不见去!唉~ 要帮一般账号建立密码需要使用『 passwd 账号 』的格式,使用『 passwd 』表示修改自己的密码 !
与 root 不同的是,一般账号在更改密码时需要先输入自己的旧密码 (亦即 current 那一行),然后再输入新密码 (New 那一行)。 要注意的是,密码的规范是非常严格的,尤其新的 distributions 大多使用 PAM 模块来进行密码的检验,包括太短、 密码与账号相同、密码为字典常见字符串等,都会被 PAM 模块检查出来而拒绝修改密码,此时会再重复出现『 New 』这个关键词! 那时请再想个新密码!若出现『 Retype 』才是你的密码被接受了!重复输入新密码并且看到『 successfully 』这个关键词时才是修改密码成功!
为何用户要设订自己的密码会这么麻烦啊?这是因为密码的安全性啦!如果密码设定太简单, 一些有心人士就能够很简单的猜到你的密码,如此一来人家就可能使用你的一般账号登入你的主机或使用其他主机资源, 对主机的维护会造成困扰的!所以新的 distributions 是使用较严格的 PAM 模块来管理密码,这个管理的机制写在 /etc/pam.d/passwd 当中。而该档案与密码有关的测试模块就是使用:
pam_cracklib.so,这个模块会检验密码相关的信息, 并且取代 /etc/login.defs 内的 PASS_MIN_LEN 的设定!关于 PAM 我们在本章后面继续介绍,这里先谈一下, 理论上,你的密码最好符合如下要求:

  • 密码不能与账号相同;
  • 密码尽量不要选用字典里面会出现的字符串;
  • 密码需要超过 8 个字符;
  • 密码不要使用个人信息,如身份证、手机号码、其他电话号码等;
  • 密码不要使用简单的关系式,如 1+1=2, Iamvbird 等;
  • 密码尽量使用大小写字符、数字、特殊字符($,_,-等)的组合。

为了方便系统管理,新版的 passwd 还加入了很多创意选项!个人认为最好用的大概就是这个『 –stdin 』了! 举例来说,你想要帮 vbird2 变更密码成为 abc543CC ,可以这样下达指令!
这里写图片描述
这个动作会直接更新用户的密码而不用再次的手动输入!好处是方便处理,缺点是这个密码会保留在指令中, 未来若系统被攻破,人家可以在 /root/.bash_history 找到这个密码!所以这个动作通常仅用在 shell script 的大量建立使用者账号当中!要注意的是,这个选项并不存在所有 distributions 版本中, 请使用 man passwd 确认你的 distribution 是否有支持此选项! 如果你想要让 vbird2 的密码具有相当的规则,举例来说你要让 vbird2 每 60 天需要变更密码, 密码过期后 10 天未使用就宣告密码失效,那该如何处理?
这里写图片描述
那如果我想要让某个账号暂时无法使用密码登入主机呢?举例来说, vbird2 这家伙最近老是胡乱在主机乱来, 所以我想要暂时让她无法登入的话,最简单的方法就是让她的密码变成不合法 (shadow 第 2 字段长度变掉) ! 处理的方法就更简单的!
这里写图片描述
这里写图片描述
您可以自行管理一下你的账号的密码相关参数!接下来让我们用更简单的方法来查阅密码参数!

四、chage
除了使用 passwd -S 之外,chage 是有更详细的密码参数显示功能的。 他的用法如下:
这里写图片描述
我们在 passwd 的介绍中谈到了处理 vbird2 这个账号的密码属性流程,使用 passwd -S 即无法看到很清楚的说明。如果使用 chage 那可就明白多了!如上表所示,我们可以清楚的知道 vbird2 的详细参数! 如果想要修改其他的设定值,就自己参考上面的选项,或者自行 man chage 一下!
chage 有一个功能很不错!如果你想要让『使用者在第一次登入时, 强制她们一定要更改密码后才能够使用系统资源』,可以利用如下的方法来处理的!
这里写图片描述
这里写图片描述
你会发现 agetest 这个账号在第一次登入时可以使用与账号同名的密码登入, 但登入时就会被要求立刻更改密码,更改密码完成后就会被踢出系统。再次登入时就能够使用新密码登入了! 这个功能对学校老师非常有帮助!因为我们不想要知道学生的密码,那么在初次上课时就使用与学号相同的账号/密码给学生, 让她们登入时自行设定她们的密码,如此一来就能够避免其他同学随意使用别人的账号,也能够保证学生知道如何更改自己的密码!

五、usermod
有的时候会『不小心』在 useradd 的时候加入了错误的设定数据。或者是,在使用 useradd 后,发现某些地方还可以进行细部修改。 此时,当然我们可以直接到 /etc/passwd 或 /etc/shadow 去修改相对应字段的数据, 不过,Linux 也有提供相关的指令让大家来进行账号相关数据的微调~那就是 usermod ~
这里写图片描述
如果你仔细的比对,会发现 usermod 的选项与 useradd 非常类似! 这是因为 usermod 也是用来微调 useradd 增加的使用者参数!不过 usermod 还是有新增的选项, 那就是 -L 与 -U ,不过这两个选项其实与 passwd 的 -l, -u 是相同的!而且也不见得会存在所有的 distribution 当中!接下来,让我们谈谈一些变更参数的实例吧!
这里写图片描述
这里写图片描述
六、userdel
目的在删除用户的相关数据,而用户的数据有:

  • 用户账号/密码相关参数:/etc/passwd, /etc/shadow
  • 使用者群组相关参数:/etc/group, /etc/gshadow
  • 用户个人档案数据: /home/username, /var/spool/mail/username..

整个指令的语法非常简单:
这里写图片描述
这个指令下达的时候要小心了!通常我们要移除一个账号的时候,你可以手动的将 /etc/passwd 与 /etc/shadow 里头的该账号取消即可!一般而言,如果该账号只是『暂时不启用』的话,那么将 /etc/shadow 里头账号失效日期 (第八字段) 设定为 0 就可以让该账号无法使用,但是所有跟该账号相关的数据都会留下来! 使用 userdel 的时机通常是『你真的确定不要让该用户在主机上面使用任何数据了 !』
另外,其实用户如果在系统上面操作过一阵子了,那么该用户其实在系统内可能会含有其他档案的。 举例来说,他的邮件信箱 (mailbox) 或者是例行性工作排程 (crontab, 十六章) 之类的档案。 所以,如果想要完整的将某个账号完整的移除,最好可以在下达 userdel -r username 之前, 先以『 find / -user username 』查出整个系统内属于 username 的档案,然后再加以删除吧!

14.2.2. 用户功能:finger, chfn, chsh, id
不论是 useradd/usermod/userdel ,那都是系统管理员所能够使用的指令, 如果我是一般身份使用者,那么我是否除了密码之外,就无法更改其他的数据呢? 当然不是!这里我们介绍几个一般身份用户常用的账号数据变更与查询指令!

一、finger
finger 的中文字面意义是:『手指』或者是『指纹』的意思。这个 finger 可以查阅很多用户相关的信息! 大部分都是在 /etc/passwd 这个档案里面的信息!我们就先来检查检查用户信息吧!
这里写图片描述
由于 finger 类似指纹的功能,他会将用户的相关属性列出来!如上表所示,其实他列出来的几乎都是 /etc/passwd 档案里面的东西。列出的信息说明如下:

  • Login:为使用者账号,亦即 /etc/passwd 内的第一字段;
  • Name:为全名,亦即 /etc/passwd 内的第五字段(或称为批注);
  • Directory:就是家目录了;
  • Shell:就是使用的 Shell 档案所在; Never logged in.:figner 还会调查用户登入主机的情况!
  • No mail.:调查 /var/spool/mail 当中的信箱资料;
  • No Plan.:调查 ~vbird1/.plan 档案,并将该档案取出来说明!

不过是否能够查阅到 Mail 与 Plan 则与权限有关了!因为 Mail / Plan 都是与使用者自己的权限设定有关, root 当然可以查阅到用户的这些信息,但是 vbird1 就不见得能够查到 vbird3 的信息, 因为 /var/spool/mail/vbird3 与 /home/vbird3/ 的权限分别是 660, 700 ,那 vbird1 当然就无法查阅的到! 这样解释可以理解吧?此外,我们可以建立自己想要执行的预定计划,当然,最多是给自己看的!可以这样做:
这里写图片描述
这里写图片描述
在范例三当中,我们发现输出的信息还会有 Office, Office Phone 等信息,那这些信息要如何记录呢? 底下我们会介绍 chfn 这个指令!来看看如何修改用户的 finger 数据吧!

二、chfn
chfn 有点像是: change finger 的意思!这玩意的使用方法如下:
这里写图片描述
这里写图片描述
这个指令说实在的,除非是你的主机有很多的用户,否则倒真是用不着这个程序!这就有点像是 bbs 里头更改你『个人属性』的那一个资料!不过还是可以自己玩一玩!尤其是用来提醒自己相关资料!

三、chsh
这就是 change shell 的简写!使用方法就更简单了!
这里写图片描述
这里写图片描述
不论是 chfn 与 chsh ,都是能够让一般用户修改 /etc/passwd 这个系统文件的!所以你猜猜,这两个档案的权限是什么? 一定是 SUID 的功能!看到这里,想到前面! 这就是 Linux 的学习方法~

四、id
id 这个指令则可以查询某人或自己的相关 UID/GID 等等的信息,他的参数也不少,不过, 都不需要记~反正使用 id 就全部都列出:
这里写图片描述
这里写图片描述

14.2.3. 新增与移除群组:groupadd, groupmod, groupdel, gpasswd 群组管理员
了解了账号的新增、删除、更动与查询后,再来我们可以聊一聊群组的相关内容了。 基本上,群组的内容都与这两个档案有关:/etc/group, /etc/gshadow。 群组的内容其实很简单,都是上面两个档案的新增、修改与移除而已, 不过,如果再加上有效群组的概念,那么 newgrp 与 gpasswd 则不可不知呢!

一、groupadd
这里写图片描述
曾经有某些版本的教育训练手册谈到,为了让使用者的 UID/GID 成对,她们建议新建的与使用者私有群组无关的其他群组时,使用小于 500 以下的 GID 为宜。 也就是说,如果要建立群组的话,最好能够使用『 groupadd -r 群组名』的方式来建立! 不过,这见仁见智啦!看你自己的抉择啰!

二、groupmod
跟 usermod 类似的,这个指令仅是在进行 group 相关参数的修改而已。
这里写图片描述
这里写图片描述
不过,还是那句老话,不要随意的更动 GID ,容易造成系统资源的错乱!

三、groupdel
groupdel 自然就是在删除群组。用法很简单:
这里写图片描述
为什么 mygroup 可以删除,但是 vbird1 就不能删除呢?原因很简单,『有某个账号 (/etc/passwd) 的 initial group 使用该群组!』 如果查阅一下,你会发现在 /etc/passwd 内的 vbird1 第四栏的 GID 就是 /etc/group 内的 vbird1 那个群组的 GID ,所以当然无法删除~否则 vbird1 这个用户登入系统后, 就会找不到 GID ,那可是会造成很大的困扰的!那么如果硬要删除 vbird1 这个群组呢? 你『必须要确认 /etc/passwd 内的账号没有任何人使用该群组作为 initial group 』才行!所以,你可以:

  • 修改 vbird1 的 GID ,或者是:
  • 删除 vbird1 这个使用者。

四、gpasswd:群组管理员功能
如果系统管理员太忙碌了,导致某些账号想要加入某个项目时找不到人帮忙!这个时候可以建立『群组管理员』! 什么是群组管理员呢?就是让某个群组具有一个管理员,这个群组管理员可以管理哪些账号可以加入/移出该群组! 那要如何『建立一个群组管理员』呢?就得要透过 gpasswd !
这里写图片描述
这里写图片描述
这里写图片描述
我们可以让 testgroup 成为一个可以公开的群组,然后建立起群组管理员, 群组管理员可以有多个。在这个案例中,我将 vbird1 设定为 testgroup 的群组管理员,所以 vbird1 就可以自行增加群组成员!然后,该群组成员就能够使用 newgrp ~

14.2.4. 账号管理实例
账号管理不是随意建置几个账号就算了!有时候我们需要考虑到一部主机上面可能有多个账号在协同工作! 举例来说,在大学任教时,我们学校的与题生是需要分组的,这些同一组的同学间必须要能够互相修改对方的数据文件, 但是同时这些同学又需要保留自己的私密数据,因此直接公开家目录是不适宜的。那该如何是好? 为此,我们底下提供几个例子来让大家思考看看:
任务一:单纯的完成上头交代的任务,假设我们需要的账号数据如下,你该如何实作?
这里写图片描述
处理的方法如下所示:
这里写图片描述
这里写图片描述
要注意的地方主要有:myuser1 与 myuser2 都有支援次要群组,但该群组不见得会存在,因此需要先手动建立他! 然后 myuser3 是『不可登入系统』的账号,因此需要使用 /sbin/nologin 这个 shell 来给予,这样该账号就无法登入! 这样是否理解啊!接下来再来讨论比较难一些的环境!如果是专题环境该如何制作?

任务二:我的使用者 pro1, pro2, pro3 是同一个项目计划的开发人员,我想要让这三个用户在同一个目录底下工作, 但这三个用户还是拥有自己的家目录与基本的私有群组。假设我要让这个项目计划在 /srv/projecta 目录下开发, 可以如何进行?
这里写图片描述
由于此项目计划只能够给 pro1, pro2, pro3 三个人使用,所以 /srv/projecta 的权限设定一定要正确才行! 所以该目录群组一定是 projecta ,但是权限怎么会是 2770 呢?还让得第七章谈到的 SGID 吧?为了让三个使用者能够互相修改对方的档案, 这个 SGID 是必须要存在的!如果连这里都能够理解,您的账号管理已经有一定程度的概念!
但接下来有个困扰的问题发生了!假如任务一的 myuser1 是 projecta 这个项目的助理,他需要这个项目的内容, 但是他『不可以修改』项目目录内的任何数据!那该如何是好?你或许可以这样做:

  • 将 myuser1 加入 projecta 这个群组的支持,但是这样会让 myuser1 具有完整的 /srv/projecta 的权限, myuser1 是可以删除该目录下的任何数据的!这样是有问题的;
  • 将 /srv/projecta 的权限改为 2775 ,让 myuser1 可以进入查阅数据。但此时会发生所有其他人均可进入该目录查阅的困扰! 这也不是我们要的环境。

真要命!传统的 Linux 权限无法针对某个个人设定与属的权限吗?其实是可以啦!接下来我们就来谈谈这个功能吧!

14.3. 主机的细部权限规划:ACL的使用
从第六章开始,我们就一直强调 Linux 的权限概念是非常重要的! 但是传统的权限仅有三种身份 (owner, group, others) 搭配三种权限 (r,w,x) 而已,并没有办法单纯的针对某一个使用者或某一个群组来设定特定的权限需求,例如前一小节最后的那个任务! 此时就得要使用 ACL 这个机制!底下我们就来谈一谈:

14.3.1. 什么是 ACL
ACL 是 Access Control List 的缩写,主要的目的是在提供传统的 owner,group,others 的 read,write,execute 权限之外的细部权限设定。ACL 可以针对单一使用者,单一档案或目录来进行 r,w,x 的权限规范,对于需要特殊权限的使用状况非常有帮助。
那 ACL 主要可以针对哪些方面来控制权限呢?他主要可以针对几个项目:

  • 使用者 (user):可以针对使用者来设定权限;
  • 群组 (group):针对群组为对象来设定其权限;
  • 默认属性 (mask):还可以针对在该目录下在建立新档案/目录时,规范新数据的默认权限;

好了,再来看看如何让你的文件系统可以支持 ACL 吧!

14.3.2. 如何启动 ACL
由于 ACL 是传统的 Unix-like 操作系统权限的额外支持项目,因此要使用 ACL 必须要有文件系统的支持才行。目前绝大部分的文件系统都有支持 ACL 的功能,包括 ReiserFS, EXT2/EXT3, JFS, XFS 等等。在我们的 CentOS 5.x 当中,预设使用 Ext3 是启动 ACL 支持的!至于察看你的文件系统是否支持 ACL 可以这样看:
这里写图片描述
由 mount 单纯去查阅不见得可以看到实际的项目,由于目前新的 distributions 常常会主动加入某些默认功能, 如上表所示,其实 CentOS 5.x 在预设的情况下 (Default mount options:) 就帮你加入 acl 的支持了! 那如果你的系统默认不会帮你加上 acl 的支持呢?那你可以这样做:
这里写图片描述
如果你不确定或者是不会使用 dumpe2fs 观察你的文件系统,那么建议直接将上述的 /etc/fstab 里面的内容修改一下即可!

14.3.3. ACL 的设定技巧: setfacl, getfacl, ACL 的设定(user, group mask, default)
好了,让你的 filesystem 启动 ACL 支持后,接下来该如何设定与观察 ACL 呢? 利用这两个指令就可以了:

  • getfacl:取得某个档案/目录的 ACL 设定项目;
  • setfacl:设定某个目录/档案的 ACL 规范。

先让我们来瞧一瞧 setfacl 如何使用吧!

一、setfacl 指令用法
这里写图片描述
上面谈到的是 acl 的选项功能,那么如何设定 ACL 的特殊权限呢?特殊权限的设定方法有很多, 我们先来谈谈最常见的,就是针对单一使用者的设定方式:
这里写图片描述
上述动作为最简单的 ACL 设定,利用『 u:使用者:权限 』的方式来设定的!设定前请加上 -m 这个选项。 如果一个档案设定了 ACL 参数后,他的权限部分就会多出一个 + 号了!但是此时你看到的权限与实际权限可能就会有点误差! 那要如何观察呢?就透过 getfacl 吧!

二、getfacl 指令用法
这里写图片描述
这里写图片描述
上面的数据非常容易查阅吧?显示的数据前面加上 # 的,代表这个档案的默认属性,包括文件名、档案拥有者与档案所属群组。 底下出现的 user, group, mask, other 则是属于不同使用者、群组与有效权限(mask)的设定值。 以上面的结果来看,我们刚刚设定的 vbird1 对于这个档案具有 r 与 x 的权限!这样看的懂吗? 如果看的懂的话,接下来让我们在测试其他类型的 setfacl 设定吧!
这里写图片描述
基本上,群组与使用者的设定并没有什么太大的差异!如上表所示,非常容易了解意义。不过,你应该会觉得奇怪的是, 那个 mask 是什么东西啊?其实他有点像是『有效权限』的意思!他的意义是: 使用者或群组所设定的权限必须要存在于mask 的权限设定范围内才会生效,此即『有效权限 (effective permission)』 我们举个例子来看,如下所示:
这里写图片描述
vbird1 与 mask 的集合发现仅有 r 存在,因此 vbird1 仅具有 r 的权限而已,并不存在 x 权限!这就是 mask 的功能了!我们可以透过使用 mask 来规范最大允许的权限,就能够避免不小心开放某些权限给其他使用者或群组了。 不过,通常都是将 mask 设定为 rwx !然后再分别依据不同的使用者/群组去规范她们的权限就是了。
这里写图片描述
这里写图片描述
上面的设定我们就完成了之前任务二的后续需求!接下来让我们来测试一下,如果我用 root 或者是 pro1 的身份去 /srv/projecta 增加档案或目录时,该档案或目录是否能够具有 ACL 的设定? 意思就是说,ACL 的权限设定是否能够被次目录所『继承?』先试看看:
这里写图片描述
你可以明显的发现,权限后面都没有 + ,代表这个 acl 属性并没有继承!如果你想要让 acl 在目录底下的数据都有继承的功能,那就得如下这样做了!
这里写图片描述
这里写图片描述
透过这个『针对目录来设定的默认 ACL 权限设定值』的项目,我们可以让这些属性继承到次目录底下! 那如果想要让 ACL 的属性全部消失又要如何处理?透过『 setfacl -b 档名 』即可!

14.4. 使用者身份切换
在 Linux 系统当中还要作身份的变换?这是为啥?可能有底下几个原因啦!

  • 使用一般账号:系统平日操作的好习惯
    事实上,为了安全的缘故,一些老人家都会建议你,尽量以一般身份使用者来操作 Linux 的日常作业!等到需要设定系统环境时, 才变换身份成为 root 来进行系统管理,相对比较安全!避免作错一些严重的指令,例如恐怖的『 rm -rf / 』(千万作不得!)

  • 用较低权限启动系统服务
    相对于系统安全,有的时候,我们必须要以某些系统账号来进行程序的执行。 举例来说, Linux 主机上面的一套软件,名称为 apache ,我们可以额外建立一个名为 apache 的用户来启动 apache 软件,如此一来,如果这个程序被攻破,至少系统还不至于就损毁。

  • 软件本身的限制
    在远古时代的 telnet 程序中,该程序默认是不许使用 root 的身份登入的,telnet 会判断登入者的 UID, 若 UID 为 0 的话,那就直接拒绝登入了。所以,你只能使用一般使用者来登入 Linux 服务器。 此外, ssh (注3) 也可以设定拒绝 root 登入!那如果你有系统设定需求该如何是好啊?就变换身份啊!

由于上述考虑,所以我们都是使用一般账号登入系统的,等有需要进行系统维护或软件更新时才转为 root 的身份来动作。 那如何让一般使用者转变身份成为 root 呢?主要有两种方式:

  • 以『 su - 』直接将身份变成 root 即可,但是这个指令即需要 root 的密码,也就是说,如果你要以 su 变成 root 的话,你的一般使用者就必须要有 root 的密码才行;
  • 以『 sudo 指令 』执行 root 的指令串,由于 sudo 需要事先设定妥当,且 sudo 需要输入用户自己的密码, 因此多人共管同一部主机时, sudo 要比 su 来的好!至少 root 密码不会流出去!

14.4.1. su
su 是最简单的身份切换指令了,他可以进行任何身份的切换!方法如下:
这里写图片描述
上表的解释当中有出现之前第十一章谈过的 login-shell 配置文件读取方式,如果你忘记那是啥东西, 请先回去第十一章瞧瞧再回来吧!这个 su 的用法当中,有没有加上那个减号『 - 』差很多! 因为涉及 login-shell 与 non-login shell 的变量读取方法。这里让我们以一个小例子来说明吧!
这里写图片描述
这里写图片描述
单纯使用『 su 』切换成为 root 的身份,读取的变量设定方式为 non-login shell 的方式,这种方式很多原本的变量不会被改变, 尤其是我们之前谈过很多次的 PATH 这个变量,由于没有改变成为 root 的环境 (一堆 /sbin, /usr/sbin 等目录都没有被包含进来), 因此很多 root 惯用的指令就只能使用绝对路径来执行咯。其他的还有 MAIL 这个变量,你输入 mail 时, 收到的邮件竟然还是 vbird1 的,而不是 root 本身的邮件!是否觉得很奇怪啊!所以切换身份时,请务必使用如下的范例二:
这里写图片描述
上述的作法是让使用者的身份变成 root 并开始操作系统,如果想要离开 root 的身份则得要到用 exit 离开才行。 那我如果只是想要执行『一个只有 root 才能进行的指令,且执行完毕就恢复原本的身份』呢?那就可以加上 -c 这个选项! 请参考底下范例三!
这里写图片描述
由于 /etc/shadow 权限的关系,该档案仅有 root 可以查阅。为了查阅该档案,所以我们必须要使用 root 的身份工作。 但我只想要进行一次该指令而已,此时就使用类似上面的语法!好,那接下来,如果我是 root 或者是其他人, 想要变更成为某些特殊账号,可以使用如下的方法来切换!
这里写图片描述
这里写图片描述
su 就这样简单的介绍完毕,总结一下他的用法是这样的:

  • 若要完整的切换到新使用者的环境,必须要使用『 su - username 』或『 su -l username 』, 才会连同 PATH/USER/MAIL 等变量都转成新用户的环境;
  • 如果仅想要执行一次 root 的指令,可以里用『 su - -c “指令串” 』的方式来处理;
  • 使用 root 切换成为任何使用者时,并不需要输入新用户的密码;

虽然使用 su 很方便,不过缺点是,当我的主机是多人共管的环境时,如果大家都要使用 su 来切换成为 root 的身份,那么不就每个人都得要知道 root 的密码,这样密码太多人知道可能会流出去, 很不妥当呢!怎办?透过 sudo 来处理即可!

14.4.2. sudo: sudo 指令, visudo (/etc/sudoers) ( 账号, 群组, 限制指令, 别名, 时间间隔, 配合 su )
相对于 su 需要了解新切换的用户密码 (常常是需要 root 的密码), sudo 的执行则仅需要自己的密码即可! 甚至可以设定不需要密码即可执行 sudo !由于 sudo 可以让你以其他用户的身份执行指令 (通常是使用 root 的身份来执行指令),因此并非所有人都能够执行 sudo , 而是仅有规范到 /etc/sudoers 内的用户才能够执行 sudo 这个指令!说的这么神奇,底下就来瞧瞧那 sudo 如何使用?

一、sudo 的指令用法
由于一开始系统默认仅有 root 可以执行 sudo ,因此底下的范例我们先以 root 的身份来执行,等到谈到 visudo 时,再以一般使用者来讨论其他 sudo 的用法! sudo 的语法如下:
这里写图片描述
这里写图片描述
sudo 可以让你切换身份来进行某项任务,例如上面的两个范例。范例一中,我们的 root 使用 sshd 的权限去进行某项任务! 要注意,因为我们无法使用『 su - sshd 』去切换系统账号 (因为系统账号的 shell 是 /sbin/nologin), 这个时候 sudo 真是他 X 的好用了!立刻以 sshd 的权限在 /tmp 底下建立档案!查阅一下档案权限你就了解意义! 至于范例二则更使用多重指令串 (透过分号 ; 来延续指令进行),使用 sh -c 的方法来执行一连串的指令, 如此真是好方便!
但是 sudo 预设仅有 root 能使用!为什么呢?因为 sudo 的执行是这样的流程:

  1. 当用户执行 sudo 时,系统于 /etc/sudoers 档案中搜寻该使用者是否有执行 sudo 的权限;
  2. 若使用者具有可执行 sudo 的权限后,便让使用者『输入用户自己的密码』来确认;
  3. 若密码输入成功,便开始进行 sudo 后续接的指令(但 root 执行 sudo 时,不需要输入密码);
  4. 若欲切换的身份与执行者身份相同,那也不需要输入密码。

所以说,sudo 执行的重点是:『能否使用 sudo 必须要看 /etc/sudoers 的设定值, 而可使用 sudo 者是透过输入用户自己的密码来执行后续的指令串』喔!由于能否使用与 /etc/sudoers 有关, 所以我们当然要去编辑 sudoers 档案啦!不过,因为该档案的内容是有一定的规范的,因此直接使用 vi 去编辑是不好的。 此时,我们得要透过 visudo 去修改这个档案喔!

二、visudo 与 /etc/sudoers
从上面的说明我们可以知道,除了 root 之外的其他账号,若想要使用 sudo 执行属于 root 的权限指令,则 root 需要先使用 visudo 去修改 /etc/sudoers ,让该账号能够使用全部或部分的 root 指令功能。为什么要使用 visudo 呢?这是因为 /etc/sudoers 是有设定语法的,如果设定错误那会造成无法使用 sudo 指令的不良后果。因此才会使用 visudo 去修改, 并在结束离开修改画面时,系统会去检验 /etc/sudoers 的语法就是了。
一般来说,visudo 的设定方式有几种简单的方法,底下我们以几个简单的例子来分别说明:

I. 单一用户可进行 root 所有指令,与 sudoers 档案语法:
假如我们要让 vbird1 这个账号可以使用 root 的任何指令,那么可以简单的这样进行修改即可:
这里写图片描述
其实 visudo 只是利用 vi 将 /etc/sudoers 档案呼叫出来进行修改而已,所以这个档案就是 /etc/sudoerds ! 这个档案的设定其实很简单,如上面所示,如果你找到 76 行 (有 root 设定的那行) 左右,看到的数据就是:
这里写图片描述
上面这一行的四个组件意义是:

  1. 系统的哪个账号可以使用 sudo 这个指令的意思,默认为 root 这个账号;
  2. 当这个账号由哪部主机联机到本 Linux 主机,意思是这个账号可能是由哪一部网络主机联机过来的, 这个设定值可以指定客户端计算机(信任用户的意思)。默认值 root 可来自任何一部网络主机 。
  3. 这个账号可以切换成什么身份来下达后续的指令,默认 root 可以切换成任何人;
  4. 可用该身份下达什么?这个指令请务必使用绝对路径撰写。 预设 root 可以切换任何身份且进行任何指令之意。

那个 ALL 是特殊的关键词,代表任何身份、主机或指令的意思。所以,我想让 vbird1 可以进行任何身份的任何指令, 就如同上表特殊字体写的那样,其实就是复制上述默认值那一行,再将 root 改成 vbird1 即可! 此时『vbird1 不论来自哪部主机登入,他可以变换身份成为任何人,且可以进行系统上面的任何指令』之意。 修改完请储存后离开 vi,并以 vbird1 登入系统后,进行如下的测试看看:
这里写图片描述
vbird1 输入自己的密码就能够执行 root 的指令!所以,系统管理员当然要了解 vbird1 这个用户的『操守』才行!否则随便设定一个用户,他恶搞系统怎办?另外,一个一个设定太麻烦了, 能不能使用群组的方式来设定呢?参考底下的方式吧。

II. 利用群组以及免密码的功能处理 visudo
我们在本章前面曾经建立过 pro1, pro2, pro3 ,这三个用户能否透过群组的功能让这三个人可以管理系统? 可以的,而且很简单!同样我们使用实际案例来说明:
这里写图片描述
上面的设定值会造成『任何加入 wheel 这个群组的使用者,就能够使用 sudo 切换任何身份来操作任何指令』的意思。 你当然可以将 wheel 换成你自己想要的群组名。接下来,请分别切换身份成为 pro1 及 pro2 试看看 sudo 的运作。
这里写图片描述
这样理解群组了吧?如果你想要让 pro3 也支持这个 sudo 的话,不需要重新使用 visudo ,只要利用 usermod 去修改 pro3 的群组支持,让 wheel 也支持 pro3 的话,那他就能够进行 sudo ! 不过,既然我们都信任这些 sudo 的用户了,能否提供『不需要密码即可使用 sudo 』呢? 就透过如下的方式:
这里写图片描述
重点是那个 NOPASSWD !该关键词是免除密码输入的意思!

III. 有限制的指令操作:
上面两点都会让使用者能够利用 root 的身份进行任何事情!这样总是不太好~如果我想要让用户仅能够进行部分系统任务, 比方说,系统上面的 myuser1 仅能够帮 root 修改其他用户的密码时,亦即『当使用者仅能使用 passwd 这个指令帮忙 root 修改其他用户的密码』时,你该如何撰写呢?可以这样做:
这里写图片描述
上面的设定值指的是『myuser1 可以切换成为 root 使用 passwd 这个指令』的意思。其中要注意的是: 指令字段必须要填写绝对路径才行!否则 visudo 会出现语法错误的状况发生! 此外,上面的设定是有问题的!我们使用底下的指令操作来让您了解:
这里写图片描述
恐怖啊!我们竟然让 root 的密码被 myuser1 给改变了!怎么办? 所以我们必须要限制用户的指令参数!修改的方法为将上述的那行改一改先:
这里写图片描述
由于屏幕一行写不完,我将这行写成两行,所以上面第一行最后加上反斜杠。加上惊叹号『 ! 』代表『不可执行』的意思。 因此上面这一行会变成:可以执行『 passwd 任意字符』,但是『 passwd 』与『 passwd root 』这两个指令例外! 如此一来 myuser1 就无法改变 root 的密码了!这样这位使用者可以具有 root 的能力帮助你修改其他用户的密码, 而且也不能随意改变 root 的密码!很有用处的!

IV. 透过别名建置 visudo:
如上述第三点,如果我有 15 个用户需要加入刚刚的管理员行列,那么我是否要将上述那长长的设定写入 15 行? 而且如果想要修改命令或者是新增命令时,那我每行都需要重新设定,很麻烦!有没有更简单的方式? 是有的!透过别名即可!我们 visudo 的别名可以是『指令别名、帐户别名、主机别名』等。不过这里我们仅介绍帐户别名, 其他的设定值有兴趣的话,可以自行玩玩! 假设我的 pro1, pro2, pro3 与 myuser1, myuser2 要加入上述的密码管理员的 sudo 列表中, 那我可以创立一个帐户别名称为 ADMPW 的名称,然后将这个名称处理一下即可。处理的方式如下:
这里写图片描述
我透过 User_Alias 建立出一个新账号,这个账号名称一定要使用大写字符来处理,包括 Cmnd_Alias(命令别名)、Host_Alias(来源主机名别名) 都需要使用大写字符的 !这个 ADMPW 代表后面接的那些实际账号。 而该账号能够进行的指令就如同 ADMPWCOM 后面所指定的那样!上表最后一行则写入这两个别名 (账号与指令别名), 未来要修改时,我只要修改 User_Alias 以及 Cmnd_Alias 这两行即可!设定方面会比较简单有弹性!

V. sudo 的时间间隔问题:
或许您已经发现了,那就是,如果我使用同一个账号在短时间内重复操作 sudo 来运作指令的话, 在第二次执行 sudo 时,并不需要输入自己是密码!sudo 还是会正确的运作!为什么呢? 第一次执行 sudo 需要输入密码,是担心由于用户暂时离开座位,但有人跑来你的座位使用你的账号操作系统之故。 所以需要你输入一次密码重新确认一次身份。 两次执行 sudo 的间隔在五分钟内,那么再次执行 sudo 时就不需要再次输入密码了, 这是因为系统相信你在五分钟内不会离开你的作业,所以执行 sudo 的是同一个人!真是很人性化的设计啊~。不过如果两次 sudo 操作的间隔超过 5 分钟,那就得要重新输入一次你的密码了 (注4) 另外要注意的是,因为使用一般账号时,理论上不会使用到 /sbin, /usr/sbin 等目录内的指令,所以 $PATH 变量不会含有这些目录,因此很多管理指令需要使用绝对路径来下达比较妥当!

VI. sudo 搭配 su 的使用方式:
很多时候我们需要大量执行很多 root 的工作,所以一直使用 sudo 觉得很烦之!那有没有办法使用 sudo 搭配 su , 一口气将身份转为 root ,而且还用用户自己的密码来变成 root 呢?是有的!而且方法简单的会让你想笑! 我们建立一个 ADMINS 帐户别名,然后这样做:
这里写图片描述
接下来,上述的 pro1, pro2, pro3, myuser1 这四个人,只要输入『 sudo su - 』并且输入『自己的密码』后, 立刻变成 root 的身份!不但 root 密码不会外流,用户的管理也变的非常方便! 这也是实务上面多人共管一部主机时常常使用的技巧!这样管理确实方便,不过还是要强调一下大前提, 那就是『这些你加入的使用者,全部都是你能够信任的用户』!

14.5. 用户的特殊 shell 与 PAM 模块
我们前面一直谈到的大多是一般身份用户与系统管理员 (root) 的相关操作, 而且大多是讨论关于可登入系统的账号来说。那么换个角度想,如果我今天想要建立的, 是一个『仅能使用 mail server 相关邮件服务的账号,而该账号并不能登入 Linux 主机』呢?如果不能给予该账号一个密码,那么该账号就无法使用系统的各项资源,当然也包括 mail 的资源, 而如果给予一个密码,那么该账号就可能可以登入 Linux 主机啊! 所以,底下让我们来谈一谈这些有趣的话题!
另外,在本章之前谈到过 /etc/login.defs 档案中,关于密码长度应该默认是 5 个字符串长度,但是我们上面也谈到,该设定值已经被 PAM 模块所取代了,那么 PAM 是什么?为什么他可以影响我们使用者的登入呢?

14.5.1. 特殊的 shell :/sbin/nologin, nologin.txt
在本章一开头的 passwd 档案结构里面我们就谈过系统账号这玩意儿,这玩意儿的 shell 就是使用 /sbin/nologin ,重点在于系统账号是不需要登入的!所以我们就给他这个无法登入的合法 shell。 使用了这个 shell 的用户即使有了密码,你想要登入时他也无法登入,因为会出现如下的讯息:
这里写图片描述
我们所谓的『无法登入』指的仅是:『这个使用者无法使用 bash 或其他 shell 来登入系统』而已, 并不是说这个账号就无法使用其他的系统资源! 举例来说,各个系统账号,打印作业由 lp 这个账号在管理, WWW 服务由 apache 这个账号在管理, 他们都可以进行系统程序的工作,但是『就是无法登入主机』而已!
换个角度来想,如果我的 Linux 主机提供的是邮件服务,所以说,在这部 Linux 主机上面的账号, 其实大部分都是用来收受主机的信件而已,并不需要登入主机的! 这个时候,我们就可以考虑让单纯使用 mail 的账号以 /sbin/nologin 做为他们的 shell , 这样,最起码当我的主机被尝试想要登入系统以取得 shell 环境时,可以拒绝该账号!
另外,如果我想要让某个具有 /sbin/nologin 的使用者知道,他们不能登入主机时, 其实我可以建立『 /etc/nologin.txt 』这个档案, 并且在这个档案内说明不能登入的原因,那么下次当这个用户想要登入系统时, 屏幕上出现的就会是 /etc/nologin.txt 这个档案的内容,而不是预设的内容了!
这里写图片描述
这里写图片描述

14.5.2. PAM 模块简介
在过去,我们想要对一个使用者进行认证 (authentication),得要求用户输入账号密码, 然后透过自行撰写的程序来判断该账号密码是否正确。也因为如此,我们常常得使用不同的机制来判断账号密码, 所以搞的一部主机上面拥有多个各别的认证系统,也造成账号密码可能不同步的验证问题! 为了解决这个问题因此有了 PAM (Pluggable Authentication Modules, 嵌入式模块) 的机制!
PAM 可以说是一套应用程序编程接口 (Application Programming Interface, API),他提供了一连串的验证机制,只要使用者将验证阶段的需求告知 PAM 后, PAM 就能够回报使用者验证的结果 (成功或失败)。由于 PAM 仅是一套验证的机制,又可以提供给其他程序所呼叫引用,因此不论你使用什么程序,都可以使用 PAM 来进行验证,如此一来,就能够让账号密码或者是其他方式的验证具有一致的结果!也让程序设计师方便处理验证的问题! (注5)
这里写图片描述
如上述的图示, PAM 是一个独立的 API 存在,只要任何程序有需求时,可以向 PAM 发出验证要求的通知, PAM 经过一连串的验证后,将验证的结果回报给该程序,然后该程序就能够利用验证的结果来进行可登入或显示其他无法使用的讯息。 这也就是说,你可以在写程序的时候将 PAM 模块的功能加入,就能够利用 PAM 的验证功能。 因此目前很多程序都会利用 PAM !所以我们才要来学习他!
PAM 用来进行验证的数据称为模块 (Modules),每个 PAM 模块的功能都不太相同。举例来说, 还记得我们在本章使用 passwd 指令时,如果随便输入字典上面找的到的字符串, passwd 就会回报错误信息了!这是为什么呢?这就是 PAM 的 pam_cracklib.so 模块的功能!他能够判断该密码是否在字典里面! 并回报给密码修改程序,此时就能够了解你的密码强度了。
所以,当你有任何需要判断是否在字典当中的密码字符串时,就可以使用 pam_cracklib.so 这个模块来验证! 并根据验证的回报结果来撰写你的程序!这样说,可以理解 PAM 的功能了? PAM 的模块也是很重要的一环!

14.5.3. PAM 模块设定语法:验证类别 (type)、控制标准(flag)、模块与参数
PAM 藉由一个与程序相同文件名的配置文件来进行一连串的认证分析需求。我们同样以 passwd 这个指令的呼叫 PAM 来说明好了。 当你执行 passwd 后,这支程序呼叫 PAM 的流程是:

  1. 用户开始执行 /usr/bin/passwd 这支程序,并输入密码;
  2. passwd 呼叫 PAM 模块进行验证;
  3. PAM 模块会到 /etc/pam.d/ 找寻与程序 (passwd) 同名的配置文件;
  4. 依据 /etc/pam.d/passwd 内的设定,引用相关的 PAM 模块逐步进行验证分析;
  5. 将验证结果 (成功、失败以及其他讯息) 回传给 passwd 这支程序;
  6. passwd 这支程序会根据 PAM 回传的结果决定下一个动作 (重新输入新密码或者通过验证!)

从上头的说明,我们会知道重点其实是 /etc/pam.d/ 里面的配置文件,以及配置文件所呼叫的 PAM 模块进行的验证工作! 既然一直谈到 passwd 这个密码修改指令,那我们就来看看 /etc/pam.d/passwd 这个配置文件的内容是怎样吧!
这里写图片描述
在这个配置文件当中,除了第一行宣告 PAM 版本之外,其他任何『 # 』开头的都是批注,而每一行都是一个独立的验证流程, 每一行可以区分为三个字段,分别是验证类别(type)、控制标准(flag)、PAM的模块与该模块的参数。 底下我们先来谈谈验证类别与控制标准这两项数据吧!

第一个字段:验证类别 (Type)
验证类别主要分为四种,分别说明如下:

  • auth
    是 authentication (认证) 的缩写,所以这种类别主要用来检验使用者的身份验证,这种类别通常是需要密码来检验的, 所以后续接的模块是用来检验用户的身份。
  • account
    account (账号) 则大部分是在进行 authorization (授权),这种类别则主要在检验使用者是否具有正确的权限, 举例来说,当你使用一个过期的密码来登入时,当然就无法正确的登入了。
  • session
    session 是会议期间的意思,所以 session 管理的就是使用者在这次登入 (或使用这个指令) 期间,PAM 所给予的环境设定。 这个类别通常用在记录用户登入与注销时的信息!例如,如果你常常使用 su 或者是 sudo 指令的话, 那么应该可以在 /var/log/secure 里面发现很多关于 pam 的说明,而且记载的数据是『session open, session close』的信息!
  • password
    password 就是密码!所以这种类别主要在提供验证的修订工作,举例来说,就是修改/变更密码!

这四个验证的类型通常是有顺序的,不过也有例外就是了。 会有顺序的原因是,(1)我们总是得要先验证身份 (auth) 后, (2)系统才能够藉由用户的身份给予适当的授权与权限设定 (account),而且(3)登入与注销期间的环境才需要设定, 也才需要记录登入与注销的信息 (session)。如果在运作期间需要密码修订时,(4)才给予 password 的类别。这样说起来, 自然是需要有点顺序吧!

第二个字段:验证的控制旗标 (control flag)
那么『验证的控制旗标(control flag)』又是什么?简单的说,他就是『验证通过的标准』! 这个字段在管控该验证的放行方式,主要也分为四种控制方式:

  • required
    此验证若成功则带有 success (成功) 的标志,若失败则带有 failure 的标志,但不论成功或失败都会继续后续的验证流程。 由于后续的验证流程可以继续进行,因此相当有利于资料的登录 (log) ,这也是 PAM 最常使用 required 的原因。
  • requisite
    若验证失败则立刻回报原程序 failure 的标志,并终止后续的验证流程。若验证成功则带有 success 的标志并继续后续的验证流程。 这个项目与 required 最大的差异,就在于失败的时候还要不要继续验证下去?由于 requisite 是失败就终止, 因此失败时所产生的 PAM 信息就无法透过后续的模块来记录了。
  • sufficient
    若验证成功则立刻回传 success 给原程序,并终止后续的验证流程;若验证失败则带有 failure 标志并继续后续的验证流程。 这玩意儿与 requisits 刚好相反!
  • optional
    这个模块控件目的大多是在显示讯息而已,并不是用在验证方面的。

如果将这些控制旗标以图示的方式配合成功与否的条件绘图,会有点像底下这样:
这里写图片描述
程序运作过程中遇到验证时才会去呼叫 PAM ,而 PAM 验证又分很多类型与控制,不同的控制旗标所回报的讯息并不相同。 如上图所示, requisite 失败就回报了并不会继续,而 sufficient 则是成功就回报了也不会继续。 至于验证结束后所回报的信息通常是『succes 或 failure 』而已,后续的流程还需要该程序的判断来继续执行才行。

14.5.4. 常用模块简介: securetty, nologin, pam_cracklib, login流程
谈完了配置文件的语法后,现在让我们来查阅一下 CentOS 5.x 提供的 PAM 预设档案的内容是啥吧! 由于我们常常需要透过各种方式登入 (login) 系统,因此就来看看登入所需要的 PAM 流程为何:
这里写图片描述
这里写图片描述
上面这个表格当中使用到非常多的 PAM 模块,每个模块的功能都不太相同,详细的模块情报可以在你的系统中找到:

  • /etc/pam.d/*:每个程序个别的 PAM 配置文件;
  • /lib/security/*:PAM 模块档案的实际放置目录;
  • /etc/security/*:其他 PAM 环境的配置文件;
  • /usr/share/doc/pam-*/:详细的 PAM 说明文件。

例如我使用未 update 过的 CentOS 5.2 ,pam_nologin 说明文件档在: /usr/share/doc/pam-0.99.6.2/txts/README.pam_nologin。你可以自行查阅一下该模块的功能。 这里仅简单介绍几个较常使用的模块,详细的信息还得要您努力查阅参考书!

  • pam_securetty.so:
    限制系统管理员 (root) 只能够从安全的 (secure) 终端机登入;那什么是终端机?例如 tty1, tty2 等就是传统的终端机装置名称。那么安全的终端机设定呢? 就写在 /etc/securetty 这个档案中。你可以查阅一下该档案, 就知道为什么 root 可以从 tty1~tty7 登入,但即无法透过 telnet 登入 Linux 主机了!
  • pam_nologin.so:
    这个模块可以限制一般用户是否能够登入主机之用。当 /etc/nologin 这个档案存在时,则所有一般使用者均无法再登入系统了 !若 /etc/nologin 存在,则一般使用者在登入时, 在他们的终端机上会将该档案的内容显示出来!所以,正常的情况下,这个档案应该是不能存在系统中的。 但这个模块对 root 以及已经登入系统中的一般账号并没有影响。
  • pam_selinux.so:
    SELinux 是个针对程序来进行细部管理权限的功能,SELinux 这玩意儿我们会在第十七章的时候再来详细谈论。由于 SELinux 会影响到用户执行程序的权限,因此我们利用 PAM 模块,将 SELinux 暂时关闭,等到验证通过后, 再予以启动!
  • pam_console.so:
    当系统出现某些问题,或者是某些时刻你需要使用特殊的终端接口 (例如 RS232 之类的终端联机设备) 登入主机时, 这个模块可以帮助处理一些档案权限的问题,让使用者可以透过特殊终端接口 (console) 顺利的登入系统。
  • pam_loginuid.so:
    我们知道系统账号与一般账号的 UID 是不同的!一般账号 UID 均大于 500 才合理。 因此,为了验证使用者的 UID 真的是我们所需要的数值,可以使用这个模块来进行规范!
  • pam_env.so:
    用来设定环境变量的一个模块,如果你有需要额外的环境变量设定,可以参考 /etc/security/pam_env.conf 这个档案的详细说明。
  • pam_unix.so:
    这是个很复杂且重要的模块,这个模块可以用在验证阶段的认证功能,可以用在授权阶段的账号许可证管理, 可以用在会议阶段的登录文件记录等,甚至也可以用在密码更新阶段的检验!非常丰富的功能! 这个模块在早期使用得相当频繁!
  • pam_cracklib.so:
    可以用来检验密码的强度!包括密码是否在字典中,密码输入几次都失败就断掉此次联机等功能,都是这模块提供的! 这玩意儿很重要!
  • pam_limits.so:
    还记得我们在十一章谈到的 ulimit 吗? 其实那就是这个模块提供的能力!还有更多细部的设定可以参考: /etc/security/limits.conf 内的说明。

了解了这些模块的大致功能后,言归正传,讨论一下 login 的 PAM 验证机制流程是这样的:

  1. 验证阶段 (auth):首先,(a)会先经过 pam_securetty.so 判断,如果使用者是 root 时,则会参考 /etc/securetty 的设定; 接下来(b)经过 pam_env.so 设定额外的环境变量;再(c)透过 pam_unix.so 检验密码,若通过则回报 login 程序;若不通过则(d)继续往下以 pam_succeed_if.so 判断 UID 是否大于 500 ,若小于 500则回报失败,否则再往下 (e)以 pam_deny.so 拒绝联机。
  2. 授权阶段 (account):(a)先以 pam_nologin.so 判断 /etc/nologin 是否存在,若存在则不许一般使用者登入; (b)接下来以 pam_unix 进行账号管理,再以 (c) pam_succeed_if.so 判断 UID 是否小于 500 ,若小于 500 则不记录登录信息。(d)最后以 pam_permit.so 允许该账号登入。
  3. 密码阶段 (password):(a)先以 pam_cracklib.so 设定密码仅能尝试错误 3 次;(b)接下来以 pam_unix.so 透过 md5, shadow 等功能进行密码检验,若通过则回报 login 程序,若不通过则 (c)以 pam_deny.so 拒绝登入。
  4. 会议阶段 (session):(a)先以 pam_selinux.so 暂时关闭 SELinux;(b)使用 pam_limits.so 设定好用户能够操作的系统资源; (c)登入成功后开始记录相关信息在登录文件中; (d)以 pam_loginuid.so 规范不同的 UID 权限;(e)开启 pam_selinux.so 的功能。

总之,就是依据验证类别 (type) 来看,然后先由 login 的设定值去查阅,如果出现『 include system-auth 』 就转到 system-auth 档案中的相同类别,去取得额外的验证流程就是了。然后再到下一个验证类别,最终将所有的验证跑完! 就结束这次的 PAM 验证!
经过这样的验证流程,现在你知道为啥 /etc/nologin 存在会有问题,也会知道为何你使用一些远程联机机制时, 老是无法使用 root 登入的问题了吧?这都是 PAM 模块提供的功能!
这里写图片描述

14.5.5. 其他相关档案: limits.conf,
除了前一小节谈到的 /etc/securetty 会影响到 root 可登入的安全终端机, /etc/nologin 会影响到一般使用者是否能够登入的功能之外,我们也知道 PAM 相关的配置文件在 /etc/pam.d , 说明文件在 /usr/share/doc/pam-(版本) ,模块实际在 /lib/security/ 。那么还有没有相关的 PAM 档案呢? 是有的,主要都在 /etc/security 这个目录内!我们底下介绍几个可能会用到的配置文件!

一、limits.conf
我们在第十一章谈到的 ulimit 功能中, 除了修改使用者的 ~/.bashrc 配置文件之外,其实系统管理员可以统一藉由 PAM 来管理的! 那就是 /etc/security/limits.conf 这个档案的设定了。这个档案的设定很简单,你可以自行参考一下该档案内容。 我们这里仅作个简单的介绍:
这里写图片描述
这里写图片描述
这个档案挺有趣的,而且是设定完成就生效了,你不用重新启动任何服务的! 但是 PAM 有个特殊的地方,由于他是在程序呼叫时才予以设定的,因此你修改完成的数据, 对于已登入系统中的用户是没有效果的,要等他再次登入时才会生效!另外, 上述的设定请在测试完成后立刻批注掉,否则下次这两个使用者登入就会发生些许问题!

二、/var/log/secure, /var/log/messages
如果发生任何无法登入或者是产生一些你无法预期的错误时,由于 PAM 模块都会将数据下载在 /var/log/secure 当中,所以发生了问题请务必到该档案内去查询一下问题点!记录来说, 我们在 limits.conf 的介绍内的范例二,就有谈到多重登入的错误可以到 /var/log/secure 内查阅了! 这样你也就知道为何第二个 pro1 无法登入啦!

14.6. Linux 主机上的用户讯息传递
谈了这么多的账号问题,总是该要谈一谈,那么如何针对系统上面的用户进行查询吧? 想几个状态,如果你在 Linux 上面操作时,刚好有其他的用户也登入主机,你想要跟他对谈,该如何是好? 你想要知道某个账号的相关信息,该如何查阅?

14.6.1. 查询使用者: w, who, last, lastlog
如何查询一个用户的相关数据呢?这还不简单,我们之前就提过了 id, finger 等指令了,都可以让您了解到一个用户的相关信息!那么想要知道使用者到底啥时候登入呢? 最简单可以使用 last 检查!这个玩意儿我们也在 第十一章 bash 提过了, 您可以自行前往参考啊!简单的很。
那如果你想要知道目前已登入在系统上面的用户呢?可以透过 w 或 who 来查询!如下范例所示:
这里写图片描述
另外,如果您想要知道每个账号的最近登入的时间,则可以使用 lastlog 这个指令! lastlog 会去读取 /var/log/lastlog 档案,结果将数据输出如下表:
这里写图片描述
这样就能够知道每个账号的最近登入的时间了~ ^

14.6.2. 使用者对谈: write, mesg, wall
那么我是否可以跟系统上面的用户谈天说地呢?当然可以!利用 write 这个指令即可。 write 可以直接将讯息传给接收者!记录来说,我们的 Linux 目前有 vbird1 与 root 两个人在在线, 我的 root 要跟 vbird1 讲话,可以这样做:
这里写图片描述
这里写图片描述
立刻会有讯息响应给 vbird1 !不过……当时 vbird1 正在查资料, 这些讯息会立刻打断 vbird1 原本的工作!所以,如果 vbird1 这个人不想要接受任何讯息,直接下达这个动作:
这里写图片描述
不过,这个 mesg 的功能对 root 传送来的讯息没有抵挡的能力!所以如果是 root 传送讯息, vbird1 还是得要收下。 但是如果 root 的 mesg 是 n 的,那么 vbird1 写给 root 的信息会变这样:
这里写图片描述
如果想要解开的话,再次下达『 mesg y 』就好啦!想要知道目前的 mesg 状态,直接下达『 mesg 』即可!相对于 write 是仅针对一个使用者来传『简讯』,我们还可以『对所有系统上面的用户传送简讯 (广播)』~ 如何下达?用 wall 即可!他的语法也是很简单的!
这里写图片描述
然后你就会发现所有的人都会收到这个简讨呢!

14.6.3. 使用者邮件信箱: mail
使用 wall, write 毕竟要等到使用者在在线才能够进行,有没有其他方式来联络啊? 不是说每个 Linux 主机上面的用户都具有一个 mailbox 吗? 我们可否寄信给使用者啊!当然可以啊!我们可以寄、收 mailbox 内的信件! 一般来说, mailbox 都会放置在 /var/spool/mail 里面,一个账号一个 mailbox (档案)。 举例来说,我的 vbird1 就具有 /var/spool/mail/vbird1 这个 mailbox 喔!
那么我该如何寄出信件呢?就直接使用 mail 这个指令即可!这个指令的用法很简单的,直接这样下达:『 mail username@localhost -s “邮件标题” 』即可! 一般来说,如果是寄给本机上的使用者,基本上,连『 @localhost 』都不用写! 举例来说,我以 root 寄信给 vbird1 ,信件标题是『 nice to meet you 』,则:
这里写图片描述
如此一来,你就已经寄出一封信给 vbird1 这位使用者,而且,该信件标题为: nice to meet you,信件内容就如同上面提到的。不过,你或许会觉得 mail 这个程序不好用~ 因为在信件编写的过程中,如果写错字而按下 Enter 进入次行,前一行的数据很难删除之! 那怎么办?我们使用数据流重导向!利用那个小于的符号 ( < ) 就可以达到取代键盘输入的要求了。也就是说,你可以先
用 vi 将信件内容编好, 然后再以 mail vbird1 -s “nice to meet you” < filename 来将档案内容传输即可。
这里写图片描述
刚刚上面提到的是关于『寄信』的问题,那么如果是要收信呢?同样的使用 mail ! 假设我以 vbird1 的身份登入主机,然后输入 mail 后,会得到什么?
这里写图片描述
在 mail 当中的提示字符是 & 符号~输入 mail 之后,我可以看到我有一封信件, 这封信件的前面那个 > 代表目前处理的信件,而在大于符号的左边那个 N 代表该封信件尚未读过, 如果我想要知道这个 mail 内部的指令有哪些,可以在 & 之后输入『 ? 』,就可以看到如下的画面:
这里写图片描述
指的是每封邮件的左边那个数字!而几个比较常见的指令是:
这里写图片描述
这里写图片描述
由于读过的信件若使用『 q 』来离开 mail 时,会将该信件移动到 ~/mbox 中,所以你可以这样想象: /var/spool/mail/vbird1 为 vbird1 的『新件匣』,而 /home/vbird1/mbox 则为『收件匣』的意思。 那如何读取 /home/vbird1/mbox 呢?就使用『mail -f /home/vbird1/mbox』即可。

14.7. 手动新增使用者
一般来说,我们不很建议大家使用手动的方式来新增使用者,为什么呢? 因为使用者的建立涉及到 GID/UID 等权限的关系,而且,与档案/目录的权限也有关系, 使用 useradd 可以帮我们自动设定好 UID/GID 家目录以及家目录相关的权限设定, 但是,手动来增加的时候,有可能会忘东忘西,结果导致一些困扰的发生。
不过,要了解整个系统,最好还是手动来修改过比较好,至少我们的账号问题可以完全依照自己的意思去修订, 而不必迁就于系统的默认值!但是,还是要告诫一下朋友们,要手动设定账号时, 您必须要真的很了解自己在作什么,尤其是与权限有关的设定方面!

14.7.1. 一些检查工具:pwck, pwconv, pwunconv, chpasswd
既然要手动修改账号的相关配置文件,那么一些检查群组、账号相关的指令就不可不知道啊~ 尤其是那个密码转换的 pwconv 及 pwuconv 这两个玩意~可重要的很呢!底下我们稍微介绍一下这些指令吧!

一、pwck
pwck 这个指令在检查 /etc/passwd 这个账号配置文件内的信息,与实际的家目录是否存在等信息, 还可以比对 /etc/passwd /etc/shadow 的信息是否一致,另外,如果 /etc/passwd 内的数据字段错误时,会提示使用者修订。 一般来说,我只是利用这个玩意儿来检查我的输入是否正确就是了。
这里写图片描述
上面仅是告知我,这些账号并没有家目录,由于那些账号绝大部分都是系统账号, 确实也不需要家目录的,所以,那是『正常的错误!』不理他。 相对应的群组检查可以使用 grpck 这个指令的!

二、pwconv
这个指令主要的目的是在『将 /etc/passwd 内的账号与密码,移动到 /etc/shadow 当中!』 早期的 Unix 系统当中并没有 /etc/shadow 呢,所以,用户的登入密码早期是在 /etc/passwd 的第二栏,后来为了系统安全,才将密码数据移动到 /etc/shadow 内的。使用 pwconv 后,可以:

  • 比对 /etc/passwd 及 /etc/shadow ,若 /etc/passwd 内存在的账号并没有对应的 /etc/shadow 密码时,则 pwconv 会去 /etc/login.defs 取用相关的密码数据,并建立该账号的 /etc/shadow 数据;
  • 若 /etc/passwd 内存在加密后的密码数据时,则 pwconv 会将该密码栏移动到 /etc/shadow 内,并将原本的 /etc/passwd 内相对应的密码栏变成 x !

一般来说,如果您正常使用 useradd 增加使用者时,使用 pwconv 并不会有任何的动作,因为 /etc/passwd 与 /etc/shadow 并不会有上述两点问题! 不过,如果手动设定账号,这个 pwconv 就很重要!

三、pwunconv
相对于 pwconv , pwunconv 则是『将 /etc/shadow 内的密码栏数据写回 /etc/passwd 当中, 并且删除 /etc/shadow 档案。』这个指令说实在的,最好不要使用! 因为他会将你的 /etc/shadow 删除!如果你忘让备份,又不会使用 pwconv 的话,粉严重呢!

四、chpasswd
chpasswd 是个挺有趣的指令,他可以『读入未加密前的密码,并且经过加密后, 将加密后的密码写入 /etc/shadow 当中。』这个指令很常被使用在大量建置账号的情况中! 他可以由 Standard input 读入数据,每笔数据的格式是『 username:password 』。 举例来说,我的系统当中有个用户账号为 dmtsai ,我想要更新他的密码 (update) , 假如他的密码是 abcdefg 的话,那么我可以这样做:
这里写图片描述
这样就可以更新了!在预设的情况中, chpasswd 使用的是 DES 加密方法来加密, 我们可以使用 chpasswd -m 来使用 CentOS 5.x 预设的 MD5 加密方法。这个指令虽然已经很好用了,不过 CentOS 5.x 其实已经提供了『 passwd –stdin 』的选项,老实说,这个 chpasswd 可以不必使用了。但考虑其他版本不见得会提供 –stdin 给 passwd 这个指令,所以您还是得要了解一下这个指令用途!

14.7.2. 特殊账号,如纯数字账号的手工建立
在我们了解了 UID/GID 与账号的关系之后,基本上,您应该了解了,为啥我们不建议使用纯数字的账号了!因为很多时候,系统会搞不清楚那组数字是『账号』还是『 UID 』,也因此,在早期某些版本底下,是没有办法使用数字来建立账号的。例如在 Red Hat 9 的环境中, 使用『 useradd 1234 』他会显示『 useradd: invalid user name ‘1234’ 』了解了吗?
不过,有的时候,长官的命令难为啊, 有时还是得要建立这方面的账号的,那该如何是好? 当然可以手动来建立这样的账号!不过,为了系统安全起见,还是不建议使用纯数字的账号的! 因此,底下的范例当中,我们使用手动的方式来建立一个名为 normaluser 的账号, 而且这个账号属于 normalgroup 这个群组。那么整个步骤该如何是好呢? 由前面的说明来看,您应该了解了账号与群组是与 /etc/group, /etc/shadow, /etc/passwd, /etc/gshadow 有关,因此,整个动作是这样的:

  1. 先建立所需要的群组 ( vi /etc/group );
  2. 将 /etc/group 与 /etc/gshadow 同步化 ( grpconv );
  3. 建立账号的各个属性 ( vi /etc/passwd );
  4. 将 /etc/passwd 与 /etc/shadow 同步化 ( pwconv );
  5. 建立该账号的密码 ( passwd accountname );
  6. 建立用户家目录 ( cp -a /etc/skel /home/accountname );
  7. 更改用户家目录的属性 ( chown -R accountname.group /home/accountname )。

这里写图片描述
这里写图片描述
这样就搞定了一个账号的设定了! 从此以后,你可以建立任何名称的账号~不过,还是不建议您设定一些很怪很怪的账号名称啦!

14.7.3 大量建置账号模板(适用 passwd –stdin 选项)
由于 CentOS 5.x 的 passwd 已经提供了 –stdin 的功能,因此如果我们可以提供账号密码的话, 那么就能够很简单的建置起我们的账号密码了。底下制作一个简单的 script 来执行新增用户的功能!
这里写图片描述
这里写图片描述
接下来只要建立 account1.txt 这个档案即可!建立这个档案里面共有十行,你可以自行建立该档案! 内容每一行一个账号。注意,最终的结果会是每个账号具有与账号相同的密码,且初次登入后, 必须要重新设定密码后才能够再次登入使用系统资源!
这里写图片描述
这支简单的脚本你可以在按如下的连结下载:
http://linux.vbird.org/linux_basic/0410accountmanager/account1.sh

另外,我的 script 是在 zh_TW.big5 的语系下建立的,如果你需要转成万国码 (utf8) 的编码格式, 请下载上述档案后,利用第十章谈到的 iconv 来处理语系的问题!

14.7.4 大量建置账号的范例(适用于连续数字,如学号)
前一小节的内容已经可以满足很多朋友的账号建置方法了,不过,某些时候上述的 script 还是很麻烦! 因为需要手动编辑 account1.txt !如果是类似学校单位这种学号非常类似的账号时,有没有更快的方案? 此外,如果需要每个班级同属于一个群组,不同班级的群组不同,又该如何建置?这是比较麻烦! 目前很多网站都有提供大量建立账号的工具,例如台南县网中心的卧龙大师:
http://news.ols3.net/techdoc/old/howtouse_cmpwd101.htm

提供的好用的 cmpwd 程序,但是小三大师的程序仅供学术单位使用,一般个人是无权使用的(参考上述连结的授权)。 不过,其实我们也可以利用简单的 script 来帮我们达成!例如底下这支程序, 他的执行结果与小三大师提供的程序差不多~但是因为我是直接以 useradd 来新增的, 所以,即使不了解 UID ,也是可以适用的~整支程序的特色是:

  • 默认与允许使用纯数字方式建立账号;
  • 可加入年级来区分账号;
  • 可设定账号的起始号码与账号数量;
  • 有两种密码建立方式,可以与账号相同或程序自行以随机数建立密码文件。

执行方法也简单的要命~请自行参考!注意不要在公家使用的主机上面进行测试,因为….. 这支程序会大量建立账号!
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
如果有需要建立同一班级具有同一群组的话,可以先使用 groupadd 建立群组后, 将该群组加入『 cat “$accountfile” | cut -d’:’ -f1 | xargs -n 1 useradd -m -g groupname 』那行!这支脚本可以在底下
连结下载:
http://linux.vbird.org/linux_basic/0410accountmanager/account2.sh

如果仅是测试而已,想要将刚刚建立的使用者整个删除,则可以使用如下的脚本来进行删除!
这里写图片描述
总之,账号管理是很重要的!希望上面的说明能够对大家有点帮助!

猜你喜欢

转载自blog.csdn.net/kk53976047/article/details/79222453