sudo

  使用 su 切换身份真的是很简单啦~不过, su 却有一个很严重的问题, 那就是.....我们必须要知道想要变成的那个人的登入密码~ 举例来说,如果我想要变成 root ,那么就必须要知道 root 的密码才行, 如果我想要变成 dmtsai 来工作,那么除非我是 root ,否则就必须要知道 dmtsai 这个使用者的密码才行~而众所皆知的,如果多人管理一部主机的话, 大家都知道 root 的密码,那......挺危险的,不是吗?!

  这个时候, sudo 就派的上用场啰~那么 sudo 是怎样工作的呢?

  * 当使用者执行 sudo 时,系统会主动的去寻找 /etc/sudoers 档案,判断该使用者是否有执行 sudo 的权限;
* 若使用者具有可执行 sudo 的权限后,便让使用者‘输入使用者自己的密码’来确认;
* 若密码输入成功,便开始进行 sudo 后续接的指令;
* 不过, root 执行 sudo 时,不需要输入密码;
* 若欲切换的身份与执行者身份相同,那也不需要输入密码。

  要注意的是,使用者‘输入的是自己的密码,而不是欲切换成为他的那个身份的密码!’ 举例来说,假设 dmtsai 具有执行 sudo 的权限,那么当他以 sudo 执行 root 的工作时, 他需要输入的是 dmtsai 自己的密码,而不是 root 的密码!嘿嘿!很棒吧! ^_^ 如此一来,大家可以使用自己的密码执行 root 的工作,而不必知道 root 的密码,安全多了。 此外,使用者能够执行的指令是可以被限制的! 所以,我们可以设定 dmtsai 仅能进行 shutdown 的工作,或者是其他一些简单的指令, 嘿嘿!是否很棒啊!

  不过,由上面的说明当中,您也会瞭解,是否具有 sudo 的执行权限是很重要的, 而 sudo 的执行权限与 /etc/sudoers 这的档案有关。在预设的情况下,只有 root 才能够使用 sudo 呢!至于编辑 /etc/sudoers 则需要 visudo 这个指令。好了, 底下我们就来看一看 sudo 的语法先。

  [root@linux ~]# sudo [-u [username|#uid]] command
参数:
-u :后面可以接使用者帐号名称,或者是 UID。例如 UID 是 500 的身份,可以:
-u #500 来作为切换到 UID 为 500 的那位使用者。
范例:

  范例一:一般身份使用者使用 sudo 在 /root 底下建立目录:
[dmtsai@linux ~]$ sudo mkdir /root/testing
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: <==这里输入 dmtsai 自己的密码
dmtsai is not in the sudoers file. This incident will be reported.
# 瞧!因为 dmtsai 不在 /etc/sudoers ,所以他就无法执行 sudo 喔!

  范例二:假设 dmtsai 已经具有 sudo 的执行权限,如何在 /root 底下建立目录?
[dmtsai@linux ~]$ sudo mkdir /root/testing
Password: <==这里输入 dmtsai 自己的密码

  范例三:如何将 sudo 与 su 搭配使用?
[dmtsai@linux ~]$ sudo su -

  范例四:dmtsai 想要切换身份成为 vbird 来进行 touch 时?
[dmtsai@linux ~]$ sudo -u vbird touch /home/vbird/test

  上面我进行了四个范例,不过,要注意的是,若我是以 dmtsai 来进行的, 那么在接下来的五分钟内,如果你持续使用 sudo 来工作时,那就不需要再次的输入密码。 这是因为系统相信你在五分钟内不会离开而有第二个人跑来操作系统啊! 呼呼!真是很人性化的设计啊~ ^_^。不过如果两次 sudo 操作的间隔超过 5 分钟,那就得要重新输入一次你的密码了。 而且要注意的是,因为使用一般帐号时,理论上不会使用到 /sbin, /usr/sbin 等目录内的指令, 所以 $PATH 变数不会含有这些目录,因此很多管理指令需要使用绝对路径来下达比较妥当喔! 或者直接修改您自己的 PATH 变数吧!

  上面这四个范例我都是以 dmtsai 这个使用者来进行的,但是,在预设的情况中, 您的使用者应该是不能使用 sudo 的~这是因为我们上面提到的啊,还没有去设定 /etc/sudoers 嘛! 所以啰,如果您要测试上面的范例之前,是需要将 /etc/sudoers 动动手脚的。 不过,因为 /etc/sudoers 需要一些比较特别的语法,因此,如果你直接以 vi 去编辑他时, 如果输入的字句错误,可能会造成无法启用 sudo 的困扰,因此,建议您一定要使用 visudo 去编辑 /etc/sudoers 喔!(注: visudo 必须要使用 root 的身份来执行!)

  [root@linux ~]# visudo
# sudoers file.
# This file MUST be edited with the 'visudo' command as root.
# See the sudoers man page for the details on how to write a sudoers file.
#
# Host alias specification
# User alias specification
# Cmnd alias specification
# Defaults specification
# Runas alias specification
# User privilege specification
root    ALL=(ALL) ALL
dmtsai ALL=(ALL) ALL   <==这里将 dmtsai 制作成完全可用!

  # Uncomment to allow people in group wheel to run all commands
# %wheel        ALL=(ALL)       ALL
# Same thing without a password
# %wheel        ALL=(ALL)       NOPASSWD: ALL
# Samples
# %users ALL=/sbin/mount /cdrom,/sbin/umount /cdrom
# %users localhost=/sbin/shutdown -h now

  使用 visudo 之后,其实就会出现一个 vi 的画面啦!他就是以 vi 来开启 /etc/sudoers , 不过,当我们储存离开时, visudo 会额外去检查 /etc/sudoers 内部的语法, 以避免使用者输入错误的资讯了。我上面只有加入一行,就是让那个 dmtsai 成为可以随意使用 sudo 的身份而已。基本上, /etc/sudoers 的结构您可以使用 man sudoers 去查阅, 该说明内容说的很清楚,而且还有一些范例呢!鸟哥在这里仅作一些简单的说明就是了。 那一行‘ dmtsai ALL=(ALL) ALL ’代表的意义是:

  使用者帐号 登入的主机 = (可以变换的身份) 可以下达的指令

  因此,我上面这一行的意义是:‘ dmtsai 这个使用者,不论来自何方, 他可以变换成任何 Linux 本机上面有的所有帐号,并执行所有的指令’的意思啦! 假如您的系统里面,有个 Web 的软体是以 www 这个使用者来进行编辑的, 您想要让 vbird2 这个使用者可以用 www 这个帐号进行编辑,那么就应该写成:

  vbird2 ALL = (www) ALL

  如果错写成:

  vbird2 ALL = ALL

  亦即没有加上身份宣告的话,那么‘预设是仅能进行 root 的身份切换’而已喔! ^_^ 这可是很重要的一个观念呢!另外,如果想要以使用者的群组来进行规范的话,那么在 ‘使用者帐号’的栏位,前面加上‘ % ’时,就代表是群组 (group) 的身份了。 举例来说,我想要让系统里面所有属于 wheel 这个群组的使用者都能够进行 sudo 时,可以这样写:

  %wheel ALL = (ALL) ALL

  而如果你还想要让这个群组内的使用者在使用 sudo 时,不需要输入密码, 那么可以在‘可以下达的指令’那个栏位内多加入一个参数,名为‘NOPASSWD:’即可,亦即:

  %wheel ALL = (ALL) NOPASSWD: ALL

  另外,除了单一个人或单一群组之外,我们还可以额外指定一些‘帐号别名、主机别名、指令别名’ 等等的资料来相互套用喔!真是好棒啊!不过,关于别名的使用上,‘必须要使用大写字元’才行喔! 好了,我们来做一些练习,让您可以很清楚的知道如何进行 visudo 的设定吧!

  例题:我想要建立一个可以帮忙系统管理员变更使用者密码的群组,名称为 ADMPW ( 注意,在 sudoers 内,这个别名的名称一定要是大写字元才行!)但是这个群组不能修改 root 的密码喔!且他们执行 sudo 时,不需要密码验证。
答:

  我以 root 的身份使用 visudo ,进入编辑画面后,去设定成底下的模样:

  User_Alias ADMPW = vbird, dmtsai, vbird1, vbird3
ADMPW ALL = NOPASSWD: !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, \
!/usr/bin/passwd root

  上面的意思是说,我的系统上面有四个帐号,分别是 vbird, vbird1, vbird3 与 dmtsai 这四个帐号加入 sudo 内的 ADMPW 群组中,这四个帐号可以使用 sudo 进行‘ /usr/bin/passwd * ’密码的更改动作,但是不能 (在指令前面加入 ! 代表不可) 使用 /usr/bin/passwd 或 /usr/bin/passwd root ,如此一来,就让该 ADMPW 可以更改使用者的密码,但是不能变更 root 的密码啰! ^_^


在 /etc/sudoers 里头加入别名有很多的好处,举例来说,以上面的例子来讲, 假设未来我有其他的使用者要加入该密码管理的群组时,直接将帐号加入 ADMPW 那个群组中就好了,很简单的使用吧! ^_^。再看看下一题:

  例题:我的系统中有 DNS 服务,他的启动指令在 /etc/init.d/named ,如果我想要建立一个 DNSMASTER 的群组来管理他时?如何是好?
答:

  我以 root 的身份使用 visudo ,进入编辑画面后,去设定成底下的模样:

  User_Alias DNSMASTER = vbird, dmtsai
Cmnd_Alias DNSCMD = /etc/init.d/named, /usr/bin/vim /var/named/*
DNSMASTER ALL = DNSCMD

  看的懂吗?嘿嘿!因为 DNS 的设定档大多在 /var/named 里面,所以,我也允许相关帐号用 vi 去处理 DNS 的设定档啦!很简单对吧! ^_^


好了,我们知道 sudo 可以搭配 su 来进行一堆系统的工作对吧! 因为 sudo 仅能进行一次指令,很麻烦,如果我能够将 sudo 与 su 搭配在一起,不就很棒了吗? 这个时候,我可以利用上面已经建立好的 ADMPW 群组来新增这一行:

  ADMPW ALL = /bin/su

  如此一来,在 ADMPW 内的使用者,就可以利用‘ sudo su - ’来切换身份成为 root 啰~ 真是棒得不得了啊! ^_^