5.6 su命令与sudo服务

各位读者在实验环境中很少遇到安全问题,并且为了避免因权限因素导致配置服务失败,从而建议使用root管理员来学习本书,但是在生产环境中还是要对安全多一份敬畏之心,不要用root管理员去做所有事情。因为一旦执行了错误的命令,可能会直接导致系统崩溃,这样一来,不但客户指责、领导批评,没准奖金也会鸡飞蛋打。但转头一想,尽管Linux系统为了安全性考虑,使得许多系统命令和服务只能被root管理员来使用,但是这也让普通用户受到了更多的权限束缚,从而导致无法顺利完成特定的工作任务。

su命令可以解决切换用户身份的需求,使得当前用户在不退出登录的情况下,顺畅地切换到其他用户,比如从root管理员切换至普通用户:

  1. [root@linuxprobe ~]# id
  2. uid=0(root) gid=0(root) groups=0(root)
  3. [root@linuxprobe ~]# su - linuxprobe
  4. Last login: Wed Jan 4 01:17:25 EST 2017 on pts/0
  5. [linuxprobe@linuxprobe ~]$ id
  6. uid=1000(linuxprobe) gid=1000(linuxprobe) groups=1000(linuxprobe) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

细心的读者一定会发现,上面的su命令与用户名之间有一个减号(-),这意味着完全切换到新的用户,即把环境变量信息也变更为新用户的相应信息,而不是保留原始的信息。强烈建议在切换用户身份时添加这个减号(-)。

另外,当从root管理员切换到普通用户时是不需要密码验证的,而从普通用户切换成root管理员就需要进行密码验证了;这也是一个必要的安全检查:

  1. [linuxprobe@linuxprobe root]$ su root
  2. Password:
  3. [root@linuxprobe ~]# su - linuxprobe
  4. Last login: Mon Aug 24 19:27:09 CST 2017 on pts/0
  5. [linuxprobe@linuxprobe ~]$ exit
  6. logout
  7. [root@linuxprobe ~]#

尽管像上面这样使用su命令后,普通用户可以完全切换到root管理员身份来完成相应工作,但这将暴露root管理员的密码,从而增大了系统密码被黑客获取的几率;这并不是最安全的方案。

刘遄老师接下来将介绍如何使用sudo命令把特定命令的执行权限赋予给指定用户,这样既可保证普通用户能够完成特定的工作,也可以避免泄露root管理员密码。我们要做的就是合理配置sudo服务,以便兼顾系统的安全性和用户的便捷性。sudo服务的配置原则也很简单—在保证普通用户完成相应工作的前提下,尽可能少地赋予额外的权限。

sudo命令用于给普通用户提供额外的权限来完成原本root管理员才能完成的任务,格式为“sudo [参数] 命令名称”。sudo服务中可用的参数以及相应的作用如表5-7所示。

表5-7 sudo服务中的可用参数以及作用

参数作用
-h列出帮助信息
-l列出当前用户可执行的命令
-u 用户名或UID值以指定的用户身份执行命令
-k清空密码的有效时间,下次执行sudo时需要再次进行密码验证
-b在后台执行指定的命令
-p更改询问密码的提示语

总结来说,sudo命令具有如下功能:

限制用户执行指定的命令:

记录用户执行的每一条命令;

配置文件(/etc/sudoers)提供集中的用户管理、权限与主机等参数;

验证密码的后5分钟内(默认值)无须再让用户再次验证密码。

当然,如果担心直接修改配置文件会出现问题,则可以使用sudo命令提供的visudo命令来配置用户权限。这条命令在配置用户权限时将禁止多个用户同时修改sudoers配置文件,还可以对配置文件内的参数进行语法检查,并在发现参数错误时进行报错。

只有root管理员才可以使用visudo命令编辑sudo服务的配置文件。

  1. visudo: >>> /etc/sudoers: syntax error near line 111 <<<
  2. What now?
  3. Options are:
  4. (e)dit sudoers file again
  5. (x)it without saving changes to sudoers file
  6. (Q)uit and save changes to sudoers file (DANGER!)

使用visudo命令配置sudo命令的配置文件时,其操作方法与Vim编辑器中用到的方法一致,因此在编写完成后记得在末行模式下保存并退出。在sudo命令的配置文件中,按照下面的格式将第99行(大约)填写上指定的信息:

谁可以使用 允许使用的主机=(以谁的身份) 可执行命令的列表

  1. [root@linuxprobe ~]# visudo
  2. 96 ##
  3. 97 ## Allow root to run any commands anywhere
  4. 98 root ALL=(ALL) ALL
  5. 99 linuxprobe ALL=(ALL) ALL

在填写完毕后记得要先保存再退出,然后切换至指定的普通用户身份,此时就可以用sudo -l命令查看到所有可执行的命令了(下面的命令中,验证的是该普通用户的密码,而不是root管理员的密码,请读者不要搞混了):

  1. [root@linuxprobe ~]# su - linuxprobe
  2. Last login: Thu Sep 3 15:12:57 CST 2017 on pts/1
  3. [linuxprobe@linuxprobe ~]$ sudo -l
  4. [sudo] password for linuxprobe:此处输入linuxprobe用户的密码
  5. Matching Defaults entries for linuxprobe on this host:
  6. requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS
  7. DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1
  8. PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE
  9. LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES", env_keep+="LC_MONETARY
  10. LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE", env_keep+="LC_TIME LC_ALL
  11. LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
  12. secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
  13. User linuxprobe may run the following commands on this host:
  14. (ALL) ALL

接下来是见证奇迹的时刻!作为一名普通用户,是肯定不能看到root管理员的家目录(/root)中的文件信息的,但是,只需要在想执行的命令前面加上sudo命令就可以了:

  1. [linuxprobe@linuxprobe ~]$ ls /root
  2. ls: cannot open directory /root: Permission denied
  3. [linuxprobe@linuxprobe ~]$ sudo ls /root
  4. anaconda-ks.cfg Documents initial-setup-ks.cfg Pictures Templates
  5. Desktop Downloads Music Public Videos

效果立竿见影!但是考虑到生产环境中不允许某个普通用户拥有整个系统中所有命令的最高执行权(这也不符合前文提到的权限赋予原则,即尽可能少地赋予权限),因此ALL参数就有些不合适了。因此只能赋予普通用户具体的命令以满足工作需求,这也受到了必要的权限约束。如果需要让某个用户只能使用root管理员的身份执行指定的命令,切记一定要给出该命令的绝对路径,否则系统会识别不出来。我们可以先使用whereis命令找出命令所对应的保存路径,然后把配置文件第99行的用户权限参数修改成对应的路径即可:

  1. [linuxprobe@linuxprobe ~]$ exit
  2. logout
  3. [root@linuxprobe ~]# whereis cat
  4. cat: /usr/bin/cat /usr/share/man/man1/cat.1.gz /usr/share/man/man1p/cat.1p.gz
  5. [root@linuxprobe ~]# visudo
  6. 96 ##
  7. 97 ## Allow root to run any commands anywhere
  8. 98 root ALL=(ALL) ALL
  9. 99 linuxprobe ALL=(ALL) /usr/bin/cat

在编辑好后依然是先保存再退出。再次切换到指定的普通用户,然后尝试正常查看某个文件的内容,此时系统提示没有权限。这时再使用sudo命令就可以顺利地查看文件内容了:

  1. [root@linuxprobe ~]# su - linuxprobe
  2. Last login: Thu Sep 3 15:51:01 CST 2017 on pts/1
  3. [linuxprobe@linuxprobe ~]$ cat /etc/shadow
  4. cat: /etc/shadow: Permission denied
  5. [linuxprobe@linuxprobe ~]$ sudo cat /etc/shadow
  6. root:$6$GV3UVtX4ZGg6ygA6$J9pBuPGUSgZslj83jyoI7ThJla9ZAULku3BcncAYF00Uwk6Sqc4E36MnD1hLtlG9QadCpQCNVJs/5awHd0/pi1:16626:0:99999:7:::
  7. bin:*:16141:0:99999:7:::
  8. daemon:*:16141:0:99999:7:::
  9. adm:*:16141:0:99999:7:::
  10. lp:*:16141:0:99999:7:::
  11. sync:*:16141:0:99999:7:::
  12. shutdown:*:16141:0:99999:7:::
  13. halt:*:16141:0:99999:7:::
  14. mail:*:16141:0:99999:7:::
  15. operator:*:16141:0:99999:7:::
  16. games:*:16141:0:99999:7:::
  17. ftp:*:16141:0:99999:7:::
  18. nobody:*:16141:0:99999:7:::
  19. ………………省略部分文件内容………………

大家千万不要以为到这里就结束了,刘遄老师还有更压箱底的宝贝。不知大家是否发觉在每次执行sudo命令后都会要求验证一下密码。虽然这个密码就是当前登录用户的密码,但是每次执行sudo命令都要输入一次密码其实也挺麻烦的,这时可以添加NOPASSWD参数,使得用户执行sudo命令时不再需要密码验证:

  1. [linuxprobe@linuxprobe ~]$ exit
  2. logout
  3. [root@linuxprobe ~]# whereis poweroff
  4. poweroff: /usr/sbin/poweroff /usr/share/man/man8/poweroff.8.gz
  5. [root@linuxprobe ~]# visudo
  6. 96 ##
  7. 97 ## Allow root to run any commands anywhere
  8. 98 root ALL=(ALL) ALL
  9. 99 linuxprobe ALL=NOPASSWD: /usr/sbin/poweroff

这样,当切换到普通用户后再执行命令时,就不用再频繁地验证密码了,我们在日常工作中也就痛快至极了。

  1. [root@linuxprobe ~]# su - linuxprobe
  2. Last login: Thu Sep 3 15:58:31 CST 2017 on pts/1
  3. [linuxprobe@linuxprobe ~]$ poweroff
  4. User root is logged in on seat0.
  5. Please retry operation after closing inhibitors and logging out other users.
  6. Alternatively, ignore inhibitors and users with 'systemctl poweroff -i'.
  7. [linuxprobe@linuxprobe ~]$ sudo poweroff

本章节的复习作业(答案就在问题的下一行哦,用鼠标选中即可看到的~)

1.在RHEL 7系统中,root管理员是谁?

答:是UID为0的用户,默认是root管理员。

2.如何使用Linux系统的命令行来添加或删除用户?

答:添加和删除用户的命令分别是useradd与userdel。

3.若某个文件的所有者具有文件的读/写/执行权限,其余人仅有读权限,那么用数字法表示应该是什么?

答:所有者权限为rwx,所属组和其他人的权限为r—,因此数字法表示应该是744。

4.某链接文件的权限用数字法表示为755,那么相应的字符法表示是什么呢?

答:在Linux系统中,不同文件具有不同的类型,因此这里应写成lrwxr-xr-x。

5.如果希望用户执行某命令时临时拥有该命令所有者的权限,应该设置什么特殊权限?

答:特殊权限中的SUID。

6.若对文件设置了隐藏权限+i,则意味着什么?

答:无法对文件进行修改;若对目录设置了该参数,则仅能修改其中的子文件内容而不能新建或删除文件。

7.使用访问控制列表(ACL)来限制linuxprobe用户组,使得该组中的所有成员不得在/tmp目录中写入内容。

答:想要设置用户组的ACL,则需要把u改成g,即setfacl -Rm g:linuxprobe:r-x /tmp。

8.当普通用户使用sudo命令时是否需要验证密码?

答:系统在默认情况下需要验证当前登录用户的密码,若不想要验证,可添加NOPASSWD参数。

本文原创地址:https://www.linuxprobe.com/chapter-05.html   编辑:刘遄,审核员:暂无

为您推荐一些与本文相关的文章:

转载必需保留本文链接:https://www.linuxprobe.com/chapter-05.html

本文依据CC-BY-NC-SA 3.0协议发布,竭诚为读者提供Linux视频教程、Linux学习资料以及红帽考试资料等优质学习资源。