CentOS学习笔记--账号管理与权限配置

时间:2023-03-08 21:53:27

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 对应的账号与组名再显示出来!

你登录系统,系统帮你处理了什么呢?

  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@localhost ~]# cat /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
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
uucp:x:10:14:uucp:/var/spool/uucp:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
gopher:x:13:30:gopher:/var/gopher:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
vcsa:x:69:69:virtual console memory owner:/dev:/sbin/nologin
rpc:x:32:32:Rpcbind Daemon:/var/cache/rpcbind:/sbin/nologin
rpcuser:x:29:29:RPC Service User:/var/lib/nfs:/sbin/nologin
nfsnobody:x:65534:65534:Anonymous NFS User:/var/lib/nfs:/sbin/nologin
sshd:x:74:74:Privilege-separated SSH:/var/empty/sshd:/sbin/nologin
ntp:x:38:38::/etc/ntp:/sbin/nologin

每一行使用『:』分隔开,共有七个咚咚,分别是:

  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 号码喔!
  4. GID:

    这个与 /etc/group 有关!其实 /etc/group 的观念与 /etc/passwd 差不多,只是他是用来规范组名与 GID 的对应而已!
  5. 用户信息说明栏:

    这个字段基本上并没有什么重要用途,只是用来解释这个账号的意义而已!不过,如果您提供使用 finger 的功能时, 这个字段可以提供很多的信息呢!
  6. 家目录:

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

    当用户登陆系统后就会取得一个 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 里头呢!在这里,我们先来了解一下这个文件的构造吧!

[root@localhost ~]# cat /etc/shadow
root:$6$9MO6Rei52Ks4sUwV$U7nP7q/SZkeVgYo0mFmtm4SD6SEVRe6PVSd.xYIIOyxmIAnACQQHPeXYxdo/VA4gEUgz9erdECMQPj1KSFrXV0:16377:0:99999:7:::
bin:*:15513:0:99999:7:::
daemon:*:15513:0:99999:7:::
adm:*:15513:0:99999:7:::
lp:*:15513:0:99999:7:::
sync:*:15513:0:99999:7:::
shutdown:*:15513:0:99999:7:::
halt:*:15513:0:99999:7:::
mail:*:15513:0:99999:7:::
uucp:*:15513:0:99999:7:::
operator:*:15513:0:99999:7:::
games:*:15513:0:99999:7:::
gopher:*:15513:0:99999:7:::
ftp:*:15513:0:99999:7:::
nobody:*:15513:0:99999:7:::
vcsa:!!:16377::::::
rpc:!!:16377:0:99999:7:::
rpcuser:!!:16377::::::
nfsnobody:!!:16377::::::
sshd:!!:16377::::::
ntp:!!:16381::::::

基本上, shadow 同样以『:』作为分隔符,如果数一数,会发现共有九个字段啊,这九个字段的用途是这样的:

  1. 账号名称:

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

    这个字段内的数据才是真正的口令,而且是经过编码的口令 (加密) 啦! 你只会看到有一些特殊符号的字母就是了!需要特别留意的是,虽然这些加密过的口令很难被解出来, 但是『很难』不等于『不会』,所以,这个文件的默认权限是『-rw-------』或者是『-r--------』,亦即只有 root 才可以读写就是了!你得随时注意,不要不小心更动了这个文件的权限呢!

    另外,由于各种口令编码的技术不一样,因此不同的编码系统会造成这个字段的长度不相同。 举例来说,旧式的 DES 编码系统产生的口令长度就与目前惯用的 MD5 不同!MD5 的口令长度明显的比较长些。由于固定的编码系统产生的口令长度必须一致,因此『当你让这个字段的长度改变后,该口令就会失效(算不出来)』。 很多软件透过这个功能,在此字段前加上 ! 或 * 改变口令字段长度,就会让口令『暂时失效』了。

  3. 最近更动口令的日期:

    这个字段记录了『更动口令那一天』的日期,不过,很奇怪呀!在我的例子中怎么会是 14126 呢?呵呵,这个是因为计算 Linux 日期的时间是以 1970 年 1 月 1 日作为 1 而累加的日期,1971 年 1 月 1 日则为 366 啦! 得注意一下这个数据呦!上述的 14126 指的就是 2008-09-04 那一天啦!了解乎? 而想要了解该日期可以使用本章后面 chage 命令的帮忙!
  4. 口令不可被更动的天数:(与第 3 字段相比)

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

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

    当账号的口令有效期限快要到的时候 (第 5 字段),系统会依据这个字段的配置,发出『警告』言论给这个账号,提醒他『再过 n 天你的口令就要过期了,请尽快重新配置你的口令呦!』,如上面的例子,则是口令到期之前的 7 天之内,系统会警告该用户。
  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/passwd 与 /etc/shadow 之后,你或许还是会觉得奇怪, 那么群组的配置文件在哪里?还有,在 /etc/passwd 的第四栏不是所谓的 GID 吗?那又是啥? 呵呵~此时就需要了解 /etc/group 与 /etc/gshadow 啰~

  • /etc/group 文件结构

这个文件就是在记录 GID 与组名的对应了~鸟哥测试机的 /etc/group 内容有点像这样:

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

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

  1. 组名:

    就是组名啦!
  2. 群组口令:

    通常不需要配置,这个配置通常是给『群组管理员』使用的,目前很少有这个机会配置群组管理员啦! 同样的,口令已经移动到 /etc/gshadow 去,因此这个字段只会存在一个『x』而已;
  3. GID:

    就是群组的 ID 啊。我们 /etc/passwd 第四个字段使用的 GID 对应的群组名,就是由这里对应出来的!
  4. 此群组支持的账号名称:

    我们知道一个账号可以加入多个群组,那某个账号想要加入此群组时,将该账号填入这个字段即可。 举例来说,如果我想要让 dmtsai 也加入 root 这个群组,那么在第一行的最后面加上『,dmtsai』,注意不要有空格, 使成为『 root:x:0:root,dmtsai 』就可以啰~

账号管理

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

  • useradd
    [root@www ~]# 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@www ~]# useradd vbird1
    [root@www ~]# ll -d /home/vbird1
    drwx------ 4 vbird1 vbird1 4096 Feb 25 09:38 /home/vbird1
    # 默认会创建用户家目录,且权限为 700 !这是重点!
  • passwd
    [root@www ~]# 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@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. <==竟然还是成功修改了!

    root 果然是最伟大的人物!当我们要给予用户口令时,透过 root 来配置即可。 root 可以配置各式各样的口令,系统几乎一定会接受!所以您瞧瞧,如同上面的范例一,明明鸟哥输入的口令太短了, 但是系统依旧可接受 vbird2 这样的口令配置。这个是 root 帮忙配置的结果,那如果是用户自己要改口令呢? 包括 root 也是这样修改的喔!

    范例二:用 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. <==有无成功看关键词
  • usermod

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

[root@www ~]# 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 口令栏的 ! 拿掉,解冻啦!

如果你仔细的比对,会发现 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..

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

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

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

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

新增与移除群组

  • groupadd
    [root@www ~]# groupadd [-g gid] [-r] 组名
    选项与参数:
    -g :后面接某个特定的 GID ,用来直接给予某个 GID ~
    -r :创建系统群组啦!与 /etc/login.defs 内的 GID_MIN 有关。 范例一:新建一个群组,名称为 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 来决定!
  • groupdel
    [root@www ~]# groupdel [groupname]
    
    范例一:将刚刚的 mygroup 删除!
    [root@www ~]# groupdel mygroup 范例二:若要删除 vbird1 这个群组的话?
    [root@www ~]# groupdel vbird1
    groupdel: cannot remove user's primary group.
  • gpasswd:群组管理员功能
    # 关于系统管理员(root)做的动作:
    [root@www ~]# gpasswd groupname
    [root@www ~]# gpasswd [-A user1,...] [-M user3,...] groupname
    [root@www ~]# gpasswd [-rR] groupname
    选项与参数:
    :若没有任何参数时,表示给予 groupname 一个口令(/etc/gshadow)
    -A :将 groupname 的主控权交由后面的使用者管理(该群组的管理员)
    -M :将某些账号加入这个群组当中!
    -r :将 groupname 的口令移除
    -R :让 groupname 的口令栏失效 # 关于群组管理员(Group administrator)做的动作:
    [someone@www ~]$ gpasswd [-ad] user groupname
    选项与参数:
    -a :将某位使用者加入到 groupname 这个群组当中!
    -d :将某位使用者移除出 groupname 这个群组当中。 范例一:创建一个新群组,名称为 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

使用者身份切换

在 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 口令不会流出去!

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

  • su

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

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

这个 su 的用法当中,有没有加上那个减号『 - 』差很多喔! 因为涉及 login-shell 与 non-login shell 的变量读取方法。这里让我们以一个小例子来说明吧!

范例一:假设你原本是 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 的环境!

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

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

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

  • sudo

minimal版没有sudo软件,yum install sudo安装一下,下面的visudo同样需要sudo软件。

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

[root@www ~]# sudo [-b] [-u 新使用者账号]
选项与参数:
-b :将后续的命令放到背景中让系统自行运行,而不与目前的 shell 产生影响
-u :后面可以接欲切换的使用者,若无此项则代表切换身份为 root 。 范例一:你想要以 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

一般来说,visudo 的配置方式有几种简单的方法喔,底下我们以几个简单的例子来分别说明:

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

假如我们要让 vbird1 这个账号可以使用 root 的任何命令,那么可以简单的这样进行修改即可:

[root@www ~]# visudo
....(前面省略)....
root ALL=(ALL) ALL <==找到这一行,大约在 76 行左右
vbird1 ALL=(ALL) ALL <==这一行是你要新增的!
....(前面省略)....

有趣吧!其实 visudo 只是利用 vi 将 /etc/sudoers 文件呼叫出来进行修改而已,所以这个文件就是 /etc/sudoers 啦!其实 visudo 只是利用 vi 将 /etc/sudoers 文件呼叫出来进行修改而已,所以这个文件就是 /etc/sudoers 啦! 这个文件的配置其实很简单,如上面所示,如果你找到 76 行 (有 root 配置的那行) 左右,看到的数据就是:

使用者账号  登陆者的来源主机名=(可切换的身份)  可下达的命令
root ALL=(ALL) ALL <==这是默认值

上面这一行的四个组件意义是:

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

[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 !
  • 利用群组以及免口令的功能处理 visudo

我们在本章前面曾经创建过 pro1, pro2, pro3 ,这三个用户能否透过群组的功能让这三个人可以管理系统? 可以的,而且很简单!同样我们使用实际案例来说明:

[root@www ~]# visudo  <==同样的,请使用 root 先配置
....(前面省略)....
%wheel ALL=(ALL) ALL <==大约在 84 行左右,请将这行的 # 拿掉!
# 在最左边加上 % ,代表后面接的是一个『群组』之意!改完请储存后离开 [root@www ~]# usermod -a -G wheel pro1 <==将 pro1 加入 wheel 的支持

上面的配置值会造成『任何加入 wheel 这个群组的使用者,就能够使用 sudo 切换任何身份来操作任何命令』的意思。 你当然可以将 wheel 换成你自己想要的群组名。接下来,请分别切换身份成为 pro1 及 pro2 试看看 sudo 的运行。

  • 有限制的命令操作:

上面两点都会让使用者能够利用 root 的身份进行任何事情!这样总是不太好~如果我想要让用户仅能够进行部分系统任务, 比方说,系统上面的 myuser1 仅能够帮 root 修改其他用户的口令时,亦即『当使用者仅能使用 passwd 这个命令帮忙 root 修改其他用户的口令』时,你该如何撰写呢?可以这样做:

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

上面的配置值指的是『myuser1 可以切换成为 root 使用 passwd 这个命令』的意思。其中要注意的是: 命令字段必须要填写绝对路径才行!否则 visudo 会出现语法错误的状况发生! 此外,上面的配置是有问题的!我们使用底下的命令操作来让您了解:

[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 的口令?

恐怖啊!我们竟然让 root 的口令被 myuser3 给改变了!下次 root 回来竟无法登陆系统...欲哭无泪~怎办? 所以我们必须要限制用户的命令参数!修改的方法为将上述的那行改一改先:

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

由于屏幕一行写不完,我将这行写成两行,所以上面第一行最后加上反斜杠啰。加上惊叹号『 ! 』代表『不可运行』的意思。 因此上面这一行会变成:可以运行『 passwd 任意字符』,但是『 passwd 』与『 passwd root 』这两个命令例外! 如此一来 myuser1 就无法改变 root 的口令了!这样这位使用者可以具有 root 的能力帮助你修改其他用户的口令, 而且也不能随意改变 root 的口令!很有用处的!

sudo 搭配 su 的使用方式:

很多时候我们需要大量运行很多 root 的工作,所以一直使用 sudo 觉得很烦ㄟ!那有没有办法使用 sudo 搭配 su , 一口气将身份转为 root ,而且还用用户自己的口令来变成 root 呢?是有的!而且方法简单的会让你想笑! 我们创建一个 ADMINS 帐户别名,然后这样做:

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

接下来,上述的 pro1, pro2, pro3, myuser1 这四个人,只要输入『 sudo su - 』并且输入『自己的口令』后, 立刻变成 root 的身份!不但 root 口令不会外流,用户的管理也变的非常方便! 这也是实务上面多人共管一部主机时常常使用的技巧呢!这样管理确实方便,不过还是要强调一下大前提, 那就是『这些你加入的使用者,全部都是你能够信任的用户』!