linux 下关于用户的操作

Linux 的账号与群组

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

使用者标识符: UID 与 GID

虽然我们登陆 Linux 主机的时候,输入的是我们的账号,但是其实 Linux 主机并不会直接认识你的『账号名称』的,他仅认识 ID 啊 (ID 就是一组号码啦)。 由于计算机仅认识 0 与 1,所以主机对于数字比较有概念的;至于账号只是为了让人们容易记忆而已。 而你的 ID 与账号的对应就在 /etc/passwd 当中哩。

每一个文件都具有『拥有人与拥有群组』的属性吗?没错啦~每个登陆的使用者至少都会取得两个 ID ,一个是使用者 ID (User ID ,简称 UID)、一个是群组 ID (Group ID ,简称 GID)。
 
那么文件如何判别他的拥有者与群组呢?其实就是利用 UID 与 GID 啦!每一个文件都会有所谓的拥有者 ID 与拥有群组 ID ,当我们有要显示文件属性的需求时,系统会依据 /etc/passwd 与 /etc/group 的内容, 找到 UID / GID 对应的账号与组名再显示出来!我们可以作个小实验,你可以用 root 的身份 vi /etc/passwd ,然后将你的一般身份的使用者的 ID 随便改一个号码,然后再到你的一般身份的目录下看看原先该账号拥有的文件,你会发现该文件的拥有人变成了 『数字了』呵呵!这样可以理解了吗?来看看底下的例子:
 
复制代码
# 1. 先察看一下,系统里面有没有一个名为 dmtsai 的用户?
[root@www ~]# grep 'dmtsai' /etc/passwd
dmtsai:x:503:504::/home/dmtsai:/bin/bash   <==是有这个账号喔!
[root@www ~]# ll -d /home/dmtsai
drwx------ 4 dmtsai dmtsai 4096 Feb  6 18:25 /home/dmtsai
# 瞧一瞧,使用者的字段正是 dmtsai 本身喔!

# 2. 修改一下,将刚刚我们的 dmtsai 的 503 UID 改为 2000 看看:
[root@www ~]# vi /etc/passwd
....(前面省略)....
dmtsai:x:2000:504::/home/dmtsai:/bin/bash <==修改一下特殊字体部分,由 503 改过来
[root@www ~]# ll -d /home/dmtsai
drwx------ 4 503 dmtsai 4096 Feb  6 18:25 /home/dmtsai
# 很害怕吧!怎么变成 503 了?因为文件只会记录数字而已!
# 因为我们乱改,所以导致 503 找不到对应的账号,因此显示数字!

# 3. 记得将刚刚的 2000 改回来!
[root@www ~]# vi /etc/passwd
....(前面省略)....
dmtsai:x:503:504::/home/dmtsai:/bin/bash <==赶紧改回来!
复制代码

你一定要了解的是,上面的例子仅是在说明 UID 与账号的对应性,在一部正常运行的 Linux 主机环境下,上面的动作不可随便进行, 这是因为系统上已经有很多的数据被创建存在了,随意修改系统上某些账号的 UID 很可能会导致某些程序无法进行,这将导致系统无法顺利运行的结果。 因为权限的问题啊!所以,了解了之后,请赶快回到 /etc/passwd 里面,将数字改回来喔!

 

使用者账号

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

/etc/passwd 文件结构

这个文件的构造是这样的:每一行都代表一个账号,有几行就代表有几个账号在你的系统中! 不过需要特别留意的是,里头很多账号本来就是系统正常运行所必须要的,我们可以简称他为系统账号, 例如 bin, daemon, adm, nobody 等等,这些账号请不要随意的杀掉他呢! 这个文件的内容有点像这样:

[root@www ~]# head -n 4 /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

我们先来看一下每个 Linux 系统都会有的第一行,就是 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~499
    (系统账号)
    保留给系统使用的 ID,其实除了 0 之外,其他的 UID 权限与特性并没有不一样。默认 500 以下的数字让给系统作为保留账号只是一个习惯。

    由于系统上面启动的服务希望使用较小的权限去运行,因此不希望使用 root 的身份去运行这些服务, 所以我们就得要提供这些运行中程序的拥有者账号才行。这些系统账号通常是不可登陆的。

    根据系统账号的由来,通常系统账号又约略被区分为两种:
    1~99:由 distributions 自行创建的系统账号;
    100~499:若用户有系统账号需求时,可以使用的账号 UID。
    500~65535
    (可登陆账号)
    给一般使用者用的。事实上,目前的 linux 核心 (2.6.x 版)已经可以支持到 4294967295 (2^32-1) 这么大的 UID 号码喔!

    上面这样说明可以了解了吗?是的, UID 为 0 的时候,就是 root 呦!所以请特别留意一下你的 /etc/passwd 文件!

  4. GID
    这个与 /etc/group 有关!其实 /etc/group 的观念与 /etc/passwd 差不多,只是他是用来规范组名与 GID 的对应而已!

  5. 用户信息说明栏
    这个字段基本上并没有什么重要用途,只是用来解释这个账号的意义而已!不过,如果您提供使用 finger 的功能时, 这个字段可以提供很多的信息呢!本章后面的 chfn 命令会来解释这里的说明。

  6. 家目录
    这是用户的家目录,以上面为例, root 的家目录在 /root ,所以当 root 登陆之后,就会立刻跑到 /root 目录里头啦!呵呵! 如果你有个账号的使用空间特别的大,你想要将该账号的家目录移动到其他的硬盘去该怎么作? 没有错!可以在这个字段进行修改呦!默认的用户家目录在 /home/yourIDname

  7. 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 文件有点像这样:

[root@www ~]# head -n 4 /etc/shadow
root:$1$/30QpE5e$y9N/D0bh6rAACBEz.hqo00:14126:0:99999:7:::  <==底下说明用
bin:*:14126:0:99999:7:::
daemon:*:14126:0:99999:7:::
adm:*:14126:0:99999:7:::

基本上, 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 命令的帮忙!至于想要知道某个日期的累积日数, 可使用如下的程序计算:
  4. [root@www ~]# echo $(($(date --date="2008/09/04" +%s)/86400+1))
    14126

    上述命令中,2008/09/04 为你想要计算的日期,86400 为每一天的秒数, %s 为 1970/01/01 以来的累积总秒数。 由于 bash 仅支持整数,因此最终需要加上 1 补齐 1970/01/01 当天。

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

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

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

  8. 口令过期后的账号宽限时间(口令失效日):(与第 5 字段相比)
    口令有效日期为『升级日期(第3字段)』+『重新变更日期(第5字段)』,过了该期限后用户依旧没有升级口令,那该口令就算过期了。 虽然口令过期但是该账号还是可以用来进行其他工作的,包括登陆系统取得 bash 。不过如果口令过期了, 那当你登陆系统时,系统会强制要求你必须要重新配置口令才能登陆继续使用喔,这就是口令过期特性

    那这个字段的功能是什么呢?是在口令过期几天后,如果使用者还是没有登陆更改口令,那么这个账号的口令将会『失效』, 亦即该账号再也无法使用该口令登陆了。要注意口令过期与口令失效并不相同

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

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

举个例子来说好了,假如我的 dmtsai 这个用户的口令栏如下所示:

dmtsai:$1$vyUuj.eX$omt6lKJvMcIZHx4H7RI1V.:14299:5:60:7:5:14419:

 这表示什么呢?先要注意的是 14299 是 2009/02/24 。所以 dmtsai 这个用户的口令相关意义是:

由于口令几乎仅能单向运算(由明码计算成为口令,无法由口令反推回明码),因此由上表的数据我们无法得知 dmstai 的实际口令明文

此账号最近一次更动口令的日期是 2009/02/24 (14299);

能够再次修改口令的时间是 5 天以后,也就是 2009/03/01 以前 dmtsai 不能修改自己的口令;如果用户还是尝试要更动自己的口令,系统就会出现这样的信息:

You must wait longer to change your password
passwd: Authentication token manipulation error

画面中告诉我们:你必须要等待更久的时间才能够变更口令之意啦!

由于口令过期日期定义为 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 登陆系统就会发现如下的信息:

Warning: your password will expire in 5 days

如果该账号一直到 2009/04/25 都没有更改口令,那么口令就过期了。但是由于有 5 天的宽限天数, 因此 dmtsai 在 2009/04/30 前都还可以使用旧口令登陆主机。 不过登陆时会出现强制更改口令的情况,画面有点像底下这样:

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:

你必须要输入一次旧口令以及两次新口令后,才能够开始使用系统的各项资源。如果你是在 2009/04/30 以后尝试以 dmtsai 登陆的话,那么就会出现如下的错误信息且无法登陆,因为此时你的口令就失效去啦!

Your account has expired; please contact your system administrator

如果使用者在 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 口令即可。

 
 

关于群组: 有效与初始群组、groups, newgrp

认识了账号相关的两个文件 /etc/passwd 与 /etc/shadow 之后,你或许还是会觉得奇怪, 那么群组的配置文件在哪里?还有,在 /etc/passwd 的第四栏不是所谓的 GID 吗?那又是啥? 呵呵~此时就需要了解 /etc/group 与 /etc/gshadow 啰~
/etc/group 文件结构
 
这个文件就是在记录 GID 与组名的对应了~鸟哥测试机的 /etc/group 内容有点像这样:
[root@www ~]# head -n 4 /etc/group
root:x:0:root
bin:x:1:root,bin,daemon
daemon:x:2:root,bin,daemon
sys:x:3:root,bin,adm

这个文件每一行代表一个群组,也是以冒号『:』作为字段的分隔符,共分为四栏,每一字段的意义是:

  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 相关的内容如下:。
复制代码
[root@www ~]# usermod -G users dmtsai  <==先配置好次要群组
[root@www ~]# grep dmtsai /etc/passwd /etc/group /etc/gshadow
/etc/passwd:dmtsai:x:503:504::/home/dmtsai:/bin/bash
/etc/group:users:x:100:dmtsai  <==次要群组的配置
/etc/group:dmtsai:x:504:       <==因为是初始群组,所以第四字段不需要填入账号
/etc/gshadow:users:::dmtsai    <==次要群组的配置
/etc/gshadow:dmtsai:!::
复制代码

仔细看到上面这个表格,在 /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@www ~]$ groups
dmtsai users

在这个输出的信息中,可知道 dmtsai 这个用户同时属于 dmtsai 及 users 这个两个群组,而且, 第一个输出的群组即为有效群组 (effective group) 了。 也就是说,我的有效群组为 dmtsai 啦~此时,如果我以 touch 去创建一个新档,例如: 『 touch test 』,那么这个文件的拥有者为 dmtsai ,而且群组也是 dmtsai 的啦。

[dmtsai@www ~]$ touch test
[dmtsai@www ~]$ ll
-rw-rw-r-- 1 dmtsai dmtsai 0 Feb 24 17:26 test

这样是否可以了解什么是有效群组了?通常有效群组的作用是在新建文件啦!那么有效群组是否能够变换?

 

newgrp: 有效群组的切换

那么如何变更有效群组呢?就使用 newgrp 啊!不过使用 newgrp 是有限制的,那就是你想要切换的群组必须是你已经有支持的群组。举例来说, dmtsai 可以在 dmtsai/users 这两个群组间切换有效群组,但是 dmtsai 无法切换有效群组成为 sshd 啦!使用的方式如下:

复制代码
[dmtsai@www ~]$ newgrp users
[dmtsai@www ~]$ groups
users dmtsai
[dmtsai@www ~]$ touch test2
[dmtsai@www ~]$ ll
-rw-rw-r-- 1 dmtsai dmtsai 0 Feb 24 17:26 test
-rw-r--r-- 1 dmtsai users  0 Feb 24 17:33 test2
复制代码

此时,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 的内容有点像这样:

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

这个文件内同样还是使用冒号『:』来作为字段的分隔字符,而且你会发现,这个文件几乎与 /etc/group 一模一样啊!是这样没错~不过,要注意的大概就是第二个字段吧~第二个字段是口令栏, 如果口令栏上面是『!』时,表示该群组不具有群组管理员!至于第四个字段也就是支持的账号名称啰~ 这四个字段的意义为:

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

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

useradd

完全参考默认值创建一个用户,名称为 vbird1

[root@www ~]# useradd vbird1
[root@www ~]# ll -d /home/vbird1
drwx------ 4 vbird1 vbird1 4096 Feb 25 09:38 /home/vbird1
# 默认会创建用户家目录,且权限为 700 !这是重点!
[root@www ~]# grep vbird1 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird1:x:504:505::/home/vbird1:/bin/bash
/etc/shadow:vbird1:!!:14300:0:99999:7:::
/etc/group:vbird1:x:505:    <==默认会创建一个与账号一模一样的群组名

由于在 /etc/shadow 内仅会有口令参数而不会有加密过的口令数据,因此我们在创建使用者账号时, 还需要使用『 passwd 账号 』来给予口令才算是完成了用户创建的流程。

 

假设我已知道我的系统当中有个组名为 users ,且 UID 700 并不存在,请用 users 为初始群组,以及 uid 为 700 来创建一个名为 vbird2 的账号

复制代码
[root@www ~]# useradd -u 700 -g users vbird2
[root@www ~]# ll -d /home/vbird2
drwx------ 4 vbird2 users 4096 Feb 25 09:59 /home/vbird2

[root@www ~]# grep vbird2 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird2:x:700:100::/home/vbird2:/bin/bash
/etc/shadow:vbird2:!!:14300:0:99999:7:::
# 看一下,UID 与 initial group 确实改变成我们需要的了!
复制代码

在这个范例中,我们创建的是指定一个已经存在的群组作为使用者的初始群组,因为群组已经存在, 所以在 /etc/group 里面就不会主动的创建与账号同名的群组了! 此外,我们也指定了特殊的 UID 来作为使用者的专属 UID 喔!

 

创建一个系统账号,名称为 vbird3

复制代码
[root@www ~]# useradd -r vbird3
[root@www ~]# ll -d /home/vbird3
ls: /home/vbird3: No such file or directory  <==不会主动创建家目录

[root@www ~]# grep vbird3 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird3:x:100:103::/home/vbird3:/bin/bash
/etc/shadow:vbird3:!!:14300::::::
/etc/group:vbird3:x:103:
复制代码

我们在谈到 UID 的时候曾经说过一般账号应该是 500 号以后,那用户自己创建的系统账号则一般是由 100 号以后起算的。 所以在这里我们加上 -r 这个选项以后,系统就会主动将账号与账号同名群组的 UID/GID 都指定小于 500 以下, 在本案例中则是使用 100(UID) 与 103(GID) 啰!此外,由于系统账号主要是用来进行运行系统所需服务的权限配置, 所以系统账号默认都不会主动创建家目录的

useradd 的默认值

复制代码
[root@www ~]# useradd -D
GROUP=100        <==默认的群组
HOME=/home        <==默认的家目录所在目录
INACTIVE=-1        <==口令失效日,在 shadow 内的第 7 栏
EXPIRE=            <==账号失效日,在 shadow 内的第 8 栏
SHELL=/bin/bash        <==默认的 shell
SKEL=/etc/skel        <==用户家目录的内容数据参考目录
CREATE_MAIL_SPOOL=yes   <==是否主动帮使用者创建邮件信箱(mailbox)
复制代码

 

passwd

使用 useradd 创建了账号之后,在默认的情况下,该账号是暂时被封锁的, 也就是说,该账号是无法登陆的,配置口令就使用 passwd

 

请 root 给予 vbird2 口令

[root@www ~]# passwd vbird2
Changing password for user vbird2.
New UNIX password: <==这里直接输入新的口令,屏幕不会有任何反应
BAD PASSWORD: it is WAY too short <==口令太简单或过短的错误!
Retype new UNIX password:  <==再输入一次同样的口令
passwd: all authentication tokens updated successfully.  <==竟然还是成功修改了!

用 vbird2 登陆后,修改 vbird2 自己的口令

复制代码
[vbird2@www ~]$ passwd   <==后面没有加账号,就是改自己的口令!
Changing password for user vbird2.
Changing password for vbird2
(current) UNIX password: <==这里输入『原有的旧口令』
New UNIX password: <==这里输入新口令
BAD PASSWORD: it is based on a dictionary word <==口令检验不通过,请再想个新口令
New UNIX password: <==这里再想个来输入吧
Retype new UNIX password: <==通过口令验证!所以重复这个口令的输入
passwd: all authentication tokens updated successfully. <==有无成功看关键词
复制代码

与 root 不同的是,一般账号在更改口令时需要先输入自己的旧口令 (亦即 current 那一行),然后再输入新口令 (New 那一行)。 要注意的是,口令的规范是非常严格的,尤其新的 distributions 大多使用 PAM 模块来进行口令的检验,包括太短、 口令与账号相同、口令为字典常见字符串等,都会被 PAM 模块检查出来而拒绝修改口令,此时会再重复出现『 New 』这个关键词! 那时请再想个新口令!若出现『 Retype 』才是你的口令被接受了!重复输入新口令并且看到『 successfully 』这个关键词时才是修改口令成功喔!

 

使用 standard input 创建用户的口令

[root@www ~]# echo "abc543CC" | passwd --stdin vbird2
Changing password for user vbird2.
passwd: all authentication tokens updated successfully.

这个动作会直接升级用户的口令而不用再次的手动输入!好处是方便处理,缺点是这个口令会保留在命令中, 未来若系统被攻破,人家可以在 /root/.bash_history 找到这个口令呢!所以这个动作通常仅用在 shell script 的大量创建使用者账号当中!

 

管理 vbird2 的口令使具有 60 天变更、10 天口令失效的配置

复制代码
[root@www ~]# passwd -S vbird2
vbird2 PS 2009-02-26 0 99999 7 -1 (Password set, MD5 crypt.)
# 上面说明口令创建时间 (2009-02-26)、0 最小天数、99999 变更天数、7 警告日数
# 与口令不会失效 (-1) 。

[root@www ~]# passwd -x 60 -i 10 vbird2
[root@www ~]# passwd -S vbird2
vbird2 PS 2009-02-26 0 60 7 10 (Password set, MD5 crypt.)
复制代码

让 vbird2 的账号失效,观察完毕后再让她激活

复制代码
[root@www ~]# passwd -l vbird2
[root@www ~]# passwd -S vbird2
vbird2 LK 2009-02-26 0 60 7 10 (Password locked.)
# 嘿嘿!状态变成『 LK, Lock 』了啦!无法登陆喔!
[root@www ~]# grep vbird2 /etc/shadow
vbird2:!!$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10::
# 其实只是在这里加上 !! 而已!

[root@www ~]# passwd -u vbird2
[root@www ~]# grep vbird2 /etc/shadow
vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10::
# 口令字段恢复正常!
复制代码

 

chage

除了使用 passwd -S 之外,有没有更详细的口令参数显示功能呢?有的!那就是 chage 了!

 

列出 vbird2 的详细口令参数

复制代码
[root@www ~]# chage -l vbird2
Last password change                               : Feb 26, 2009
Password expires                                   : Apr 27, 2009
Password inactive                                  : May 07, 2009
Account expires                                    : never
Minimum number of days between password change     : 0
Maximum number of days between password change     : 60
Number of days of warning before password expires  : 7
复制代码

chage 有一个功能很不错喔!如果你想要让『使用者在第一次登陆时, 强制她们一定要更改口令后才能够使用系统资源』,可以利用如下的方法来处理的!

 

创建一个名为 agetest 的账号,该账号第一次登陆后使用默认口令,但必须要更改过口令后,使用新口令才能够登陆系统使用 bash 环境

[root@www ~]# useradd agetest
[root@www ~]# echo "agetest" | passwd --stdin agetest
[root@www ~]# chage -d 0 agetest
# 此时此账号的口令创建时间会被改为 1970/1/1 ,所以会有问题!

尝试以 agetest 登陆的情况

You are required to change your password immediately (root enforced)
WARNING: Your password has expired.
You must change your password now and login again!
Changing password for user agetest.
Changing password for agetest
(current) UNIX password:  <==这个账号被强制要求必须要改口令!

非常有趣吧!你会发现 agetest 这个账号在第一次登陆时可以使用与账号同名的口令登陆, 但登陆时就会被要求立刻更改口令,更改口令完成后就会被踢出系统。再次登陆时就能够使用新口令登陆了!

 

usermod

在 useradd 的时候加入了错误的配置数据。或者是,在使用 useradd 后,发现某些地方还可以进行细部修改。 此时,当然我们可以直接到 /etc/passwd 或 /etc/shadow 去修改相对应字段的数据, 不过,Linux 也有提供相关的命令让大家来进行账号相关数据的微调呢~那就是 usermod 啰~

 usermod 的选项与 useradd 非常类似! 这是因为 usermod 也是用来微调 useradd 添加的使用者参数嘛!不过 usermod 还是有新增的选项, 那就是 -L 与 -U ,不过这两个选项其实与 passwd 的 -l, -u 是相同的!

 

修改使用者 vbird2 的说明栏,加上『VBird's test』的说明。

[root@www ~]# usermod -c "VBird's test" vbird2
[root@www ~]# grep vbird2 /etc/passwd
vbird2:x:700:100:VBird's test:/home/vbird2:/bin/bash

用户 vbird2 口令在 2009/12/31 失效。

[root@www ~]# usermod -e "2009-12-31" vbird2
[root@www ~]# grep vbird2 /etc/shadow
vbird2:$1$50MnwNFq$oChX.0TPanCq7ecE4HYEi.:14301:0:60:7:10:14609:

我们创建 vbird3 这个系统账号时并没有给予家目录,请创建他的家目录

复制代码
[root@www ~]# ll -d ~vbird3
ls: /home/vbird3: No such file or directory  <==确认一下,确实没有家目录的存在!
[root@www ~]# cp -a /etc/skel /home/vbird3
[root@www ~]# chown -R vbird3:vbird3 /home/vbird3
[root@www ~]# chmod 700 /home/vbird3
[root@www ~]# ll -a ~vbird3
drwx------  4 vbird3 vbird3 4096 Sep  4 18:15 .  <==用户家目录权限
drwxr-xr-x 11 root   root   4096 Feb 26 11:45 ..
-rw-r--r--  1 vbird3 vbird3   33 May 25  2008 .bash_logout
-rw-r--r--  1 vbird3 vbird3  176 May 25  2008 .bash_profile
-rw-r--r--  1 vbird3 vbird3  124 May 25  2008 .bashrc
drwxr-xr-x  3 vbird3 vbird3 4096 Sep  4 18:11 .kde
drwxr-xr-x  4 vbird3 vbird3 4096 Sep  4 18:15 .mozilla
# 使用 chown -R 是为了连同家目录底下的用户/群组属性都一起变更的意思;
# 使用 chmod 没有 -R ,是因为我们仅要修改目录的权限而非内部文件的权限!
复制代码

userdel

这个功能就太简单了,目的在删除用户的相关数据,而用户的数据有:

  • 用户账号/口令相关参数:/etc/passwd, /etc/shadow
  • 使用者群组相关参数:/etc/group, /etc/gshadow
  • 用户个人文件数据: /home/username, /var/spool/mail/username..

整个命令的语法非常简单:

[root@www ~]# userdel [-r] username
选项与参数:
-r  :连同用户的家目录也一起删除

删除 vbird2 ,连同家目录一起删除
[root@www ~]# userdel -r vbird2

这个命令下达的时候要小心了!通常我们要移除一个账号的时候,你可以手动的将 /etc/passwd 与 /etc/shadow 里头的该账号取消即可!一般而言,如果该账号只是『暂时不激活』的话,那么将 /etc/shadow 里头账号失效日期 (第八字段) 配置为 0 就可以让该账号无法使用,但是所有跟该账号相关的数据都会留下来! 使用 userdel 的时机通常是『你真的确定不要让该用户在主机上面使用任何数据了!』

另外,其实用户如果在系统上面操作过一阵子了,那么该用户其实在系统内可能会含有其他文件的。 举例来说,他的邮件信箱 (mailbox) 或者是crontab 之类的文件。 所以,如果想要完整的将某个账号完整的移除,最好可以在下达 userdel -r username 之前, 先以『 find / -user username 』查出整个系统内属于 username 的文件,然后再加以删除吧!

finger

finger 可以查阅很多用户相关的信息喔! 大部分都是在 /etc/passwd 这个文件里面的信息啦!我们就先来检查检查用户信息吧!

 

观察 vbird1 的用户相关账号属性

[root@www ~]# finger vbird1
Login: vbird1                           Name: (null)
Directory: /home/vbird1                 Shell: /bin/bash
Never logged in.
No mail.
No Plan.

由于 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 当然就无法查阅的到! 这样解释可以理解吧?此外,我们可以创建自己想要运行的预定计划,当然,最多是给自己看的!可以这样做:

利用 vbird1 创建自己的计划档

复制代码
[vbird1@www ~]$ echo "I will study Linux during this year." > ~/.plan
[vbird1@www ~]$ finger vbird1
Login: vbird1                           Name: (null)
Directory: /home/vbird1                 Shell: /bin/bash
Never logged in.
No mail.
Plan:
I will study Linux during this year.
复制代码

找出目前在系统上面登陆的用户与登陆时间

[vbird1@www ~]$ finger
Login     Name       Tty      Idle  Login Time   Office     Office Phone
root      root       tty1           Feb 26 09:53
vbird1               tty2           Feb 26 15:21

 

chfn

chfn 是: change finger 的意思!

复制代码
[root@www ~]# chfn [-foph] [账号名]

vbird1 自己更改一下自己的相关信息!
[vbird1@www ~]$ chfn
Changing finger information for vbird1.
Password: <==确认身份,所以输入自己的口令
Name []: VBird Tsai test <==输入你想要呈现的全名
Office []: Dic in Ksu. Tainan <==办公室号码
Office Phone []: 06-2727175#356 <==办公室电话
Home Phone []: 06-1234567 <==家里电话号码

Finger information changed.
[vbird1@www ~]$ grep vbird1 /etc/passwd
vbird1:x:504:505:VBird Tsai test,Dic in Ksu. Tainan,06-2727175#356,06-1234567:
/home/vbird1:/bin/bash
# 其实就是改到第五个字段,该字段里面用多个『 , 』分隔就是了!

[vbird1@www ~]$ finger vbird1
Login: vbird1 Name: VBird Tsai test
Directory: /home/vbird1 Shell: /bin/bash
Office: Dic in Ksu. Tainan Office Phone: 06-2727175#356
Home Phone: 06-1234567
On since Thu Feb 26 15:21 (CST) on tty2
No mail.
Plan:
I will study Linux during this year.
# 就是上面特殊字体呈现的那些地方是由 chfn 所修改出来的!
复制代码

这个命令说实在的,除非是你的主机有很多的用户,否则倒真是用不着这个程序!这就有点像是 bbs 里头更改你『个人属性』的那一个数据啦!不过还是可以自己玩一玩!尤其是用来提醒自己相关数据啦! ^_^

 

chsh

这就是 change shell 的简写!使用方法就更简单了!

 

用 vbird1 的身份列出系统上所有合法的 shell,并且指定 csh 为自己的 shell

复制代码
[vbird1@www ~]$ chsh -l
/bin/sh
/bin/bash
/sbin/nologin  <==所谓:合法不可登陆的 Shell 就是这玩意!
/bin/tcsh
/bin/csh       <==这就是 C shell 啦!
/bin/ksh
# 其实上面的信息就是我们在 bash 中谈到的 /etc/shells 啦!

[vbird1@www ~]$ chsh -s /bin/csh; grep vbird1 /etc/passwd
Changing shell for vbird1.
Password:  <==确认身份,请输入 vbird1 的口令
Shell changed.
vbird1:x:504:505:VBird Tsai test,Dic in Ksu. Tainan,06-2727175#356,06-1234567:
/home/vbird1:/bin/csh

[vbird1@www ~]$ chsh -s /bin/bash
# 测试完毕后,立刻改回来!

[vbird1@www ~]$ ll $(which chsh)
-rws--x--x 1 root root 19128 May 25  2008 /usr/bin/chsh
复制代码

不论是 chfn 与 chsh ,都是能够让一般用户修改 /etc/passwd 这个系统文件的!所以你猜猜,这两个文件的权限是什么? 一定是 SUID 的功能啦!

 

id

id 这个命令则可以查询某人或自己的相关 UID/GID 等等的信息,他的参数也不少,不过, 都不需要记~反正使用 id 就全部都列出啰

查阅 root 自己的相关 ID 信息!

[root@www ~]# id
uid=0(root) gid=0(root) groups=0(root),1(bin),2(daemon),3(sys),4(adm),6(disk),
10(wheel) context=root:system_r:unconfined_t:SystemLow-SystemHigh
# 上面信息其实是同一行的数据!包括会显示 UID/GID 以及支持的所有群组!
# 至于后面那个 context=... 则是 SELinux 的内容,先不要理会他!

查阅一下 vbird1 吧~

[root@www ~]# id vbird1
uid=504(vbird1) gid=505(vbird1) groups=505(vbird1) context=root:system_r:
unconfined_t:SystemLow-SystemHigh

[root@www ~]# id vbird100
id: vbird100: No such user <== id 这个命令也可以用来判断系统上面有无某账号!

 

groupadd

新建一个群组,名称为 group1

[root@www ~]# groupadd group1
[root@www ~]# grep group1 /etc/group /etc/gshadow
/etc/group:group1:x:702:
/etc/gshadow:group1:!::
# 群组的 GID 也是会由 500 以上最大 GID+1 来决定!

 

groupmod

跟 usermod 类似的,这个命令仅是在进行 group 相关参数的修改而已。

将刚刚上个命令创建的 group1 名称改为 mygroup , GID 为 201

[root@www ~]# groupmod -g 201 -n mygroup group1
[root@www ~]# grep mygroup /etc/group /etc/gshadow
/etc/group:mygroup:x:201:
/etc/gshadow:mygroup:!::

不过,还是那句老话,不要随意的更动 GID ,容易造成系统资源的错乱喔!

 

groupdel

将刚刚的 mygroup 删除!

[root@www ~]# groupdel mygroup

若要删除 vbird1 这个群组的话?

[root@www ~]# groupdel vbird1
groupdel: cannot remove user's primary group.

为什么 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 管理:

复制代码
[root@www ~]# groupadd testgroup <==先创建群组
[root@www ~]# gpasswd testgroup <==给这个群组一个口令吧!
Changing the password for group testgroup
New Password:
Re-enter new password:
# 输入两次口令就对了!
[root@www ~]# gpasswd -A vbird1 testgroup <==加入群组管理员为 vbird1
[root@www ~]# grep testgroup /etc/group /etc/gshadow
/etc/group:testgroup:x:702:
/etc/gshadow:testgroup:$1$I5ukIY1.$o5fmW.cOsc8.K.FHAFLWg0:vbird1:
# 很有趣吧!此时 vbird1 则拥有 testgroup 的主控权喔!身份有点像板主啦!
复制代码

以 vbird1 登陆系统,并且让他加入 vbird1, vbird3 成为 testgroup 成员

复制代码
[vbird1@www ~]$ id
uid=504(vbird1) gid=505(vbird1) groups=505(vbird1) ....
# 看得出来,vbird1 尚未加入 testgroup 群组喔!

[vbird1@www ~]$ gpasswd -a vbird1 testgroup
[vbird1@www ~]$ gpasswd -a vbird3 testgroup
[vbird1@www ~]$ grep testgroup /etc/group
testgroup:x:702:vbird1,vbird3
 

我们都是使用一般账号登陆系统的,等有需要进行系统维护或软件升级时才转为 root 的身份来动作。 那如何让一般使用者转变身份成为 root 呢?主要有两种方式喔:

  • 以『 su - 』直接将身份变成 root 即可,但是这个命令却需要 root 的口令,也就是说,如果你要以 su 变成 root 的话,你的一般使用者就必须要有 root 的口令才行;

  • 以『 sudo 命令 』运行 root 的命令串,由于 sudo 需要事先配置妥当,且 sudo 需要输入用户自己的口令, 因此多人共管同一部主机时, sudo 要比 su 来的好喔!至少 root 口令不会流出去!

底下我们就来说一说 su 跟 sudo 的用法啦!

su

su 是最简单的身份切换命令了,他可以进行任何身份的切换唷!方法如下:

复制代码
[root@www ~]# su [-lm] [-c 命令] [username]
选项与参数:
-   :单纯使用 - 如『 su - 』代表使用 login-shell 的变量文件读取方式来登陆系统;
      若使用者名称没有加上去,则代表切换为 root 的身份。
-l  :与 - 类似,但后面需要加欲切换的使用者账号!也是 login-shell 的方式。
-m  :-m 与 -p 是一样的,表示『使用目前的环境配置,而不读取新使用者的配置文件』
-c  :仅进行一次命令,所以 -c 后面可以加上命令喔!
复制代码

假设你原本是 vbird1 的身份,想要使用 non-login shell 的方式变成 root

复制代码
[vbird1@www ~]$ su       <==注意提示字符,是 vbird1 的身份喔!
Password:                <==这里输入 root 的口令喔!
[root@www vbird1]# id    <==提示字符的目录是 vbird1 喔!
uid=0(root) gid=0(root) groups=0(root),1(bin),...   <==确实是 root 的身份!
[root@www vbird1]# env | grep 'vbird1'
USER=vbird1
PATH=/usr/local/bin:/bin:/usr/bin:/home/vbird1/bin  <==这个影响最大!
MAIL=/var/spool/mail/vbird1                         <==收到的 mailbox 是 vbird1
PWD=/home/vbird1                                    <==并非 root 的家目录
LOGNAME=vbird1
# 虽然你的 UID 已经是具有 root 的身份,但是看到上面的输出信息吗?
# 还是有一堆变量为原本 vbird1 的身份,所以很多数据还是无法直接利用。
[root@www vbird1]# exit   <==这样可以离开 su 的环境!
复制代码

单纯使用『 su 』切换成为 root 的身份,读取的变量配置方式为 non-login shell 的方式,这种方式很多原本的变量不会被改变, 尤其是我们之前谈过很多次的 PATH 这个变量,由于没有改变成为 root 的环境 (一堆 /sbin, /usr/sbin 等目录都没有被包含进来), 因此很多 root 惯用的命令就只能使用绝对路径来运行咯。其他的还有 MAIL 这个变量,你输入 mail 时, 收到的邮件竟然还是 vbird1 的,而不是 root 本身的邮件!

 

使用 login shell 的方式切换为 root 的身份并观察变量

复制代码
[vbird1@www ~]$ su -
Password:   <==这里输入 root 的口令喔!
[root@www ~]# env | grep root
USER=root
MAIL=/var/spool/mail/root
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
PWD=/root
HOME=/root
LOGNAME=root
# 了解差异了吧?下次变换成为 root 时,记得最好使用 su - 喔!
[root@www ~]# exit   <==这样可以离开 su 的环境!
复制代码

上述的作法是让使用者的身份变成 root 并开始操作系统,如果想要离开 root 的身份则得要利用 exit 离开才行。 那我如果只是想要运行『一个只有 root 才能进行的命令,且运行完毕

就恢复原本的身份』呢?那就可以加上 -c 这个选项啰

vbird1 想要运行『 head -n 3 /etc/shadow 』一次,且已知 root 口令

复制代码
[vbird1@www ~]$ head -n 3 /etc/shadow
head: cannot open `/etc/shadow' for reading: Permission denied
[vbird1@www ~]$ su - -c "head -n 3 /etc/shadow"
Password: <==这里输入 root 的口令喔!
root:$1$/30QpEWEBEZXRD0bh6rAABCEQD.BAH0:14126:0:99999:7:::
bin:*:14126:0:99999:7:::
daemon:*:14126:0:99999:7:::
[vbird1@www ~]$ <==注意看,身份还是 vbird1 喔!继续使用旧的身份进行系统操作!
复制代码

由于 /etc/shadow 权限的关系,该文件仅有 root 可以查阅。为了查阅该文件,所以我们必须要使用 root 的身份工作。 但我只想要进行一次该命令而已,此时就使用类似上面的语法吧!好,那接下来,如果我是 root 或者是其他人, 想要变更成为某些特殊账号,可以使用如下的方法来切换喔!

 

原本是 vbird1 这个使用者,想要变换身份成为 dmtsai 时

复制代码
[vbird1@www ~]$ su -l dmtsai
Password: <==这里输入 dmtsai 的口令喔!
[dmtsai@www ~]$ su -
Password: <==这里输入 root 的口令喔!
[root@www ~]# id sshd
uid=74(sshd) gid=74(sshd) groups=74(sshd) ... <==确实有存在此人
[root@www ~]# su -l sshd
This account is currently not available.      <==竟然说此人无法切换?
[root@www ~]# finger sshd
Login: sshd                             Name: Privilege-separated SSH
Directory: /var/empty/sshd              Shell: /sbin/nologin
[root@www ~]# exit    <==离开第二次的 su 
[dmtsai@www ~]$ exit  <==离开第一次的 su 
[vbird1@www ~]$ exit  <==这才是最初的环境! 
复制代码

su 就这样简单的介绍完毕,总结一下他的用法是这样的:

  • 若要完整的切换到新使用者的环境,必须要使用『 su - username 』或『 su -l username 』, 才会连同 PATH/USER/MAIL 等变量都转成新用户的环境;

  • 如果仅想要运行一次 root 的命令,可以利用『 su - -c "命令串" 』的方式来处理;

  • 使用 root 切换成为任何使用者时,并不需要输入新用户的口令;

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

sudo

相对于 su 需要了解新切换的用户口令 (常常是需要 root 的口令), sudo 的运行则仅需要自己的口令即可! 甚至可以配置不需要口令即可运行 sudo 呢!由于 sudo 可以让你以其他用户的身份运行命令 (通常是使用 root 的身份来运行命令),因此并非所有人都能够运行 sudo , 而是仅有规范到 /etc/sudoers 内的用户才能够运行 sudo 这个命令喔!说的这么神奇,底下就来瞧瞧那 sudo 如何使用?

 
你想要以 sshd 的身份在 /tmp 底下创建一个名为 mysshd 的文件
[root@www ~]# sudo -u sshd touch /tmp/mysshd
[root@www ~]# ll /tmp/mysshd
-rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd
# 特别留意,这个文件的权限是由 sshd 所创建的情况喔!

你想要以 vbird1 的身份创建 ~vbird1/www 并于其中创建 index.html 文件

复制代码
[root@www ~]# sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
>  echo 'This is index.html file' > index.html"
[root@www ~]# ll -a ~vbird1/www
drwxr-xr-x 2 vbird1 vbird1 4096 Feb 28 17:51 .
drwx------ 5 vbird1 vbird1 4096 Feb 28 17:51 ..
-rw-r--r-- 1 vbird1 vbird1   24 Feb 28 17:51 index.html
# 要注意,创建者的身份是 vbird1 ,且我们使用 sh -c "一串命令" 来运行的!
复制代码

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 的配置方式有几种简单的方法喔,底下我们以几个简单的例子来分别说明:

  1. 单一用户可进行 root 所有命令,与 sudoers 文件语法:

    假如我们要让 vbird1 这个账号可以使用 root 的任何命令,那么可以简单的这样进行修改即可:
    [root@www ~]# visudo
    ....(前面省略)....
    root    ALL=(ALL)       ALL  <==找到这一行,大约在 76 行左右
    vbird1  ALL=(ALL)       ALL  <==这一行是你要新增的!
    ....(前面省略)....

  2. 有趣吧!其实 visudo 只是利用 vi 将 /etc/sudoers 文件呼叫出来进行修改而已,所以这个文件就是 /etc/sudoers 啦! 这个文件的配置其实很简单,如上面所示,如果你找到 76 行 (有 root 配置的那行) 左右,看到的数据就是:
  3. 使用者账号  登陆者的来源主机名=(可切换的身份)  可下达的命令
    root                         ALL=(ALL)           ALL   <==这是默认值
  4. 上面这一行的四个组件意义是:

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

    那个 ALL 是特殊的关键词,代表任何身份、主机或命令的意思。所以,我想让 vbird1 可以进行任何身份的任何命令, 就如同上表特殊字体写的那样,其实就是复制上述默认值那一行,再将 root 改成 vbird1 即可啊! 此时『vbird1 不论来自哪部主机登陆,他可以变换身份成为任何人,且可以进行系统上面的任何命令』之意。 修改完请储存后离开 vi,并以 vbird1 登陆系统后,进行如下的测试看看:
  5. 复制代码
    [vbird1@www ~]$ tail -n 1 /etc/shadow  <==注意!身份是 vbird1
    tail: cannot open `/etc/shadow' for reading: Permission denied
    # 因为不是 root 嘛!所以当然不能查询 /etc/shadow
    
    [vbird1@www ~]$ sudo tail -n 1 /etc/shadow <==透过 sudo
    
    We trust you have received the usual lecture from the local System
    Administrator. It usually boils down to these three things:
    
        #1) Respect the privacy of others.  <==这里仅是一些说明与警示项目
        #2) Think before you type.
        #3) With great power comes great responsibility.
    
    Password: <==注意啊!这里输入的是『 vbird1 自己的口令 』
    pro3:$1$GfinyJgZ$9J8IdrBXXMwZIauANg7tW0:14302:0:99999:7::: 
    # 看!vbird1 竟然可以查询 shadow !
    复制代码
  6. 注意到了吧!vbird1 输入自己的口令就能够运行 root 的命令!所以,系统管理员当然要了解 vbird1 这个用户的『操守』才行!否则随便配置一个用户,他恶搞系统怎办?另外,一个一个配置太麻烦了, 能不能使用群组的方式来配置呢?参考底下的方式吧。

  7. 利用群组以及免口令的功能处理 visudo

    我们在本章前面曾经创建过 pro1, pro2, pro3 ,这三个用户能否透过群组的功能让这三个人可以管理系统? 可以的,而且很简单!同样我们使用实际案例来说明:
  8. [root@www ~]# visudo  <==同样的,请使用 root 先配置
    ....(前面省略)....
    %wheel     ALL=(ALL)    ALL <==大约在 84 行左右,请将这行的 # 拿掉!
    # 在最左边加上 % ,代表后面接的是一个『群组』之意!改完请储存后离开
    
    [root@www ~]# usermod -a -G wheel pro1 <==将 pro1 加入 wheel 的支持
  9. 上面的配置值会造成『任何加入 wheel 这个群组的使用者,就能够使用 sudo 切换任何身份来操作任何命令』的意思。 你当然可以将 wheel 换成你自己想要的群组名。接下来,请分别切换身份成为 pro1 及 pro2 试看看 sudo 的运行。
  10. 复制代码
    [pro1@www ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro1
    ....(前面省略)....
    Password:  <==输入 pro1 的口令喔!
    pro3:$1$GfinyJgZ$9J8IdrBXXMwZIauANg7tW0:14302:0:99999:7:::
    
    [pro2@www ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro2
    Password:
    pro2 is not in the sudoers file.  This incident will be reported.
    # 仔细看错误信息他是说这个 pro2 不在 /etc/sudoers 的配置中!
    复制代码
  11. 这样理解群组了吧?如果你想要让 pro3 也支持这个 sudo 的话,不需要重新使用 visudo ,只要利用 usermod 去修改 pro3 的群组支持,让 wheel 也支持 pro3 的话,那他就能够进行 sudo 啰! 简单吧!不过,既然我们都信任这些 sudo 的用户了,能否提供『不需要口令即可使用 sudo 』呢? 就透过如下的方式:
  12. [root@www ~]# visudo  <==同样的,请使用 root 先配置
    ....(前面省略)....
    %wheel     ALL=(ALL)   NOPASSWD: ALL <==大约在 87 行左右,请将 # 拿掉!
    # 在最左边加上 % ,代表后面接的是一个『群组』之意!改完请储存后离开
  13. 重点是那个 NOPASSWD 啦!该关键词是免除口令输入的意思喔!

  14. 有限制的命令操作:

    上面两点都会让使用者能够利用 root 的身份进行任何事情!这样总是不太好~如果我想要让用户仅能够进行部分系统任务, 比方说,系统上面的 myuser1 仅能够帮 root 修改其他用户的口令时,亦即『当使用者仅能使用 passwd 这个命令帮忙 root 修改其他用户的口令』时,你该如何撰写呢?可以这样做:
  15. [root@www ~]# visudo  <==注意是 root 身份
    myuser1    ALL=(root)  /usr/bin/passwd  <==最后命令务必用绝对路径
  16. 上面的配置值指的是『myuser1 可以切换成为 root 使用 passwd 这个命令』的意思。其中要注意的是: 命令字段必须要填写绝对路径才行!否则 visudo 会出现语法错误的状况发生! 此外,上面的配置是有问题的!我们使用底下的命令操作来让您了解:
  17. 复制代码
    [myuser1@www ~]$ sudo passwd myuser3  <==注意,身份是 myuser1
    Password:  <==输入 myuser1 的口令
    Changing password for user myuser3. <==底下改的是 myuser3 的口令喔!这样是正确的
    New UNIX password:
    Retype new UNIX password:
    passwd: all authentication tokens updated successfully.
    
    [myuser1@www ~]$ sudo passwd
    Changing password for user root.  <==见鬼!怎么会去改 root 的口令?
    复制代码
  18. 恐怖啊!我们竟然让 root 的口令被 myuser3 给改变了!下次 root 回来竟无法登陆系统...欲哭无泪~怎办? 所以我们必须要限制用户的命令参数!修改的方法为将上述的那行改一改先:
  19. [root@www ~]# visudo  <==注意是 root 身份
    myuser1    ALL=(root)  !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \
                        !/usr/bin/passwd root
  20. 由于屏幕一行写不完,我将这行写成两行,所以上面第一行最后加上反斜杠啰。加上惊叹号『 ! 』代表『不可运行』的意思。 因此上面这一行会变成:可以运行『 passwd 任意字符』,但是『 passwd 』与『 passwd root 』这两个命令例外! 如此一来 myuser1 就无法改变 root 的口令了!这样这位使用者可以具有 root 的能力帮助你修改其他用户的口令, 而且也不能随意改变 root 的口令!很有用处的!

  21. 透过别名建置 visudo:

    如上述第三点,如果我有 15 个用户需要加入刚刚的管理员行列,那么我是否要将上述那长长的配置写入 15 行啊? 而且如果想要修改命令或者是新增命令时,那我每行都需要重新配置,很麻烦ㄟ!有没有更简单的方式? 是有的!透过别名即可!我们 visudo 的别名可以是『命令别名、帐户别名、主机别名』等。不过这里我们仅介绍帐户别名, 其他的配置值有兴趣的话,可以自行玩玩!

    假设我的 pro1, pro2, pro3 与 myuser1, myuser2 要加入上述的口令管理员的 sudo 列表中, 那我可以创立一个帐户别名称为 ADMPW 的名称,然后将这个名称处理一下即可。处理的方式如下:
  22. [root@www ~]# visudo  <==注意是 root 身份
    User_Alias ADMPW = pro1, pro2, pro3, myuser1, myuser2
    Cmnd_Alias ADMPWCOM = !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \
                          !/usr/bin/passwd root
    ADMPW   ALL=(root)  ADMPWCOM
  23. 我透过 User_Alias 创建出一个新账号,这个账号名称一定要使用大写字符来处理,包括 Cmnd_Alias(命令别名)、Host_Alias(来源主机名别名) 都需要使用大写字符的!这个 ADMPW 代表后面接的那些实际账号。 而该账号能够进行的命令就如同 ADMPWCOM 后面所指定的那样!上表最后一行则写入这两个别名 (账号与命令别名), 未来要修改时,我只要修改 User_Alias 以及 Cmnd_Alias 这两行即可!配置方面会比较简单有弹性喔!

  24. sudo 的时间间隔问题:

    或许您已经发现了,那就是,如果我使用同一个账号在短时间内重复操作 sudo 来运行命令的话, 在第二次运行 sudo 时,并不需要输入自己的口令!sudo 还是会正确的运行喔!为什么呢? 第一次运行 sudo 需要输入口令,是担心由于用户暂时离开座位,但有人跑来你的座位使用你的账号操作系统之故。 所以需要你输入一次口令重新确认一次身份。

    两次运行 sudo 的间隔在五分钟内,那么再次运行 sudo 时就不需要再次输入口令了, 这是因为系统相信你在五分钟内不会离开你的作业,所以运行 sudo 的是同一个人!呼呼!真是很人性化的设计啊~ ^_^。不过如果两次 sudo 操作的间隔超过 5 分钟,那就得要重新输入一次你的口令了 (注4)

    另外要注意的是,因为使用一般账号时,理论上不会使用到 /sbin, /usr/sbin 等目录内的命令,所以 $PATH 变量不会含有这些目录,因此很多管理命令需要使用绝对路径来下达比较妥当喔!

  25. sudo 搭配 su 的使用方式:

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

猜你喜欢

转载自blog.csdn.net/u010258235/article/details/49453333