13.4 使用者身份切换
什么?在 Linux 系统当中还要作身份的变换?这是为啥?可能有下面几个原因啦!
- 使用一般帐号:系统平日操作的好习惯
事实上,为了安全的缘故,一些老人家都会建议你,尽量以一般身份使用者来操作 Linux 的日常作业!等到需要设置系统环境时, 才变换身份成为 root 来进行系统管理,相对比较安全啦!避免作错一些严重的指令,例如恐怖的“ rm -rf / ”(千万作不得!)
- 用较低权限启动系统服务
相对于系统安全,有的时候,我们必须要以某些系统帐号来进行程序的执行。 举例来说, Linux 主机上面的一套软件,名称为 apache ,我们可以额外创建一个名为 apache 的使用者来启动 apache 软件啊,如此一来,如果这个程序被攻破,至少系统还不至于就损毁了~
- 软件本身的限制
在远古时代的 telnet 程序中,该程序默认是不许使用 root 的身份登陆的,telnet 会判断登陆者的 UID, 若 UID 为 0 的话,那就直接拒绝登陆了。所以,你只能使用一般使用者来登陆 Linux 服务器。 此外, ssh [3] 也可以设置拒绝 root 登陆喔!那如果你有系统设置需求该如何是好啊?就变换身份啊!
由于上述考虑,所以我们都是使用一般帐号登陆系统的,等有需要进行系统维护或软件更新时才转为 root 的身份来动作。 那如何让一般使用者转变身份成为 root 呢?主要有两种方式喔:
以“ su - ”直接将身份变成 root 即可,但是这个指令却需要 root 的密码,也就是说,如果你要以 su 变成 root 的话,你的一般使用者就必须要有 root 的密码才行;
以“ sudo 指令 ”执行 root 的指令串,由于 sudo 需要事先设置妥当,且 sudo 需要输入使用者自己的密码, 因此多人共管同一部主机时, sudo 要比 su 来的好喔!至少 root 密码不会流出去!
下面我们就来说一说 su 跟 sudo 的用法啦!
13.4.1 su
su 是最简单的身份切换指令了,他可以进行任何身份的切换唷!方法如下:
[root@study ~]# su [-lm] [-c 指令] [username]
选项与参数:
- :单纯使用 - 如“ su - ”代表使用 login-shell 的变量文件读取方式来登陆系统;
若使用者名称没有加上去,则代表切换为 root 的身份。
-l :与 - 类似,但后面需要加欲切换的使用者帐号!也是 login-shell 的方式。
-m :-m 与 -p 是一样的,表示“使用目前的环境设置,而不读取新使用者的配置文件”
-c :仅进行一次指令,所以 -c 后面可以加上指令喔!
上表的解释当中有出现之前第十章谈过的 login-shell 配置文件读取方式,如果你忘记那是啥东西, 请先回去第十章瞧瞧再回来吧!这个 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 惯用的指令就只能使用绝对路径来执行咯。其他的还有 MAIL 这个变量,你输入 mail 时, 收到的邮件竟然还是 dmtsai 的,而不是 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 的环境!
上述的作法是让使用者的身份变成 root 并开始操作系统,如果想要离开 root 的身份则得要利用 exit 离开才行。 那我如果只是想要执行“一个只有 root 才能进行的指令,且执行完毕就恢复原本的身份”呢?那就可以加上 -c 这个选项啰! 请参考下面范例三!
范例三:dmtsai 想要执行“ head -n 3 /etc/shadow ”一次,且已知 root 密码
[dmtsai@study ~]$ head -n 3 /etc/shadow
head: cannot open `/etc/shadow' for reading: Permission denied
[dmtsai@study ~]$ su - -c "head -n 3 /etc/shadow"
Password: <==这里输入 root 的密码喔!
root:$6$wtbCCce/PxMeE5wm$KE2IfSJr.YLP7Rcai6oa/T7KFhOYO62vDnqfLw85...:16559:0:99999:7:::
bin:*:16372:0:99999:7:::
daemon:*:16372:0:99999:7:::
[dmtsai@study ~]$ <==注意看,身份还是 dmtsai 喔!继续使用旧的身份进行系统操作!
由于 /etc/shadow 权限的关系,该文件仅有 root 可以查阅。为了查阅该文件,所以我们必须要使用 root 的身份工作。 但我只想要进行一次该指令而已,此时就使用类似上面的语法吧!好,那接下来,如果我是 root 或者是其他人, 想要变更成为某些特殊帐号,可以使用如下的方法来切换喔!
范例四:原本是 dmtsai 这个使用者,想要变换身份成为 vbird1 时?
[dmtsai@study ~]$ su -l vbird1
Password: <==这里输入 vbird1 的密码喔!
[vbird1@study ~]$ su -
Password: <==这里输入 root 的密码喔!
[root@study ~]# id sshd
uid=74(sshd) gid=74(sshd) groups=74(sshd) ... <==确实有存在此人
[root@study ~]# su -l sshd
This account is currently not available. <==竟然说此人无法切换?
[root@study ~]# finger sshd
Login: sshd Name: Privilege-separated SSH
Directory: /var/empty/sshd Shell: /sbin/nologin
[root@study ~]# exit <==离开第二次的 su
[vbird1@study ~]$ exit <==离开第一次的 su
[dmtsai@study ~]$ exit <==这才是最初的环境!
su 就这样简单的介绍完毕,总结一下他的用法是这样的:
若要完整的切换到新使用者的环境,必须要使用“ su - username ”或“ su -l username ”, 才会连同 PATH/USER/MAIL 等变量都转成新使用者的环境;
如果仅想要执行一次 root 的指令,可以利用“ su - -c "指令串" ”的方式来处理;
使用 root 切换成为任何使用者时,并不需要输入新使用者的密码;
虽然使用 su 很方便啦,不过缺点是,当我的主机是多人共管的环境时,如果大家都要使用 su 来切换成为 root 的身份,那么不就每个人都得要知道 root 的密码,这样密码太多人知道可能会流出去, 很不妥当呢!怎办?通过 sudo 来处理即可!
13.4.2 sudo
相对于 su 需要了解新切换的使用者密码 (常常是需要 root 的密码), sudo 的执行则仅需要自己的密码即可! 甚至可以设置不需要密码即可执行 sudo 呢!由于 sudo 可以让你以其他用户的身份执行指令 (通常是使用 root 的身份来执行指令),因此并非所有人都能够执行 sudo , 而是仅有规范到 /etc/sudoers 内的用户才能够执行 sudo 这个指令喔!说的这么神奇,下面就来瞧瞧那 sudo 如何使用?
Tips 事实上,一般用户能够具有 sudo 的使用权,就是管理员事先审核通过后,才开放 sudo 的使用权的!因此,除非是信任用户,否则一般用户默认是不能操作 sudo 的喔!
- sudo 的指令用法
由于一开始系统默认仅有 root 可以执行 sudo ,因此下面的范例我们先以 root 的身份来执行,等到谈到 visudo 时,再以一般使用者来讨论其他 sudo 的用法吧! sudo 的语法如下:
Tips 还记得在安装 CentOS 7 的第三章时,在设置一般帐号的项目中,有个“让这位使用者成为管理员”的选项吧?如果你有勾选该选项的话, 那除了 root 之外,该一般用户确实是可以使用 sudo 的喔(以鸟哥的例子来说, dmtsai 默认竟然可以使用 sudo 了!)!这是因为创建帐号的时候,默认将此用户加入 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 <u>"mkdir ~vbird1/www; cd ~vbird1/www; \</u>
> <u>echo 'This is index.html file' > index.html"</u>
[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 可以让你切换身份来进行某项任务,例如上面的两个范例。范例一中,我们的 root 使用 sshd 的权限去进行某项任务! 要注意,因为我们无法使用“ su - sshd ”去切换系统帐号 (因为系统帐号的 shell 是 /sbin/nologin), 这个时候 sudo 真是他 X 的好用了!立刻以 sshd 的权限在 /tmp 下面创建文件!查阅一下文件权限你就了解意义啦! 至于范例二则更使用多重指令串 (通过分号 ; 来延续指令进行),使用 sh -c 的方法来执行一连串的指令, 如此真是好方便!
但是 sudo 默认仅有 root 能使用啊!为什么呢?因为 sudo 的执行是这样的流程:
- 当使用者执行 sudo 时,系统于 /etc/sudoers 文件中搜寻该使用者是否有执行 sudo 的权限;
- 若使用者具有可执行 sudo 的权限后,便让使用者“输入使用者自己的密码”来确认;
- 若密码输入成功,便开始进行 sudo 后续接的指令(但 root 执行 sudo 时,不需要输入密码);
- 若欲切换的身份与执行者身份相同,那也不需要输入密码。
所以说,sudo 执行的重点是:“能否使用 sudo 必须要看 /etc/sudoers 的设置值, 而可使用 sudo 者是通过输入使用者自己的密码来执行后续的指令串”喔!由于能否使用与 /etc/sudoers 有关, 所以我们当然要去编辑 sudoers 文件啦!不过,因为该文件的内容是有一定的规范的,因此直接使用 vi 去编辑是不好的。 此时,我们得要通过 visudo 去修改这个文件喔!
- visudo 与 /etc/sudoers
从上面的说明我们可以知道,除了 root 之外的其他帐号,若想要使用 sudo 执行属于 root 的权限指令,则 root 需要先使用 visudo 去修改 /etc/sudoers ,让该帐号能够使用全部或部分的 root 指令功能。为什么要使用 visudo 呢?这是因为 /etc/sudoers 是有设置语法的,如果设置错误那会造成无法使用 sudo 指令的不良后果。因此才会使用 visudo 去修改, 并在结束离开修改画面时,系统会去检验 /etc/sudoers 的语法就是了。
一般来说,visudo 的设置方式有几种简单的方法喔,下面我们以几个简单的例子来分别说明:
- I. 单一使用者可进行 root 所有指令,与 sudoers 文件语法:
假如我们要让 vbird1 这个帐号可以使用 root 的任何指令,基本上有两种作法,第一种是直接通过修改 /etc/sudoers ,方法如下:
[root@study ~]# visudo
....(前面省略)....
root ALL=(ALL) ALL <==找到这一行,大约在 98 行左右
vbird1 ALL=(ALL) ALL <==这一行是你要新增的!
....(下面省略)....
有趣吧!其实 visudo 只是利用 vi 将 /etc/sudoers 文件调用出来进行修改而已,所以这个文件就是 /etc/sudoers 啦! 这个文件的设置其实很简单,如上面所示,如果你找到 98 行 (有 root 设置的那行) 左右,看到的数据就是:
使用者帐号 登陆者的来源主机名称=(可切换的身份) 可下达的指令
root ALL=(ALL) ALL <==这是默认值
上面这一行的四个元件意义是:
- “使用者帐号”:系统的哪个帐号可以使用 sudo 这个指令的意思;
- “登陆者的来源主机名称”:当这个帐号由哪部主机连线到本 Linux 主机,意思是这个帐号可能是由哪一部网络主机连线过来的, 这个设置值可以指定用户端计算机(信任的来源的意思)。默认值 root 可来自任何一部网络主机
- “(可切换的身份)”:这个帐号可以切换成什么身份来下达后续的指令,默认 root 可以切换成任何人;
- “可下达的指令”:可用该身份下达什么指令?这个指令请务必使用绝对路径撰写。 默认 root 可以切换任何身份且进行任何指令之意。
那个 ALL 是特殊的关键字,代表任何身份、主机或指令的意思。所以,我想让 vbird1 可以进行任何身份的任何指令, 就如同上表特殊字体写的那样,其实就是复制上述默认值那一行,再将 root 改成 vbird1 即可啊! 此时“vbird1 不论来自哪部主机登陆,他可以变换身份成为任何人,且可以进行系统上面的任何指令”之意。 修改完请储存后离开 vi,并以 vbird1 登陆系统后,进行如下的测试看看:
[vbird1@study ~]$ tail -n 1 /etc/shadow <==注意!身份是 vbird1
tail: cannot open `/etc/shadow' for reading: Permission denied
# 因为不是 root 嘛!所以当然不能查询 /etc/shadow
[vbird1@study ~]$ 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.
[sudo] password for vbird1: <==注意啊!这里输入的是“ vbird1 自己的密码 ”
pro3:$6$DMilzaKr$OeHeTDQPHzDOz/u5Cyhq1Q1dy...:16636:0:99999:7:::
# 看!vbird1 竟然可以查询 shadow !
注意到了吧!vbird1 输入自己的密码就能够执行 root 的指令!所以,系统管理员当然要了解 vbird1 这个用户的“操守”才行!否则随便设置一个使用者,他恶搞系统怎办?另外,一个一个设置太麻烦了, 能不能使用群组的方式来设置呢?参考下面的第二种方式吧。
- II. 利用 wheel 群组以及免密码的功能处理 visudo
我们在本章前面曾经创建过 pro1, pro2, pro3 ,这三个用户能否通过群组的功能让这三个人可以管理系统? 可以的,而且很简单!同样我们使用实际案例来说明:
[root@study ~]# visudo <==同样的,请使用 root 先设置
....(前面省略)....
%wheel ALL=(ALL) ALL <==大约在 106 行左右,请将这行的 # 拿掉!
# 在最左边加上 % ,代表后面接的是一个“群组”之意!改完请储存后离开
[root@study ~]# usermod -a -G wheel pro1 <==将 pro1 加入 wheel 的支持
上面的设置值会造成“任何加入 wheel 这个群组的使用者,就能够使用 sudo 切换任何身份来操作任何指令”的意思。 你当然可以将 wheel 换成你自己想要的群组名。接下来,请分别切换身份成为 pro1 及 pro2 试看看 sudo 的运行。
[pro1@study ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro1
....(前面省略)....
[sudo] password for pro1: <==输入 pro1 的密码喔!
pro3:$6$DMilzaKr$OeHeTDQPHzDOz/u5Cyhq1Q1dy...:16636:0:99999:7:::
[pro2@study ~]$ sudo tail -n 1 /etc/shadow <==注意身份是 pro2
[sudo] password for pro2: <==输入 pro2 的密码喔!
pro2 is not in the sudoers file. This incident will be reported.
# 仔细看错误讯息他是说这个 pro2 不在 /etc/sudoers 的设置中!
这样理解群组了吧?如果你想要让 pro3 也支持这个 sudo 的话,不需要重新使用 visudo ,只要利用 usermod 去修改 pro3 的群组支持,让 pro3 用户加入 wheel 群组当中,那他就能够进行 sudo 啰! 好了!那么现在你知道为啥在安装时创建的用户,就是那个 dmstai 默认可以使用 sudo 了吗?请使用“ id dmtsai ”看看, 这个用户是否有加入 wheel 群组呢?嘿嘿!了解乎?
Tips 从 CentOS 7 开始,在 sudoers 文件中,默认已经开放 %wheel 那一行啰!以前的 CentOS 旧版本都是没有启用的呢!
简单吧!不过,既然我们都信任这些 sudo 的用户了,能否提供“不需要密码即可使用 sudo ”呢? 就通过如下的方式:
[root@study ~]# visudo <==同样的,请使用 root 先设置
....(前面省略)....
%wheel ALL=(ALL) NOPASSWD: ALL <==大约在 109 行左右,请将 # 拿掉!
# 在最左边加上 % ,代表后面接的是一个“群组”之意!改完请储存后离开
重点是那个 NOPASSWD 啦!该关键字是免除密码输入的意思喔!
- III. 有限制的指令操作:
上面两点都会让使用者能够利用 root 的身份进行任何事情!这样总是不太好~如果我想要让使用者仅能够进行部分系统任务, 比方说,系统上面的 myuser1 仅能够帮 root 修改其他使用者的密码时,亦即“当使用者仅能使用 passwd 这个指令帮忙 root 修改其他用户的密码”时,你该如何撰写呢?可以这样做:
[root@study ~]# visudo <==注意是 root 身份
myuser1 ALL=(root) /usr/bin/passwd <==最后指令务必用绝对路径
上面的设置值指的是“myuser1 可以切换成为 root 使用 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 的密码被 myuser1 给改变了!下次 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 ”这两个指令例外! 如此一来 myuser1 就无法改变 root 的密码了!这样这位使用者可以具有 root 的能力帮助你修改其他用户的密码, 而且也不能随意改变 root 的密码!很有用处的!
- IV. 通过别名创建 visudo:
如上述第三点,如果我有 15 个用户需要加入刚刚的管理员行列,那么我是否要将上述那长长的设置写入 15 行啊? 而且如果想要修改命令或者是新增命令时,那我每行都需要重新设置,很麻烦ㄟ!有没有更简单的方式? 是有的!通过别名即可!我们 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(来源主机名称别名) 都需要使用大写字符的!这个 ADMPW 代表后面接的那些实际帐号。 而该帐号能够进行的指令就如同 ADMPWCOM 后面所指定的那样!上表最后一行则写入这两个别名 (帐号与指令别名), 未来要修改时,我只要修改 User_Alias 以及 Cmnd_Alias 这两行即可!设置方面会比较简单有弹性喔!
- V. sudo 的时间间隔问题:
或许您已经发现了,那就是,如果我使用同一个帐号在短时间内重复操作 sudo 来运行指令的话, 在第二次执行 sudo 时,并不需要输入自己的密码!sudo 还是会正确的运行喔!为什么呢? 第一次执行 sudo 需要输入密码,是担心由于使用者暂时离开座位,但有人跑来你的座位使用你的帐号操作系统之故。 所以需要你输入一次密码重新确认一次身份。
两次执行 sudo 的间隔在五分钟内,那么再次执行 sudo 时就不需要再次输入密码了, 这是因为系统相信你在五分钟内不会离开你的作业,所以执行 sudo 的是同一个人!呼呼!真是很人性化的设计啊~ ^_^。不过如果两次 sudo 操作的间隔超过 5 分钟,那就得要重新输入一次你的密码了 [4]
- VI. sudo 搭配 su 的使用方式:
很多时候我们需要大量执行很多 root 的工作,所以一直使用 sudo 觉得很烦ㄟ!那有没有办法使用 sudo 搭配 su , 一口气将身份转为 root ,而且还用使用者自己的密码来变成 root 呢?是有的!而且方法简单的会让你想笑! 我们创建一个 ADMINS 帐号别名,然后这样做:
[root@study ~]# visudo
User_Alias ADMINS = pro1, pro2, pro3, myuser1
ADMINS ALL=(root) /bin/su -
接下来,上述的 pro1, pro2, pro3, myuser1 这四个人,只要输入“ sudo su - ”并且输入“自己的密码”后, 立刻变成 root 的身份!不但 root 密码不会外流,使用者的管理也变的非常方便! 这也是实务上面多人共管一部主机时常常使用的技巧呢!这样管理确实方便,不过还是要强调一下大前提, 那就是“这些你加入的使用者,全部都是你能够信任的用户”!