Linux笔记:5-Linux 账号管理与 ACL 权限设定

发布时间 2023-05-29 00:05:53作者: CD、小月

@

Linux 账号管理与 ACL 权限设定

Linux 的账号与群组

使用者标识符: UID 与 GID

虽然我们登入 Linux 主机的时候,输入的是我们的账号,但是其实 Linux 主机并不会直接认识你的『账号名称』的,他仅认识 ID (ID 就是一组号码)
账号只是为了让人们容易记忆而已。 而你的 ID 与账号的对应就在/etc/passwd 当中。

每个登入的使用者至少都会取得两个 ID ,一个是使用者 ID (User ID ,简称UID)、一个是群组 ID (Group ID ,简称 GID)

文件判别他的拥有者与群组,其实就是利用 UID 与 GID。
每一个文件都会有所谓的拥有者 ID 与拥有群组 ID ,当我们有要显示文件属性的需求时,系统会依据 /etc/passwd 与/etc/group 的内容, 找到 UID / GID 对应的账号与组名再显示出来

使用者账号

用户登录主机,取得 shell 的环境的流程如下:
首先,他必须要在计算机前面利用 tty1~tty6 的终端机提供的 login 接口,并输入账号与密码够登入。如果是透过网络的话,那至少使用者通过 ssh 这个功能。
 
输入密码后系统的处理流程:

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

由上面的流程我们也知道,跟使用者账号有关的有两个非常重要的文件,一个是管理使用者 UID/GID重要参数的 /etc/passwd ,一个则是专门管理密码相关数据的 /etc/shadow。

etc/passwd 文件结构

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

[root@study ~]# 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

每个 Linux 系统都会有的第一行,以 root 这个系统管理员为例, 每一行使用『:』分隔开,共有七个选项。

  1. 账号名称:
    就是账号名;用来提供给对数字不太敏感的人类使用来登入系统的,需要对应的 UID 。例如 root 的UID 对应就是 0 (第三字段);

  2. 密码:
    早期 Unix 系统的密码就是放在这字段上;但是因为这个文件的特性是所有的程序都能够读取,这样一来很容易造成密码数据被窃取, 因此后来就将这个字段的密码数据给他改放到 /etc/shadow 中了。所以这里你会看到一个『 x 』。

  3. UID:
    使用者ID标识符,通常 Linux 对于 UID 有几个限制;

id 范围 该 ID 使用者特性
0 (系统管理员) 当 UID 是 0 时,代表这个账号是『系统管理员』! 所以当你要让其他的账号名称 也具有 root 的权限时,将该账号的 UID 改为 0 即可。 这也就是说,一部系统上 面的系统管理员不见得只有 root 喔! 不过,很不建议有多个账号的 UID 是 0 啦~容易让系统管理员混乱!
1~999 (系统账号) 保留给系统使用的 ID,其实除了 0 之外,其他的 UID 权限与特性并没有不一样。 默认 1000 以下的数字让给系统作为保留账号只是一个习惯。
由于系统上面启动的网络服务或背景服务希望使用较小的权限去运作,因此不希望 使用 root 的身份去执行这些服务, 所以我们就得要提供这些运作中程序的拥有者 账号才行。这些系统账号通常是不可登入的, 所以才会有我们在第十章提到的 /sbin/nologin 这个特殊的 shell 存在。
根据系统账号的由来,通常这类账号又约略被区分为两种:
1~200:由 distributions 自行建立的系统账号;
201~999:若用户有系统账号需求时,可以使用的账号 UID。
1000~60000 (可登入账号) 给一般使用者用的。事实上,目前的 linux 核心 (3.10.x 版)已经可以支持到 4294967295 (2^32-1) 这么大的 UID 号码!
  1. GID:
    该用户的群组ID,该ID为初始群组ID,后面会介绍初始群组和有效群组区别
  2. 用户信息说明栏:
    这个字段基本上并没有什么重要用途,只是用来解释这个账号的意义而已
  3. 家目录:
    这是用户的家目录,以上面为例, root 的家目录在 /root ,所以当 root 登入之后,就会立刻跑到 /root 目录里。
  4. Shell:
    用户登入系统后就会取得一个 Shell 来与系统的核心沟通以进行用户的操作任务。那为何预设 shell 会使用 bash 呢?就是在这个字段指定的。
    这里比较需要注意的是,有一个 shell 可以用来替代成让账号无法取得 shell 环境的登入动作!那就是 /sbin/nologin。

/etc/shadow 文件结构

我们知道很多程序的运作都与权限有关,而权限与 UID/GID 有关!因此各程序当然需要读取/etc/passwd 来了解不同账号的权限。
因此 /etc/passwd 的权限需设定为 -rw-r--r-- , 虽然早期的密码也有加密过,但却放置到 /etc/passwd 的第二个字段,始终不安全;
因为这样的关系,所以后来发展出将密码移动到 /etc/shadow 这个文件分隔开来的技术, 而且还加入很多的密码限制参数在 /etc/shadow 里头。

[root@study ~]# head -n 4 /etc/shadow
root:$6$wtbCCce/PxMeE5wm$KE2IfSJr.YLP7Rcai6oa/T7KFhO...:16559:0:99999:7::: <==底下说明用
bin:*:16372:0:99999:7:::
daemon:*:16372:0:99999:7:::
adm:*:16372:0:99999:7:::

shadow 同样以『:』作为分隔符,共有九个字段:

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

  2. 密码:
    这个字段内的数据才是真正的密码,而且是经过编码的密码 (加密) ;
    这个文件的预设权限是『-rw-------』或者是『----------』,亦即只有 root 才可以读写;
    加密的方式多种多样(如DES, MD5,SHA),但是由于固定的编码系统产生的密码长度必须一致,因此『当你让这个字段的长度改变后,该密码就会失效(算不出来)』。 很多软件透过这个功能,在此字段前加上 ! 或 * 改变密码字段长度,就会让密码『暂时失效』了。

  3. 最近更动密码的日期:
    这个字段记录了『更动密码那一天』的日期;
    计算 Linux 日期的时间是以 1970 年 1 月 1 日作为 1 而累加的日期,1971 年 1 月 1 日则为 366 。

  4. 密码不可被更动的天数:(与第 3 字段相比)
    第四个字段记录:这个账号的密码在最近一次被更改后需要经过几天才可以再被变更!如果是 0 的话,表示密码随时可以更动的意思。

  5. 密码需要重新变更的天数:(与第 3 字段相比)
    为了强制要求用户变更密码,这个字段可以指定在最近一次更改密码后, 在多少天数内需要再次的变更密码才行。你必须要在这个天数内重新设定你的密码,否则这个账号的密码将会『变为过期特性』。

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

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

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

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

举例来说,常常听到人家说:『我的密码忘记了』, 或者是『我的密码不晓得被谁改过,跟原先的不一样了』:

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

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

群组的配置文件为 /etc/group 与 /etc/gshadow;

/etc/group 文件结构

这个文件就是在记录 GID 与组名的映射;

[root@study ~]# head -n 4 /etc/group
root:x:0:
bin:x:1:
daemon:x:2:
sys:x:3:

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

  1. 组名:
    组名,同样用来方便识别,基本上需要与第三字段的 GID 对应。
  2. 群组密码:
    通常不需要设定,这个设定通常是给『群组管理员』使用的,目前很少有这个机会设定群组管理员;
  3. GID:
    群组的 ID 。我们 /etc/passwd 第四个字段使用的 GID 对应的群组名,就是由这里对应出来的。
  4. 已加入该群组的账号名称:
    一个账号可以加入多个群组,那某个账号想要加入此群组时,将该账号填入这个字段即可。 举例来说,如果我想要让 dmtsai 与 alex 也加入 root 这个群组,那么在第一行的最后面加上『dmtsai,alex』,注意不要有空格, 使成为『 root❌0:dmtsai,alex 』。
     

UID /GID 与密码之间的关系, 图示如下:
在这里插入图片描述

有效群组(effective group)与初始群组(initial group)

每个使用者在他的 /etc/passwd 里面的第四栏有所谓的 GID ;
那个 GID 就是所谓的『初始群组 (initial group) 』;也就是说,当用户一登入系统,立刻就拥有这个群组的相关权限。

[root@study ~]# usermod -a -G users dmtsai <==设定好dmtsai 加users这个次要群组
[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 的群组;这就是 initial group。
因为是初始群组,使用者一登入就会主动取得,不需要在 /etc/group 的第四个字段写入该账号。
 
但是非 initial group 的其他群组可就不同了。
举上面这个例子来说,我将 dmtsai 加入 users 这个群组当中,由于 users 这个群组并非是 dmtsai 的初始群组,因此, 我必须要在 /etc/group 这个文件中,找到 users 那一行,并且将 dmtsai 这个账号加入第四栏, 这样 dmtsai 才能够加入 users 这个群组。

因为此时 dmtsai 账号同时支持 dmtsai, wheel 与 users 这三个群组, 因此,在读取/写入/执行文件时,针对群组部分,只要是 users, wheel 与 dmtsai 这三个群组拥有的功能,dmtsai 这个使用者都能够拥有。
不过,这是针对已经存在的文件而言如果今天我要建立一个新的文件或者是新的目录,请问一下,新文件的群组是 dmtsai, wheel 还是 users ?
这就得要检查一下当时的有效群组了 (effective group)。

groups: 所属群组和有效群组的观察

观察用户所属的群组,利用 groups 指令。

[dmtsai@study ~]$ groups
dmtsai wheel users

在这个输出的讯息中,可知道 dmtsai 这个用户同时属于 dmtsai, wheel 及 users 这三个群组,而且,第一个输出的群组即为有效群组 (effective group) 。 也就是说,当前帐户 dmtsai 的有效群组为 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

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 的环境喔!

关于 newgrp 指令:
该指令可以变更目前用户的有效群组,是通过另一个shell 来实现这个功能的
所以,以上面的例子来说, dmtsai 这个使用者目前是以另一个 shell 登入的,而且新的 shell 给予 dmtsai 有效 GID 为users 。
示意图为下:
在这里插入图片描述

虽然用户的环境设定(例如环境变量等等其他数据)不会有影响,但是使用者的『群组权限』将会重新被计算。
但是需要注意,由于是新取得一个 shell ,因此如果你想要回到原本的环境中,请输入 exit回到原本的 shell 。

关于让帐户加入群组
加入一个群组有两个方式:一个是透过系统管理员(root) 利用 usermod 帮你加入,如果 root 太忙了而且你的系统有设定群组管理员,那么你可以透过群组管理员以 gpasswd 帮你加入他所管理的群组。

/etc/gshadow

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

这个文件内同样还是使用冒号『:』来作为字段的分隔字符,这个文件几乎与 /etc/group一模一样。
第二个字段是密码栏, 如果密码栏上面是『!』或空的时,表示该群组不具有群组管理员。
第四个字段也就是属于该群组的账号名称。

四个字段的意义为:

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

以系统管理员的角度,这个 gshadow 最大的功能就是建立群组管理员
群组管理员的作用:
由于系统上面的账号可能会很多,但是我们 root 可能平时太忙碌,所以当有使用者想要加入某些群组时, root 或许会没有空管理。该群组管理员就能够将那个账号加入自己管理的群组中,不过,由于目前有类似 sudo 之类的工具, 所以这个群组管理员的功能已经很少使用了。

账号管理

新增与移除使用者: useradd, 相关配置文件, passwd, usermod, userdel

新增用户指令:useradd (只能系统管理员使用);
密码设置指令:passwd;

useradd

[root@study ~]# useradd [-u UID] [-g 初始群组] [-G 次要群组] [-mM]\
> [-c 说明栏] [-d 家目录绝对路径] [-s shell] 使用者账号名
选项与参数:
-u :后面接的是 UID ,是一组数字。直接指定一个特定的 UID 给这个账号;
-g :后面接的那个组名就是我们上面提到的 initial group 啦~
	该群组的 GID 会被放置到 /etc/passwd 的第四个字段内。
-G :后面接的组名则是这个账号还可以加入的群组。
	这个选项与参数会修改 /etc/group 内的相关资料喔!
-M :强制!不要建立用户家目录!(系统账号默认值)
-m :强制!要建立用户家目录!(一般账号默认值)
-c :这个就是 /etc/passwd 的第五栏的说明内容啦~可以随便我们设定的啦~
-d :指定某个目录成为家目录,而不要使用默认值。务必使用绝对路径!
-r :建立一个系统的账号,这个账号的 UID 会有限制 (参考 /etc/login.defs)
-s :后面接一个 shell ,若没有指定则预设是 /bin/bash 的啦~
-e :后面接一个日期,格式为『YYYY-MM-DD』此项目可写入 shadow 第八字段,
	亦即账号失效日的设定项目啰;
-f :后面接 shadow 的第七字段项目,指定密码是否会失效。0 为立刻失效,
	-1 为永远不失效(密码只会过期而强制于登入时重新设定而已。)
	
范例一:完全参考默认值建立一个用户,名称为 vbird1
[root@study ~]# useradd vbird1
[root@study ~]# ll -d /home/vbird1
drwx------. 3 vbird1 vbird1 74 Jul 20 21:50 /home/vbird1
# 默认会建立用户家目录,且权限为 700 !这是重点!

[root@study ~]# grep vbird1 /etc/passwd /etc/shadow /etc/group
/etc/passwd:vbird1:x:1003:1004::/home/vbird1:/bin/bash
/etc/shadow:vbird1:!!:16636:0:99999:7:::
/etc/group:vbird1:x:1004: <==预设会建立一个与账号一模一样的群组名

可以简单的使用『 useradd 账号 』来建立使用者即可。
CentOS 这些默认值主要会帮我们处理几个项目:

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

useradd 建立使用者账号时,会更改不少地方,我们需要知道底下几个文件:

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

**useradd 参考档 **

当使用 useradd 指令创建用户时,会有一个去参考一个参考文档;帮助建立帐户,并设置其他相关选项。

 useradd 的默认值查看
[root@study ~]# 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)

这些数据是保存在 /etc/default/useradd 当中的;
各数据项意义:

  • GROUP=100:新建账号的初始群组使用 GID 为 100 者
    系统上面 GID 为 100 者即是 users 这个群组,此设定项目指的就是让新设使用者账号的初始群组为 users 这一个的意思。
    但是 CentOS 上面并不是这样的,在 CentOS 上面预设的群组为与账号名相同的群组。
    这是因为针对群组的建立有两种不同的机制所致, 这两种机制分别是:

    • 私有群组机制:
      系统会建立一个与账号一样的群组给使用者作为初始群组。 这种群组的设定机制会比较有保密性,这是因为使用者都有自己的群组,而且家目录权限将会设定为 700 (仅有自己可进入自己的家目录)之故。使用这种机制将不会参考 GROUP=100 这个设定值。代表性的 distributions 有 RHEL,
      Fedora, CentOS 等;
  • 公共群组机制:
    就是以 GROUP=100 这个设定值作为新建账号的初始群组,因此每个账号都属于 users 这个群组,且默认家目录通常的权限会是『 drwxr-xr-x ... username users ... 』,由于每个账号都属于 users 群组,因此大家都可以互相分享家目录内的数据之故。代表 distributions 如 SuSE 等。

  • HOME=/home:用户家目录的基准目录(basedir)

用户的家目录通常是与账号同名的目录,这个目录将会摆放在此设定值的目录后

  • INACTIVE=-1:密码过期后是否会失效的设定值

在 shadow 文件结构当中谈过,第七个字段的设定值将会影响到密码过期后, 在多久时间内还可使用旧密码登入。

  • EXPIRE=:账号失效的日期

就是 shadow 内的第八字段,你可以直接设定账号在哪个日期后就直接失效,而不理会密码的问题。

  • SHELL=/bin/bash:默认使用的 shell 程序文件名

  • SKEL=/etc/skel:用户家目录参考基准目录

指定用户家目录的参考基准目录 ;范例一为例, vbird1 家目录/home/vbird1 内的各项数据,都是由 /etc/skel 所复制过去的 。

  • CREATE_MAIL_SPOOL=yes:建立使用者的 mailbox

除了这些基本的账号参考设定值之外, UID/GID 的参考值文件在 /etc/login.defs

MAIL_DIR /var/spool/mail <==用户默认邮件信箱放置目录
PASS_MAX_DAYS 99999 <==/etc/shadow 内的第 5 栏,多久需变更密码日数
PASS_MIN_DAYS 0 <==/etc/shadow 内的第 4 栏,多久不可重新设定密码日数
PASS_MIN_LEN 5 <==密码最短的字符长度,已被 pam 模块取代,失去效用!
PASS_WARN_AGE 7 <==/etc/shadow 内的第 6 栏,过期前会警告的日数
UID_MIN 1000 <==使用者最小的 UID,意即小于 1000 的 UID 为系统保留
UID_MAX 60000 <==使用者能够用的最大 UID
SYS_UID_MIN 201 <==保留给用户自行设定的系统账号最小值 UID
SYS_UID_MAX 999 <==保留给用户自行设定的系统账号最大值 UID
GID_MIN 1000 <==使用者自定义组的最小 GID,小于 1000 为系统保留
GID_MAX 60000 <==使用者自定义组的最大 GID
SYS_GID_MIN 201 <==保留给用户自行设定的系统账号最小值 GID
SYS_GID_MAX 999 <==保留给用户自行设定的系统账号最大值 GID
CREATE_HOME yes <==在不加 -M 及 -m 时,是否主动建立用户家目录?
UMASK 077 <==用户家目录建立的 umask ,因此权限会是 700
USERGROUPS_ENAB yes <==使用 userdel 删除时,是否会删除初始群组
ENCRYPT_METHOD SHA512 <==密码加密的机制使用的是 sha512 这一个机制!

文件规范的数据说明是如下所示:

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

  • shadow 密码第 4, 5, 6 字段内容:

透过 PASS_MAX_DAYS 等等设定值来指定的!所以你知道为何预设的 /etc/shadow 内每一行都会有『 0:99999:7 』的存在

  • UID/GID 指定数值:

  • 用户家目录设定值:

  • 用户删除与密码设定值:

使用『USERGROUPS_ENAB yes』这个设定值的功能是: 如果使用 userdel 去删除一个账号时,且该账号所属的初始群组已经没有人隶属于该群组了, 那么就删除掉该群组
举例来说,我们刚刚有建立 vbird4 这个账号,他会主动建立 vbird4 这个群组。

总结:
useradd 这支程序在建立 Linux 上的账号时,至少会参考:

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

passwd

通过 useradd 建立帐号后,还需要使用『 passwd 账号 』来给予密码才算是完成了用户建立的流程。

[root@study ~]# passwd [--stdin] [账号名称] <==所有人均可使用来改自己的密码 不添加帐号,及修改当前帐号的密码;
[root@study ~]# passwd [-l] [-u] [--stdin] [-S] \
> [-n 日数] [-x 日数] [-w 日数] [-i 日期] 账号 <==root 功能
选项与参数:
--stdin :可以透过来自前一个管线的数据,作为密码输入,对 shell script 有帮助!
-l :是 Lock 的意思,会将 /etc/shadow 第二栏最前面加上 ! 使密码失效;
-u :与 -l 相对,是 Unlock 的意思!
-S :列出密码相关参数,亦即 shadow 文件内的大部分信息。
-n :后面接天数,shadow 的第 4 字段,多久不可修改密码天数
-x :后面接天数,shadow 的第 5 字段,多久内必须要更动密码
-w :后面接天数,shadow 的第 6 字段,密码过期前的警告天数
-i :后面接『日期』,shadow 的第 7 字段,密码失效日期

范例一:请 root 给予 vbird2 密码
[root@study ~]# passwd vbird2
Changing password for user vbird2.
New UNIX password: <==这里直接输入新的密码,屏幕不会有任何反应
BAD PASSWORD: The password is shorter than 8 characters <==密码太简单或过短的错误!
Retype new UNIX password: <==再输入一次同样的密码
passwd: all authentication tokens updated successfully. <==竟然还是成功修改了!

chage

除了使用 passwd -S 之外,利用指令 chage可以查看更为详细的密码参数
chage 指令:查看和修改密码参数

[root@study ~]# chage [-ldEImMW] 账号名
选项与参数:
-l :列出该账号的详细密码参数;
-d :后面接日期,修改 shadow 第三字段(最近一次更改密码的日期),格式 YYYY-MM-DD
-E :后面接日期,修改 shadow 第八字段(账号失效日),格式 YYYY-MM-DD
-I :后面接天数,修改 shadow 第七字段(密码失效日期)
-m :后面接天数,修改 shadow 第四字段(密码最短保留天数)
-M :后面接天数,修改 shadow 第五字段(密码多久需要进行变更)
-W :后面接天数,修改 shadow 第六字段(密码过期前警告日期)

范例一:列出 vbird2 的详细密码参数
[root@study ~]# chage -l vbird2
Last password change : Jul 20, 2015
Password expires : Sep 18, 2015
Password inactive : Sep 28, 2015
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

usermod

usermod 指令:修改帐户(只能系统管理员使用);

[root@study ~]# usermod [-cdegGlsuLU] username
选项与参数:
-c :后面接账号的说明,即 /etc/passwd 第五栏的说明栏,可以加入一些账号的说明。
-d :后面接账号的家目录,即修改 /etc/passwd 的第六栏;
-e :后面接日期,格式是 YYYY-MM-DD 也就是在 /etc/shadow 内的第八个字段数据啦!
-f :后面接天数,为 shadow 的第七字段。
-g :后面接初始群组,修改 /etc/passwd 的第四个字段,亦即是 GID 的字段!
-G :后面接次要群组,修改这个使用者能够支持的群组,修改的是 /etc/group 啰~
-a :与 -G 合用,可『增加次要群组的支持』而非『设定』喔!
-l :后面接账号名称。亦即是修改账号名称, /etc/passwd 的第一栏!
-s :后面接 Shell 的实际文件,例如 /bin/bash 或 /bin/csh 等等。
-u :后面接 UID 数字啦!即 /etc/passwd 第三栏的资料;
-L :暂时将用户的密码冻结,让他无法登入。其实仅改 /etc/shadow 的密码栏。
-U :将 /etc/shadow 密码栏的 ! 拿掉,解冻啦

userdel

该指令将删除用户的相关数据(只能系统管理员使用),而用户的数据有:

  • 用户账号/密码相关参数:/etc/passwd, /etc/shadow
  • 使用者群组相关参数:/etc/group, /etc/gshadow
  • 用户个人文件数据: /home/username, /var/spool/mail/username..
[root@study ~]# userdel [-r] username
选项与参数:
-r :连同用户的家目录也一起删除

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

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

用户功能

useradd/usermod/userdel ,那都是系统管理员所能够使用的指令
 
一般用户能使用 passwdidfingerchfnchsh等指令,查询与变更账号数据。

id

该指令可以查询某人或自己的相关 UID/GID 等等的信息。

[root@study ~]# id [username]

范例一:查阅 root 自己的相关 ID 信息!
[root@study ~]# id
uid=0(root) gid=0(root) groups=0(root) context=unconfined_u:unconfined_r:unconfined_t:
s0-s0:c0.c1023
# 上面信息其实是同一行的数据!包括会显示 UID/GID 以及支持的所有群组!
# 至于后面那个 context=... 则是 SELinux 的内容,先不要理会他!

范例二:查阅一下 vbird1 吧~
[root@study ~]# id vbird1
uid=1003(vbird1) gid=1004(vbird1) groups=1004(vbird1)
[root@study ~]# id vbird100
id: vbird100: No such user <== id 这个指令也可以用来判断系统上面有无某账号!

finger

可以查阅很多用户相关的信息! 大部分都是在 /etc/passwd 这个文件里面的信息。

[root@study ~]# finger [-s] username
选项与参数:
-s :仅列出用户的账号、全名、终端机代号与登入时间等等;
-m :列出与后面接的账号相同者,而不是利用部分比对 (包括全名部分)
范例一:观察 vbird1 的用户相关账号属性
[root@study ~]# finger vbird1
Login: vbird1 Name:
Directory: /home/vbird1 Shell: /bin/bash
Never logged in.
No mail.
No Plan.

信息说明如下:

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

chfn

chfn即为:change finger,改变用户的 finger 。

[root@study ~]# chfn [-foph] [账号名]
选项与参数:
-f :后面接完整的大名;
-o :您办公室的房间号码;
-p :办公室的电话号码;
-h :家里的电话号码!

范例一:vbird1 自己更改一下自己的相关信息!
[vbird1@study ~]$ chfn
Changing finger information for vbird1.
Name []: VBird Tsai test <==输入你想要呈现的全名
Office []: DIC in KSU <==办公室号码
Office Phone []: 06-2727175#356 <==办公室电话
Home Phone []: 06-1234567 <==家里电话号码
Password: <==确认身份,所以输入自己的密码
Finger information changed.
[vbird1@study ~]$ grep vbird1 /etc/passwd
vbird1:x:1003:1004:VBird Tsai test,DIC in KSU,06-2727175#356,06-1234567:/home/vbird1:/bin/bash
# 其实就是改到第五个字段,该字段里面用多个『 , 』分隔就是了!

[vbird1@study ~]$ finger vbird1
Login: vbird1 Name: VBird Tsai test
Directory: /home/vbird1 Shell: /bin/bash
Office: DIC in KSU, 06-2727175#356 Home Phone: 06-1234567
Last login Mon Jul 20 23:12 (CST) on pts/0
No mail.
Plan:
I will study Linux during this year.
# 就是上面特殊字体呈现的那些地方是由 chfn 所修改出来的!

chsh

chsh:即为 change shell,改变用户的shell。

[vbird1@study ~]$ chsh [-ls]
选项与参数:
-l :列出目前系统上面可用的 shell ,其实就是 /etc/shells 的内容!
-s :设定修改自己的 Shell 啰

范例一:用 vbird1 的身份列出系统上所有合法的 shell,并且指定 csh 为自己的 shell
[vbird1@study ~]$ chsh -l
/bin/sh
/bin/bash
/sbin/nologin <==所谓:合法不可登入的 Shell 就是这玩意!
/usr/bin/sh
/usr/bin/bash
/usr/sbin/nologin
/bin/tcsh
/bin/csh <==这就是 C shell 啦!
# 其实上面的信息就是我们在 bash 中谈到的 /etc/shells 啦!

[vbird1@study ~]$ chsh -s /bin/csh; grep vbird1 /etc/passwd
Changing shell for vbird1.
Password: <==确认身份,请输入 vbird1 的密码
Shell changed.
vbird1:x:1003:1004:VBird Tsai test,DIC in KSU,06-2727175#356,06-1234567:/home/vbird1:/bin/csh

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

[vbird1@study ~]$ ll $(which chsh)
-rws--x--x. 1 root root 23856 Mar 6 13:59 /bin/chsh

不论是 chfn 与 chsh ,都是能够让一般用户修改 /etc/passwd 这个系统文件。

新增与移除群组

与群组的内容相关联的两个文件为:/etc/group, /etc/gshadow。

groupadd

添加群组

[root@study ~]# groupadd [-g gid] [-r] 组名
选项与参数:
-g :后面接某个特定的 GID ,用来直接给予某个 GID ~
-r :建立系统群组啦!与 /etc/login.defs 内的 GID_MIN 有关。

范例一:新建一个群组,名称为 group1
[root@study ~]# groupadd group1
[root@study ~]# grep group1 /etc/group /etc/gshadow
/etc/group:group1:x:1503:
/etc/gshadow:group1:!::
# 群组的 GID 也是会由 1000 以上最大 GID+1 来决定!

groupmod

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

[root@study ~]# groupmod [-g gid] [-n group_name] 群组名
选项与参数:
-g :修改既有的 GID 数字;
-n :修改既有的组名
范例一:将刚刚上个指令建立的 group1 名称改为 mygroup , GID 为 201
[root@study ~]# groupmod -g 201 -n mygroup group1
[root@study ~]# grep mygroup /etc/group /etc/gshadow
/etc/group:mygroup:x:201:
/etc/gshadow:mygroup:!::

groupdel

删除群组

[root@study ~]# groupdel [groupname]

范例一:将刚刚的 mygroup 删除!
[root@study ~]# groupdel mygroup

范例二:若要删除 vbird1 这个群组的话?
[root@study ~]# groupdel vbird1
groupdel: cannot remove the primary group of user 'vbird1'

如果『有某个账号 (/etc/passwd) 的initial group 使用该群组!』则该群组不能删除;
如果硬要删除该群组,可以尝试一下方法:

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

gpasswd:群组管理员功能

群组管理员可以管理群组帐号的加入和移出;
建立一个群组管理员 ,可以通过gpasswd 指令。

# 关于系统管理员(root)做的动作:
[root@study ~]# gpasswd groupname
[root@study ~]# gpasswd [-A user1,...] [-M user3,...] groupname
[root@study ~]# gpasswd [-rR] groupname
选项与参数:
:若没有任何参数时,表示给予 groupname 一个密码(/etc/gshadow)
-A :将 groupname 的主控权交由后面的使用者管理(该群组的管理员)
-M :将某些账号加入这个群组当中!
-r :将 groupname 的密码移除
-R :让 groupname 的密码栏失效

# 关于群组管理员(Group administrator)做的动作:
[someone@study ~]$ gpasswd [-ad] user groupname
选项与参数:
-a :将某位使用者加入到 groupname 这个群组当中!
-d :将某位使用者移除出 groupname 这个群组当中。

范例一:建立一个新群组,名称为 testgroup 且群组交由 vbird1 管理:
[root@study ~]# groupadd testgroup <==先建立群组
[root@study ~]# gpasswd testgroup <==给这个群组一个密码吧!
Changing the password for group testgroup
New Password:
Re-enter new password:
# 输入两次密码就对了!

[root@study ~]# gpasswd -A vbird1 testgroup <==加入群组管理员为 vbird1
[root@study ~]# grep testgroup /etc/group /etc/gshadow
/etc/group:testgroup:x:1503:
/etc/gshadow:testgroup:$6$MnmChP3D$mrUn.Vo.buDjObMm8F2emTkvGSeuWikhRzaKHxpJ...:vbird1:
# 很有趣吧!此时 vbird1 则拥有 testgroup 的主控权喔!身份有点像板主啦!

范例二:以 vbird1 登入系统,并且让他加入 vbird1, vbird3 成为 testgroup 成员
[vbird1@study ~]$ id
uid=1003(vbird1) gid=1004(vbird1) groups=1004(vbird1) ...
# 看得出来,vbird1 尚未加入 testgroup 群组喔!
[vbird1@study ~]$ gpasswd -a vbird1 testgroup
[vbird1@study ~]$ gpasswd -a vbird3 testgroup
[vbird1@study ~]$ grep testgroup /etc/group
testgroup:x:1503:vbird1,vbird3

主机的细微权限规划:ACL 的使用

传统的权限仅有三种身份(owner, group, others) 搭配三种权限 (r,w,x) 而已,并没有办法单纯的针对某一个使用者或某一个群组来设定特定的权限
ACL机制则为满足该需求。

什么是 ACL 与如何支持启动 ACL

ACL 是 Access Control List 的缩写,主要的目的是在提供传统的 owner,group,others 的read,write,execute 权限之外的细部权限设定。
ACL 可以针对单一使用者,单一文件或目录来进行r,w,x 的权限规范,对于需要特殊权限的使用状况非常有帮助。

ACL可以控制权限的分类有:

  • 使用者 (user):可以针对使用者来设定权限;

  • 群组 (group):针对群组为对象来设定其权限;

  • 默认属性 (mask):还可以针对在该目录下在建立新文件/目录时,规范新数据的默认权限;
     

如果你有一个目录,需要给一堆人使用,每个人或每个群组所需要的权限并不相同时在过去,传统的 Linux 三种身份的三种权限是无法达到的, 因为基本上,传统的 Linux 权限只能针对一个用户、一个群组及非此群组的其他人设定权限而已,无法针对单一用户或个人来设计权限。
而ACL 就是为了要改变这个问题。

如何启动 ACL

原本 ACL 是 unix-like 操作系统的额外支持项目,但因为近年以来 Linux 系统对权限更为细微设定的热切需求, 因此目前 ACL 几乎已经预设加入在所有常见的 Linux 文件系统的挂载参数中(ext2/ext3/ext4/xfs 等等)!所以你无须进行任何动作, ACL 就可以被你使用 。

ACL 的设定技巧: getfacl, setfacl

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

setfacl 指令用法

acl 的选项功能  
[root@study ~]# setfacl [-bkRd] [{-m|-x} acl参数 ] 目标文件名
选项与参数:
-m :设定后续的 acl 参数给文件使用,不可与 -x 合用;
-x :删除后续的 acl 参数,不可与 -m 合用;
-b :移除『所有的』 ACL 设定参数;
-k :移除『预设的』 ACL 参数,关于所谓的『预设』参数于后续范例中介绍;
-R :递归设定 acl ,亦即包括次目录都会被设定起来;
-d :设定『预设 acl 参数』的意思!只对目录有效,在该目录新建的数据会引用此默认值

特定使用者的权限设定:『 u:账号:权限 』


# 1. 针对特定使用者的方式:
# 设定规范:『 u:[使用者账号列表]:[rwx] 』,例如针对 vbird1 的权限规范 rx :

[root@study ~]# touch acl_test1
[root@study ~]# ll acl_test1
-rw-r--r--. 1 root root 0 Jul 21 17:33 acl_test1
[root@study ~]# setfacl -m u:vbird1:rx acl_test1
[root@study ~]# ll acl_test1
-rw-r-xr--+ 1 root root 0 Jul 21 17:33 acl_test1
# 权限部分多了个 + ,且与原本的权限 (644) 看起来差异很大!但要如何查阅呢?

[root@study ~]# setfacl -m u::rwx acl_test1
[root@study ~]# ll acl_test1
-rwxr-xr--+ 1 root root 0 Jul 21 17:33 acl_test1
# 设定值中的 u 后面无使用者列表,代表设定该文件拥有者,所以上面显示 root 的权限成为 rwx 了!

上述动作为最简单的 ACL 设定,利用『 u:使用者:权限 』的方式来设定的,设定前请加上 -m 这
个选项;
如果一个文件设定了 ACL 参数后,他的权限部分就会多出一个 + 号;
此时你看到的权限与实际权限可能就会有点误差,可以通过 getfacl 进行详细观察。

getfacl 指令用法

[root@study ~]# getfacl filename
选项与参数:
getfacl 的选项几乎与 setfacl 相同!所以鸟哥这里就免去了选项的说明啊!
# 请列出刚刚我们设定的 acl_test1 的权限内容:

[root@study ~]# getfacl acl_test1
# file: acl_test1 <==说明档名而已!
# owner: root <==说明此文件的拥有者,亦即 ls -l 看到的第三使用者字段
# group: root <==此文件的所属群组,亦即 ls -l 看到的第四群组字段
user::rwx <==使用者列表栏是空的,代表文件拥有者的权限
user:vbird1:r-x <==针对 vbird1 的权限设定为 rx ,与拥有者并不同!
group::r-- <==针对文件群组的权限设定仅有 r
mask::r-x <==此文件预设的有效权限 (mask)
other::r-- <==其他人拥有的权限啰!

特定的单一群组的权限设定:『 g:群组名:权限 』

# 2. 针对特定群组的方式:
# 设定规范:『 g:[群组列表]:[rwx] 』,例如针对 mygroup1 的权限规范 rx :

[root@study ~]# setfacl -m g:mygroup1:rx acl_test1
[root@study ~]# getfacl acl_test1
# file: acl_test1
# owner: root
# group: root
user::rwx
user:vbird1:r-x
group::r--
group:mygroup1:r-x <==这里就是新增的部分!多了这个群组的权限设定!
mask::r-x
other::r--

针对有效权限设定:『 m:权限 』

有效权限:使用者或群组所设定的权限必须要存在于 mask 的权限设定范围内才会生效,此即『有效权限
(effective permission)』

# 3. 针对有效权限 mask 的设定方式:
# 设定规范:『 m:[rwx] 』,例如针对刚刚的文件规范为仅有 r :

[root@study ~]# setfacl -m m:r acl_test1
[root@study ~]# getfacl acl_test1
# file: acl_test1
# owner: root
# group: root
user::rwx
user:vbird1:r-x #effective:r-- <==vbird1+mask 均存在者,仅有 r 而已,x 不会生效
group::r--
group:mygroup1:r-x #effective:r--
mask::r--
other::r--

可以透过使用 mask 来规范最大允许的权限,就能够避免不小心开放某些权限给其他使用者或群组。

使用默认权限设定目录未来文件的 ACL 权限继承『 d:[u|g]:[user|group]:权限 』

# 4. 针对预设权限的设定方式:
# 设定规范:『 d:[ug]:使用者列表:[rwx] 』
# 让 myuser1 在 /srv/projecta 底下一直具有 rx 的预设权限!

[root@study ~]# setfacl -m d:u:myuser1:rx /srv/projecta
[root@study ~]# getfacl /srv/projecta
# file: srv/projecta
# owner: root
# group: projecta
# flags: -suser::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---

[root@study ~]# cd /srv/projecta
[root@study projecta]# touch zzz1
[root@study projecta]# mkdir zzz2
[root@study projecta]# ll -d zzz*
-rw-rw----+ 1 root projecta 0 Jul 21 17:50 zzz1
drwxrws---+ 2 root projecta 6 Jul 21 17:51 zzz2
# 看吧!确实有继承喔!然后我们使用 getfacl 再次确认看看!

[root@study projecta]# getfacl zzz2
# file: zzz2
# owner: root
# group: projecta
# flags: -suser::rwx
user:myuser1:r-x
group::rwx
mask::rwx
other::---
default:user::rwx
default:user:myuser1:r-x
default:group::rwx
default:mask::rwx
default:other::---

通过为目录文件预设ACL值,可以让该ACL值被继承到未来创建的目录文件。
 
注意:
预设ACL值,只对目录有效。

用户身份切换

让一般使用者转变身份成为 root ;主要有两种方式:

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

su

su 是最简单的身份切换指令了,他可以进行任何身份的切换

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

这个 su 的用法当中,有没有加上那个减号『 - 』差很多因为涉及 login-shell 与 non-login shell 的变量读取方法。

范例一:假设你原本是 dmtsai 的身份,想要使用 non-login shell 的方式变成 root
[dmtsai@study ~]$ su <==注意提示字符,是 dmtsai 的身份喔!
Password: <==这里输入 root 的密码喔!
[root@study dmtsai]# id <==提示字符的目录是 dmtsai 喔!
uid=0(root) gid=0(root) groups=0(root) context=unconf.... <==确实是 root 的身份!
[root@study dmtsai]# env | grep 'dmtsai'
USER=dmtsai <==竟然还是 dmtsai 这家伙!
PATH=...:/home/dmtsai/.local/bin:/home/dmtsai/bin <==这个影响最大!
MAIL=/var/spool/mail/dmtsai <==收到的 mailbox 是 vbird1
PWD=/home/dmtsai <==并非 root 的家目录
LOGNAME=dmtsai
# 虽然你的 UID 已经是具有 root 的身份,但是看到上面的输出讯息吗?
# 还是有一堆变量为原本 dmtsai 的身份,所以很多数据还是无法直接利用。
[root@study dmtsai]# exit <==这样可以离开 su 的环境!

单纯使用『 su 』切换成为 root 的身份,读取的变量设定方式为 non-login shell 的方式,这种方式很多原本的变量不会被改变, 尤其是我们之前谈过很多次的 PATH 这个变量,由于没有改变成为root 的环境, 因此很多 root 惯用的指令就只能使用绝对路径来执行 。

范例二:使用 login shell 的方式切换为 root 的身份并观察变量
[dmtsai@study ~]$ su -
Password: <==这里输入 root 的密码喔!
[root@study ~]# 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@study ~]# exit <==这样可以离开 su 的环境!

总结:

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

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

sudo

相对于 su 需要了解新切换的用户密码 (常常是需要 root 的密码), sudo 的执行则仅需要自己的密码即可! 甚至可以设定不需要密码即可执行 sudo 呢!
由于 sudo 可以让你以其他用户的身份执行指令 (通常是使用 root 的身份来执行指令),因此并非所有人都能够执行 sudo , 而是仅有配置到/etc/sudoers 内的用户才能够执行 sudo 这个指令。

sudo 的指令用法

一开始系统默认仅有 root 可以执行 sudo ;
在安装 CentOS 时,在设定一般账号的项目中,有个『让这位使用者成为管理员』的选项;如果你有勾选该选项的话, 那除了 root 之外,该一般用户确实是可以使用 sudo 的。

[root@study ~]# sudo [-b] [-u 新使用者账号]
选项与参数:
b :将后续的指令放到背景中让系统自行执行,而不与目前的 shell 产生影响
-u :后面可以接欲切换的使用者,若无此项则代表切换身份为 root 。

范例一:你想要以 sshd 的身份在 /tmp 底下建立一个名为 mysshd 的文件
[root@study ~]# sudo -u sshd touch /tmp/mysshd
[root@study ~]# ll /tmp/mysshd
-rw-r--r--. 1 sshd sshd 0 Jul 21 23:37 /tmp/mysshd
# 特别留意,这个文件的权限是由 sshd 所建立的情况喔!

范例二:你想要以 vbird1 的身份建立 ~vbird1/www 并于其中建立 index.html 文件
[root@study ~]# sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
> echo 'This is index.html file' > index.html"
[root@study ~]# ll -a ~vbird1/www
drwxr-xr-x. 2 vbird1 vbird1 23 Jul 21 23:38 .
drwx------. 6 vbird1 vbird1 4096 Jul 21 23:38 ..
-rw-r--r--. 1 vbird1 vbird1 24 Jul 21 23:38 index.html
# 要注意,建立者的身份是 vbird1 ,且我们使用 sh -c "一串指令" 来执行的!

sudo 的执行是这样的流程:

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

sudo 执行的重点是:『能否使用 sudo 必须要看 /etc/sudoers 的设定值, 而可使用 sudo 者是透过输入用户自己的密码来执行后续的指令串』
 

因为该文件的内容是有一定的规范的,因此直接使用 vi 去编辑是不好的。 此时,我们得要透过 visudo 去修改这个文件

visudo 与 /etc/sudoers

除了 root 之外的其他账号,若想要使用 sudo 执行属于 root 的权限指令,则 root 需要先使用 visudo 去修改 /etc/sudoers ,让该账号能够使用全部或部分的 root 指令功能。
是因为 /etc/sudoers 是有特定语法的,如果设定错误那会造成无法使用 sudo 指令的不良后果。因此才会使用 visudo 去修改, 并在结束离开修改画面时,系统会去检验 /etc/sudoers 的语法

visudo 的设定方式有几种简单的方法

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

假如我们要让 vbird1 这个账号可以使用 root 的任何指令,基本上有两种作法,第一种是直接透
过修改 /etc/sudoers ,方法如下

[root@study ~]# visudo
....(前面省略)....
root ALL=(ALL) ALL <==找到这一行,大约在 98 行左右
vbird1 ALL=(ALL) ALL <==这一行是你要新增的!
....(底下省略)....
使用者账号 登入者的来源主机名=(可切换的身份) 可下达的指令
root 				    ALL=(ALL)          ALL <==这是默认值

每一行的设置含义:

  1. 『使用者账号』:系统的哪个账号可以使用 sudo 这个指令的意思;
  2. 『登入者的来源主机名』:当这个账号由哪部主机联机到本 Linux 主机,意思是这个账号可能是由哪一部网络主机联机过来的, 这个设定值可以指定客户端计算机(信任的来源的意思)。默认值 root 可来自任何一部网络主机
  3. 『(可切换的身份)』:这个账号可以切换成什么身份来下达后续的指令,默认 root 可以切换成任何人;
  4. 『可下达的指令』:可用该身份下达什么指令?这个指令请务必使用绝对路径撰写。 预设 root 可以切换任何身份且进行任何指令之意。
II. 利用 wheel 群组以及免密码的功能处理 visudo
[root@study ~]# visudo <==同样的,请使用 root 先设定
....(前面省略)....
%wheel ALL=(ALL) ALL <==大约在 106 行左右,请将这行的 # 拿掉!
# 在最左边加上 % ,代表后面接的是一个『群组』之意!改完请储存后离开
[root@study ~]# usermod -a -G wheel pro1 <==将 pro1 加入 wheel 的支持

上面的设定值会造成『任何加入 wheel 这个群组的使用者,就能够使用 sudo 切换任何身份来操作任何指令』的意思。
你当然可以将 wheel 换成你自己想要的群组名。

不需要密码即可使用 sudo ,透过如下的方式:

[root@study ~]# visudo <==同样的,请使用 root 先设定
....(前面省略)....
%wheel ALL=(ALL) NOPASSWD: ALL <==大约在 109 行左右,请将 # 拿掉!
# 在最左边加上 % ,代表后面接的是一个『群组』之意!改完请储存后离开

重点是那个 NOPASSWD !该关键词是免除密码输入的意思。

III. 有限制的指令操作:

上面两点都会让使用者能够利用 root 的身份进行任何事情!这样总是不太好~如果我想要让用户仅能够进行部分系统任务,比方说,系统上面的 myuser1 仅能够帮 root 修改其他用户的密码

[root@study ~]# visudo <==注意是 root 身份
myuser1 ALL=(root) /usr/bin/passwd <==最后指令务必用绝对路径

要注意的是: 指令字段必须要填写绝对路径才行!否则 visudo 会出现语法错误的状况发生。
此外,上面的设定是有问题的

[myuser1@study ~]$ sudo passwd myuser3 <==注意,身份是 myuser1
[sudo] password for myuser1: <==输入 myuser1 的密码
Changing password for user myuser3. <==底下改的是 myuser3 的密码喔!这样是正确的
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
[myuser1@study ~]$ sudo passwd
Changing password for user root. <==见鬼!怎么会去改 root 的密码

我们必须要限制用户的指令参数!修改的方法为将上述的那行改一改先:

[root@study ~]# visudo <==注意是 root 身份
myuser1 ALL=(root) !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root

在设定值中加上惊叹号『 ! 』代表『不可执行』的意思。因此上面这一行会变成:可以执行『 passwd任意字符』,但是『 passwd 』与『 passwd root 』这两个指令例外

IV. 透过别名建置 visudo:

visudo 的别名可以是『指令别名、帐户别名、主机别名』等 ;用于简化 visudo 操作。

假设我的 pro1, pro2, pro3 与 myuser1, myuser2 要加入上述的密码管理员的 sudo 列表中, 那我可以创立一个帐户别名称为 ADMPW 的名称,然后将这个名称处理一下即可。处理的方式如下 :

[root@study ~]# 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

透过 User_Alias 建立出一个新账号,这个账号名称一定要使用大写字符来处理,包括Cmnd_Alias(命令别名)、Host_Alias(来源主机名别名) 都需要使用大写字符

V. sudo 的时间间隔问题:

如果我使用同一个账号在短时间内重复操作 sudo 来运作指令的话,在第二次执行 sudo 时,并不需要输入自己的密码;sudo 还是会正确的运作。
两次执行 sudo 的间隔在五分钟内,那么再次执行 sudo 时就不需要再次输入密码了, 这是因为系统相信你在五分钟内不会离开你的作业,所以执行 sudo 的是同一个人。不过如果两次 sudo 操作的间隔超过 5 分钟,那就得要重新输入一次你的密码。

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

很多时候我们需要大量执行很多 root 的工作,所以一直使用 sudo 觉得很麻烦;
可以使用 sudo 搭配 su , 一口气将身份转为 root ,而且还用用户自己的密码来变成 root 。

[root@study ~]# visudo
User_Alias ADMINS = pro1, pro2, pro3, myuser1
ADMINS ALL=(root) /bin/su -

上述的 pro1, pro2, pro3, myuser1 这四个人,只要输入『 sudo su - 』并且输入『自己的密码』后, 立刻变成 root 的身份!不但 root 密码不会外流,用户的管理也变的非常方便 。

用户的特殊 shell 与 PAM 模块

特殊的 shell, /sbin/nologin

passwd (管理系统账号的文件)文件结构中,有说到系统账号****,该账号的shell 就是使用/sbin/nologin** ,重点在于系统账号是不需要也不能登入的。
使用了这个 shell 的用户即使有了密码,你想要登入时他也无法登入,因为会出现如下的讯息:

This account is currently not available.

所谓的『 无法登入』指的仅是:『这个使用者无法使用 bash 或其他 shell 来登入系统』而已并不是说这个账号就无法使用其他的系统资源

PAM 模块简介

在过去,我们想要对一个使用者进行认证 (authentication),得要要求用户输入账号密码, 然后透过自行撰写的程序来判断该账号密码是否正确。也因为如此,我们常常得使用不同的机制来判断账号密码, 所以搞的一部主机上面拥有多个各别的认证系统,也造成账号密码可能不同步的验证问题。

 

为了解决这个问题因此有了 PAM (Pluggable Authentication Modules, 嵌入式验证模块) 的机制。

PAM 可以说是一套应用程序编程接口 (Application Programming Interface, API),他提供了一连串的验证机制只要使用者将验证阶段的需求告知 PAM 后, PAM 就能够回报使用者验证的结果 (成功或失败)

由于 PAM 仅是一套验证的机制,又可以提供给其他程序所呼叫引用,因此不论你使用什么程序,都可以使用 PAM 来进行验证,如此一来,就能够让账号密码或者是其他方式的验证具有一致的结果。

PAM 用来进行验证的数据称为模块 (Modules),每个 PAM 模块的功能都不太相同。

例如:使用 passwd 指令时,如果输入字典上面找的到的字符串, passwd 就会回报错误信息。

数字字典就是用来进行验证的数据,即为模块,该模块为:pam_cracklib.so 。

PAM 模块设定语法

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模块进行的验证工作。
/etc/pam.d/passwd 配置文件的内容如下:

[root@study ~]# cat /etc/pam.d/passwd
#%PAM-1.0 <==PAM 版本的说明而已!
auth 		include 	system-auth <==每一行都是一个验证的过程
account 	include 	system-auth
password 	substack 	system-auth
-password 	optional 	pam_gnome_keyring.so use_authtok
password 	substack 	postlogin
验证类别 	 控制标准 	  PAM 模块与该模块的参数

除了第一行宣告 PAM 版本之外,其他任何『 # 』开头的都是批注,而每一行都是一个独立的验证流程, 每一行可以区分为三个字段,分别是验证类别(type)控制标准(flag)PAM 的模块与该模块的参数
 
格当中出现的是『 include (包括) 』这个关键词,他代表的是『请呼叫后面的文件来作为这个类别的验证』, 所以,上述的每一行都要重复呼叫 /etc/pam.d/system-auth 那个文件来进行验证的意思。

第一个字段:验证类别 (Type)

验证类别主要分为四种

  • auth
    authentication (认证) 的缩写,所以这种类别主要用来检验使用者的身份验证这种类别通常是需要密码来检验的, 所以后续接的模块是用来检验用户的身份。

  • account
    account (账号) 则大部分是在进行 authorization (授权),这种类别则主要在检验使用者是否具有正确的权限,举例来说,当你使用一个过期的密码来登入时,当然就无法正确的登入了。

  • session
    session 是会议期间的意思,所以 session 管理的就是使用者在这次登入 (或使用这个指令) 期间,PAM 所给予的环境设定。****这个类别通常用在记录用户登入与注销时的信息
    例如,如果你常常使用 su 或者是 sudo指令的话, 那么应该可以在 /var/log/secure 里面发现很多关于 pam 的说明,而且记载的数据是『sessionopen, 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 ,而 PAM 验证又分很多类型与控制,不同的控制旗标所回报的讯息并不相同。
如上图所示, requisite 失败就回报了并不会继续,而 sufficient 则是成功就回报了也不会继续。
至于验证结束后所回报的信息通常是『succes 或 failure 』而已,后续的流程还需要该程序的判断来继续执行才行。

常用模块简介

以登陆 (login) 系统为例,登入所需要的 PAM 流程如下:

[root@study ~]# cat /etc/pam.d/login
#%PAM-1.0
auth [user_unknown=ignore success=ok ignore=ignore default=bad] pam_securetty.so
auth substack system-auth
auth include postlogin
account required pam_nologin.so
account include system-auth
password include system-auth
# pam_selinux.so close should be the first session rule
session required pam_selinux.so close
session required pam_loginuid.so
session optional pam_console.so
# pam_selinux.so open should only be followed by sessions to be executed in the user context
session required pam_selinux.so open
session required pam_namespace.so
session optional pam_keyinit.so force revoke
session include system-auth
session include postlogin
-session optional pam_ck_connector.so
# 我们可以看到,其实 login 也呼叫多次的 system-auth ,所以底下列出该配置文件

[root@study ~]# cat /etc/pam.d/system-auth
#%PAM-1.0
# This file is auto-generated.
# User changes will be destroyed the next time authconfig is run.
auth required pam_env.so
auth sufficient pam_fprintd.so
auth sufficient pam_unix.so nullok try_first_pass
auth requisite pam_succeed_if.so uid >= 1000 quiet_success
auth required pam_deny.so
account required pam_unix.so
account sufficient pam_localuser.so
account sufficient pam_succeed_if.so uid < 1000 quiet
account required pam_permit.so
password requisite pam_pwquality.so try_first_pass local_users_only retry=3 authtok_type=
password sufficient pam_unix.so sha512 shadow nullok try_first_pass use_authtok
password required pam_deny.so
session optional pam_keyinit.so revoke
session required pam_limits.so
-session optional pam_systemd.so
session [success=1 default=ignore] pam_succeed_if.so service in crond quiet use_uid
session required pam_unix.so


上面表格当中使用到非常多的 PAM 模块,每个模块的功能都不太相同,详细的模块情报可以
在你的系统中找到:

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

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 是否大于 1000 ,若小于 1000 则回报失败,否则再往下 (e)以 pam_deny.so 拒绝联机。
  2. 授权阶段 (account):(a)先以 pam_nologin.so 判断 /etc/nologin 是否存在,若存在则不许一般使用者登入;(b)接下来以 pam_unix.so 及 pam_localuser.so 进行账号管理,再以 (c) pam_succeed_if.so 判断 UID 是否小于 1000 ,若小于 1000 则不记录登录信息。(d)最后以 pam_permit.so 允许该账号登入。
  3. 密码阶段 (password):(a)先以 pam_pwquality.so 设定密码仅能尝试错误 3 次;(b)接下来以 pam_unix.so 透过 sha512, 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 验证。

Linux 主机上的用户讯息传递

查询使用者: w, who, last, lastlog

已登入在系统上面的用户 ,已登入在系统上面的用户 。

[root@study ~]# w
01:49:18 up 25 days, 3:34, 3 users, load average: 0.00, 0.01, 0.05
USER 	TTY 	FROM 			LOGIN@ 	IDLE   JCPU 	PCPU WHAT
dmtsai 	tty2 	07Jul15 		 12days  0.03s  0.03s 	 -bash
dmtsai 	pts/0 	172.16.200.254 	  00:18   6.00s  0.31s    0.11s sshd: dmtsai [priv]
# 第一行显示目前的时间、开机 (up) 多久,几个用户在系统上平均负载等;
# 第二行只是各个项目的说明,
# 第三行以后,每行代表一个使用者。如上所示,dmtsai 登入并取得终端机名 tty2 之意。

[root@study ~]# who
dmtsai tty2 2015-07-07 23:07
dmtsai pts/0 2015-07-22 00:18 (192.168.1.100)


如果您想要知道每个账号的最近登入的时间,则可以使用 lastlog 这个指令 ;
lastlog 会去读取 /var/log/lastlog 文件,结果将数据输出如下表:

[root@study ~]# lastlog
Username 	Port  From 			Latest
root 	    pts/0 	   			Wed Jul 22 00:26:08 +0800 2015
bin **Never logged in**
....(中间省略)....
dmtsai 		pts/1 192.168.1.100  Wed Jul 22 01:08:07 +0800 2015
vbird1 		pts/0			    Wed Jul 22 01:32:17 +0800 2015
pro3 						   **Never logged in**
....(以下省略)

使用者间通讯: write, mesg, wall

使用 wall, write 要等到使用者在在线才能够进行通讯。

write

write 可以直接将讯息传给接收者

[root@study ~]# write 使用者账号 [用户所在终端接口]
[root@study ~]# who
vbird1 tty3 2015-07-22 01:55 <==有看到 vbird1 在在线
root   tty4 2015-07-22 01:56
[root@study ~]# write vbird1 pts/2
Hello, there:
Please don't do anything wrong... <==这两行是 root 写的信息!
# 结束时,请按下 [crtl]-d 来结束输入。此时在 vbird1 的画面中,会出现:

Message from root@study.centos.vbird on tty4 at 01:57 ...
Hello, there:
Please don't do anything wrong...
EOF

mesg

讯息会立即发送给 vbird1(接收者);这些讯息会立刻打断vbird1(接收者) 原本的工作!所以,如果 vbird1 这个人不想要接受任何讯息,直接下达这个动作:

[vbird1@study ~]$ mesg n   <=== 禁止接收讯息
[vbird1@study ~]$ mesg
is n

这个 mesg 的功能对 root 传送来的讯息没有抵挡的能力!所以如果是 root 传送讯息, vbird1还是得要收下。

但是如果 root 的 mesg 是 n 的,那么 vbird1 写给 root 的信息会变这样:

[vbird1@study ~]$ write root
write: root has messages disabled

如果想要解开的话,再次下达『 mesg y 』即可!
想要知道目前的 mesg 状态,直接下达『 mesg 』即可

wall

相对于 write 是仅针对一个使用者来传『讯息』;
我们还可以『对所有系统上面的用户传送讯息(广播)』,用 wall 即可

[root@study ~]# wall "I will shutdown my linux server..."

使用者邮件信箱: mail

通过 mail 指令可以在让用户离线通讯。
 

一般来说, mailbox 都会放置在 /var/spool/mail 里面,一个账号一个 mailbox (文件)。 举例来说,我的 vbird1 就具有 /var/spool/mail/vbird1 这个 mailbox 。
 

指令的用法很简单的,直接这样下达:『mail -s "邮件标题" username@localhost 』即可!
一般来说,如果是寄给本机上的使用者,基本上,连『 @localhost 』都不用写

[root@study ~]# mail -s "nice to meet you" vbird1
Hello, D.M. Tsai
Nice to meet you in the network.
You are so nice. byebye!
. <==这里很重要喔,结束时,最后一行输入小数点 . 即可!
EOT
[root@study ~]# <==出现提示字符,表示输入完毕了!

收信指令同样是 mail ;

[vbird1@study ~]$ mail
Heirloom Mail version 12.5 7/5/10. Type ? for help.
"/var/spool/mail/vbird1": 1 message 1 new
>N 1 root Wed Jul 22 02:09 20/671 "nice to meet you"
& <==这里可以输入很多的指令,如果要查阅,输入 ? 即可!

在 mail 当中的提示字符是 & 符号
信件的前面那个 > 代表目前处理的信件,而在大于符号的右边那个 N 代表该封信件尚未读过如果我想要知道这个 mail 内部的指令有哪些,可以在 & 之后输入『 ? 』,就可以看到如下的画面:

& ?
mail commands
type <message list> 	    type messages
next 					   goto and type next message
from <message list> 		give head lines of messages
headers 				   print out active message headers
delete <message list> 		delete messages
undelete <message list> 	undelete messages
save <message list> folder 	append messages to folder and mark as saved
copy <message list> folder 	append messages to folder without marking them
write <message list> file 	append message texts to file, save attachments
preserve <message list> 	keep incoming messages in mailbox even if saved
Reply <message list> 		reply to message senders
reply <message list> 		reply to message senders and all recipients
mail addresses 			    mail to specific recipients
file folder 			    change to another folder
quit 					   quit and apply changes to folder
xit 					   quit and discard changes made to folder
! 						   shell escape
cd <directory> 				chdir to directory or home if none given
list 					   list names of all available commands

指的是每封邮件的左边那个数字!而几个比较常见的指令是:

指令 意义
h 列出信件标头;如果要查阅 40 封信件左右的信件标头,可以输入『 h 40 』
d 删除后续接的信件号码,删除单封是『 d10 』,删除 20~40 封则为『 d20-40 』。 不过,这个动作要生效 的话,必须要配合 q 这个指令才行(参考底下说明)!
s 将信件储存成文件。例如我要将第 5 封信件的内容存成 ~/mail.file:『s 5 ~/mail.file』
x 或者输入 exit 都可以。这个是『不作任何动作离开 mail 程序』的意思。 不论你刚刚删除了什么信件, 或者读过什么,使用 exit 都会直接离开 mail,所以刚刚进行的删除与阅读工作都会无效。 如果您只是查 阅一下邮件而已的话,一般来说,建议使用这个离开啦!除非你真的要删除某些信件。
q 相对于 exit 是不动作离开, q 则会实际进行你刚刚所执行的任何动作 (尤其是删除!)

一些账号相关的检查工具

pwck 以及 pwconv /pwuconv 等指令,检查看看用户的家目录、密码等数据有没有问题。

pwck

pwck 这个指令在检查 /etc/passwd 这个账号配置文件内的信息,与实际的家目录是否存在等信息,还可以比对 /etc/passwd /etc/shadow 的信息是否一致,另外,如果 /etc/passwd 内的数据字段错误时,会提示使用者修订。

[root@study ~]# pwck
user 'ftp': directory '/var/ftp' does not exist
user 'avahi-autoipd': directory '/var/lib/avahi-autoipd' does not exist
user 'pulse': directory '/var/run/pulse' does not exist
pwck: no changes

因为 /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 文件。』

chpasswd

chpasswd 是个挺有趣的指令,他可以『读入未加密前的密码,并且经过加密后, 将加密后的密码写入 /etc/shadow 当中。』这个指令很常被使用在大量建置账号的情况中 。