首页 > 技术文章 > sudo和su的区别

jing99 2017-11-27 16:34 原文

su 命令

su

  su命令的主要作用是让你可以在已登录的会话中切换到另外一个用户。换句话说,这个工具可以让你在不登出当前用户的情况下登录为另外一个用户。

  su命令经常被用于切换到超级用户或 root 用户(因为在命令行下工作,经常需要 root 权限),但是 - 正如前面所提到的 - su 命令也可以用于切换到任意非 root 用户。

  如何使用 su 命令切换到 root 用户,命令:su 不带参数。

  su 命令要求输入的密码是 root 用户的密码。所以,一般 su 命令需要输入目标用户的密码。在输入正确的密码之后,su 命令会在终端的当前会话中打开一个子会话。

su -

  还有一种方法可以切换到 root 用户:运行 su - 命令,如:su - 可提供的环境为用户在直接登录时的环境

  那么,su 命令与 su - 命令之间有什么区别呢?前者在切换到 root 用户之后仍然保持旧的(或者说原始用户的)环境,而后者则是创建一个新的环境(由 root 用户 ~/.bashrc 文件所设置的环境),相当于使用 root 用户正常登录(从登录屏幕登录)。

  单纯使用su切换到root,读取变量的方式是non-login shell,这种方式下很多的变量都不会改变,尤其是PATH,所以root用的很多的命令都只能用绝对路径来执行,这种方式只是切换到root的身份。而用su -这种方式的话,是login shell方式,它是先以root身份登录然后再执行别的操作。

[devdeploy@CTU1000094641 ~]$ su  单纯的su切换用户
Password: 
[root@CTU1000094641 devdeploy]# pwd  pwd没有改变
/home/devdeploy
[root@CTU1000094641 devdeploy]# echo $PATH  PATH没有改变
/usr/lib64/qt-3.3/bin:/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/sbin:/biz/maas/java/bin:/home/devdeploy/bin
[root@CTU1000094641 devdeploy]# exit  
exit    显示为exit
[devdeploy@CTU1000094641 ~]$ su -  以root身份登录方式
Password: 
[root@CTU1000094641 ~]# pwd  pwd是进入到root的主文件夹下
/root
[root@CTU1000094641 ~]# echo $PATH  PATH已经改变
/usr/lib64/qt-3.3/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/biz/maas/java/bin:/root/bin
[root@CTU1000094641 ~]# exit
logout    显示为logout

  关于 su 命令的好处和坏处:

  有的时候,对于系统管理员(root)来讲,使用其他普通用户的 Shell 账户而不是自己的 root Shell 账户更会好一些。尤其是在处理用户问题时,最有效的方法就是是:登录目标用户以便重现以及调试问题。
  然而,在多数情况下,当从普通用户切换到 root 用户进行操作时,如果还使用普通用户的环境变量的话,那是不可取甚至是危险的操作。因为是在无意间切换使用普通用户的环境,所以当使用 root 用户进行程序安装或系统更改时,会产生与正常使用 root 用户进行操作时不相符的结果。例如,以普通用户安装程序会给普通用户意外损坏系统或获取对某些数据的未授权访问的能力。
  注意:如果你想在 su - 命令的 - 后面传递更多的参数,那么你必须使用 su -l 而不是 su -。以下是 - 和 -l 命令行选项的说明:

  -, -l, --login

  提供相当于用户在直接登录时所期望的环境。

  当使用 - 时,必须放在 su 命令的最后一个选项。其他选项(-l 和 --login)无此限制。

su -c

  还有一个值得一提的 su 命令行选项为:-c。该选项允许你提供在切换到目标用户之后要运行的命令。su 命令手册页是这样说明:

-c, --command COMMAND使用 -c 选项指定由 Shell 调用的命令。被执行的命令无法控制终端。所以,此选项不能用于执行需要控制 TTY 的交互式程序。  

  参考示例:

    su [target-user] -c [command-to-run]

  示例中,command-to-run 将会被这样执行:

    [shell] -c [command-to-run]

  示例中的 shell 类型将会被目标用户在 /etc/passwd 文件中定义的登录 shell 类型所替代。

sudo命令

  相比于su切换身份需要用户的密码,经常性的是需要root密码,sudo只是需要自己的密码,就可以以其他用户的身份来执行命令,经常是以root的身份执行命令,也并非所有人都可以用sudo。

[root@CTU1000094955 ~]# sudo head -n 3 /etc/shadow
root:$6$pr.H./1G$nENhNZTk0gs9i4XvTL98JRg99doxoKgYfh2AN7HXkWGs1.rVplfQwQ1gSiUbVF4kuZxM5/BEXbr5q6EsrmC75.:17438:0:99999:7:::
bin:*:16659:0:99999:7:::
daemon:*:16659:0:99999:7:::
[root@CTU1000094955 ~]# head -n 3 /etc/shadow
head:  cannot open '/etc/shadow' for reading:  Permission denied

  sudo是依赖于/etc/sudoers这个配置文件的。sudo的执行有这样一个流程:

1).当用户执行sudo时,系统于/etc/sudoers文件中查找该用户是否有执行sudo的权限;
2).若用户具有可执行sudo的权限,那么让用户输入用户自己的密码,注意这里输入的是用户自己的密码;
3).如果密码正确,便开始进行sudo后面的命令,root执行sudo是不需要输入密码的,切换到的身份与执行者身份相同的时候,也不需要输入密码。

  下面看看/etc/sudoers这个配置文件:

## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple
## systems).
## Syntax:
##
##      user    MACHINE=COMMANDS
##
## The COMMANDS section may have other options added to it.
##
## Allow root to run any commands anywhere
root    ALL=(ALL)       ALL

## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS

## Allows people in group wheel to run all commands
%wheel  ALL=(ALL)       ALL

  为何刚开始只有root能执行sudo,切换到root身份通过visudo查看/etc/sudoers这个配置文件,如果是vim /etc/sudoers是可以查看的,但是不能修改,因为sudoers这个文件是有语法的,只能通过visudo来修改。第一处红色那行代码,这行代码第一列root是用户账号,第二列的ALL意思是登陆者的来源主机名,第三列等号右边小括号中的ALL是代表可以切换的身份,第四列ALL是可执行的命令。
  1).单个用户的sudoers语法:
    如果我要我当前这个用户能执行root的所有操作,那么我只要加一行learnpython ALL=(ALL) ALL。那么如果有很多人需要执行sudo,那不是要写编写很多行啊,这样不是很麻烦,这样就要用到用户组了。
  2).利用用户组处理visudo:
    看看第二处红色那行代码,%wheel代表wheel用户组,如果我们将需要执行root所有操作的用户都加入到wheel用户组,或者我们自定义的用户组,然后添加一行代码,那么就不用一个用户一个用户的添加进来了,这样不是很省事啊。
  3).限制用户sudo的权限:
    经常我们不需要用户有那么大的权限,只要让他们具有他们负责范围的权限就可以了,比如有的有的人来管理密码,我们就只让他能进行密码的管理,而不让他有别的权限,这样就需要权限的控制了。如果我让我当前用户来管理密码,即learnpython这个用户能使用passwd这个命令来帮root修改用户密码,只要加这行learnpython ALL=(root) /usr/bin/passwd,那么learnpython这个用户就可以使用passwd这个命令了:

        

  但是如果只是执行sudo passwd命令,修改的就是root的密码,当然我们不希望普通用户能具有修改root密码的权限,那么在visudo的时候就需要将命令的参数限制好,如改成这样:

[root@localhost ~]# visudo  
learnpython    ALL=(root)    !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root  

   4).通过别名设置visudo

          查看sudoers这个文件的时候,你会看见User_Alias,Host_Alias和Cmnd_Alias这些东西,他们都是一些别名,User_Alias表示具有sudo权限的用户列表,就是第一列参数,Host_Alias表示主机的列表,就是第二列参数,Cmnd_Alias表示允许执行命令的列表,就是第四列参数,还有个Runas_Alias,我初始的sudoers里是没有的,这个表示用户以什么身份登录,也就是第三列参数。

        所以如果有几个密码管理员的话就可以加上如下代码:

[root@localhost ~]# visudo  
User_Alias PWMNG = manager1, manager2, manager3  
Cmnd_Alias PWCMD = !/usr/bin/passwd, /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root  
PWMNG    ALL=(root)    PWCMD  

  5).sudo搭配su

          从上面来看,我们都只是切换到别的用户然后执行命令,接着就切回到我们自己的用户了,如果我们要像su那样直接切换到root,然后干自己想干的,这个时候,就要将命令修改成/bin/su -,如下:

[root@localhost ~]# visudo  
User_Alias ADMINS = user1, user2, user3  
ADMINS    ALL=(root)    /bin/su -  

  当然这个是需要慎重了,因为这样用户user1,user2,user3等就直接切换到root了,切换后他们就是老大了。

        

  当我们连续使用sudo的时候,在一定时间内是不用再次输入我们的密码,这个其实是系统自己设定的,在五分钟之内执行sudo只需要输入一次密码就可以了。

sudo和su区别联系

  两个命令的最大区别是:sudo 命令需要输入当前用户的密码,su 命令需要输入 root 用户的密码。

1、就安全而言:sudo 命令更好。例如,考虑到需要 root 访问权限的多用户使用的计算机。在这种情况下,使用 su 意味着需要与其他用户共享 root 用户密码,这显然不是一种好习惯。

  如果要撤销特定用户的超级用户/root 用户的访问权限,唯一的办法就是更改 root 密码,然后再告知所有其他用户新的 root 密码。

  鉴于 sudo 命令要求输入的是其他用户自己的密码,所以,不需要共享 root 密码。同时,想要阻止特定用户访问 root 权限,只需要调整 sudoers 文件中的相应配置即可。

2、就默认行为而言:sudo 命令只允许使用提升的权限运行单个命令。而 su 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到明确退出登录。

  因此,su 命令的默认行为是有风险的,因为用户很有可能会忘记他们正在以 root 用户身份进行工作,于是,无意中做出了一些不可恢复的更改(例如:对错误的目录运行 rm -rf 命令!)。

3、就日志记录而言:尽管 sudo 命令是以目标用户(默认情况下是 root 用户)的身份执行命令,但是它们会使用 sudoer 所配置的用户名来记录是谁执行命令。而 su 命令是无法直接跟踪记录用户切换到 root 用户之后执行了什么操作。

4、就灵活性而言:sudo 命令比 su 命令灵活很多,因为你甚至可以限制 sudo 用户可以访问哪些命令。换句话说,用户通过 sudo 命令只能访问他们工作需要的命令。而 su 命令让用户有权限做任何事情。

  大概是因为使用 su 命令或直接以 root 用户身份登录有风险,所以,一些 Linux 发行版(如 Ubuntu)默认禁用 root 用户帐户。鼓励用户在需要 root 权限时使用 sudo 命令。

  然而,您还是可以成功执行 su 命令,而不用输入 root 用户的密码。运行命令:sudo su

  由于你使用 sudo 运行命令,你只需要输入当前用户的密码。所以,一旦完成操作,su 命令将会以 root 用户身份运行,这意味着它不会再要求输入任何密码。

  PS:如果你想在系统中启用 root 用户帐户(强烈反对,因为你可以使用 sudo 命令或 sudo su 命令),你必须手动设置 root 用户密码,可以使用命令:sudo passwd root

总结

       比较su和sudo,sudo有太多的好处。su方式切换是需要输入目标用户的密码,而sudo只需要输入自己的密码,所以sudo可以保护目标用户的密码不外流的。当帮root管理系统的时候,su是直接将root所有权利交给用户,而sudo可以更好分工,只要配置好/etc/sudoers,这样sudo可以保护系统更安全,而且分工明确,有条不紊。

推荐阅读