Linux 命令 su 和 sudo 的区别

之前一向对 su 和 sudo 这两个指令犯迷糊,最近专门搜了这方面的材料,总算是把两者的联系以及用法搞清楚了,这篇文章来体系总结一下。

准备作业

由于本篇博客中涉及到用户切换,所以我需求提前准备好几个测试用户,便利后续切换。

Linux 中新建用户的指令是 useradd ,一般体系中这个指令对应的路径都在 PATH 环境变量里,假如直接输入 useradd 不管用的话,就用肯定路径名的办法:/usr/sbin/useradd 。

useradd 新建用户指令只有 root 用户才干履行,咱们先从普通用户 ubuntu 切换到 root 用户(怎么切换后文会介绍):

ubuntu@VM-0-14-ubuntu:~$ su -
Password:                                    # 输入 root 用户登录暗码
root@VM-0-14-ubuntu:~# useradd -m test_user     # 带上 -m 参数
root@VM-0-14-ubuntu:~# ls /home
test_user  ubuntu              # 能够看到 /home 目录下面有两个用户了

由于还没有给新建的用户 test_user 设置登录暗码,这就导致咱们无法从普通用户 ubuntu 切换到 test_user,所以接下来,咱们需求用 root 来设置 test_user 的登录暗码。需求用到 passwd 指令:

root@VM-0-14-ubuntu:~# passwd test_user
Enter new UNIX password:           # 输出 test_user 的暗码
Retype new UNIX password:       
passwd: password updated successfully
root@VM-0-14-ubuntu:~#

接着咱们输入 exit 退出 root 用户到 普通用户 ubuntu:

root@VM-0-14-ubuntu:~# exit
logout
ubuntu@VM-0-14-ubuntu:~$

能够看到,指令提示符前面现已由 root 变成 ubuntu,说明咱们现在的身份是 ubuntu 用户。引荐:120 个《 必知必会的 Linux 体系常用指令 》.PDF

su 指令介绍及首要用法

首先需求解说下 su 代表什么意思。

之前一向以为 su是 super user,查阅材料之后才知道原来标明switch user。知道 su 是由什么缩写来的之后,那么它供给的功用就显而易见了,便是切换用户。

参数

su 的一般运用办法是:

su  
或许
su - 

两种办法只差了一个字符 -,会有比较大的差异:

假如加入了 – 参数,那么是一种 login-shell 的办法,意思是说切换到另一个用户 之后,当时的 shell 会加载 对应的环境变量和各种设置;
假如没有加入 – 参数,那么是一种 non-login-shell 的办法,意思是说我现在切换到了 ,可是当时的 shell 仍是加载切换之前的那个用户的环境变量以及各种设置。

光解说会比较笼统,咱们看一个例子就比较简单理解了。

咱们首先从 ubuntu 用户以 non-login-shell 的办法切换到 root 用户,比较两种用户状态下环境变量中 PWD 的值(su 指令不跟任何 ,默许切换到 root 用户):

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu                        # 是 /home/ubuntu
HOME=/home/ubuntu
# 省掉......
ubuntu@VM-0-14-ubuntu:~$ su             # non-login-shell 办法
Password:                               # 输入 root 用户登录暗码
root@VM-0-14-ubuntu:/home/ubuntu# env | grep ubuntu
PWD=/home/ubuntu                        # 能够发现仍是 /home/ubuntu
root@VM-0-14-ubuntu:/home/ubuntu#

咱们的确是切换到 root 用户了,可是 shell 环境中的变量并没有改变,仍是用之前 ubuntu 用户的环境变量。

接着咱们从 ubuntu 用户以 login-shell 的办法切换到 root 用户,同样比较两种用户转台下环境变量中 PWD 的值:

ubuntu@VM-0-14-ubuntu:~$ env | grep ubuntu
USER=ubuntu
PWD=/home/ubuntu                # 是 /home/ubuntu
HOME=/home/ubuntu
# 省掉.......
ubuntu@VM-0-14-ubuntu:~$ su -    # 是 login-shell 办法
Password:
root@VM-0-14-ubuntu:~# env | grep root
USER=root
PWD=/root                        # 现已变成 /root 了
HOME=/root
MAIL=/var/mail/root
LOGNAME=root
root@VM-0-14-ubuntu:~#

能够看到用 login-shell 的办法切换用户的话,shell 中的环境变量也跟着改变了。

总结:详细运用哪种办法切换用户看个人需求:

假如不想由于切换到另一个用户导致自己在当时用户下的设置不可用,那么用 non-login-shell 的办法;
假如切换用户后,需求用到该用户的各种环境变量(不同用户的环境变量设置一般是不同的),那么运用 login-shell 的办法。
切换到指定用户

前面现已介绍了,假如 su 指令后边不跟任何 ,那么默许是切换到 root 用户:

ubuntu@VM-0-14-ubuntu:~$ su -
Password:                     # root 用户的暗码
root@VM-0-14-ubuntu:/home/ubuntu#

由于咱们在 1. 准备作业 部分现已新建了一个 test_user 用户,而且咱们也知道 test_user 用户的登录暗码(root 用户设置的),咱们就能从 ubuntu 用户切换到 test_user 用户:

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:                 # test_user 用户的暗码
$
-c 参数

前面的办法中,咱们都是先切换到另一个用户(root 或许 test_user),在哪个用户的状态下履行指令,最终输入 exit 返回当时 ubuntu 用户。

还有一种办法是:不需求先切换用户再履行指令,能够直接在当时用户下,以另一个用户的办法履行指令,履行完毕后就返回当时用户。这就得用到 -c 参数。

详细运用办法是:

su - -c \"指令串\"           # 以 root 的办法履行 \"指令串\"

我么看个例子:

ubuntu@VM-0-14-ubuntu:~$ cat /etc/shadow
cat: /etc/shadow: Permission denied     
# ubuntu 用户不能直接检查 /etc/shadow 文件内容

ubuntu@VM-0-14-ubuntu:~$ su - -c \"tail -n 4 /etc/shadow\"
Password:                      # 输入 root 用户暗码
ubuntu:$1$fZKcWEDI$uwZ64uFvVbwpHTbCSgim0/:18352:0:99999:7:::
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$     #履行完立刻返回 ubuntu 用户而不是 root 用户

这种履行办法和后边要介绍的 sudo 很像,都是暂时申请一下 root 用户的权限。但仍是有差异,咱们接着往后看。

sudo 指令介绍及首要用法

首先仍是解说下 sudo 指令是什么意思。

sudo 的英文全称是 super user do,即以超级用户(root 用户)的办法履行指令。这儿的 sudo 和之前 su 标明的 switch user 是不同的,这点需求留意,很简单搞混。

咱们先介绍 sudo 指令能做什么事情,然后说明为何能做到这些,以及怎么做到这些。咱们开始。

首要用法

咱们在 Linux 中经常会碰到 Permission denied 这种情况,比如以 ubuntu 用户的身份检查 /etc/shadow 的内容。由于这个文件的内容是只有 root 用户能检查的。

那假如咱们想要检查怎么办呢?这时候就能够运用 sudo :

ubuntu@VM-0-14-ubuntu:~$ tail -n 3 /etc/shadow
tail: cannot open \'/etc/shadow\' for reading: Permission denied      # 没有权限
ubuntu@VM-0-14-ubuntu:~$ sudo !!                                    # 跟两个惊叹号
sudo tail -n 3 /etc/shadow
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
ubuntu@VM-0-14-ubuntu:~$

实例中,咱们运用了 sudo !! 这个小技巧,标明重复上面输入的指令,只不过在指令最前面加上 sudo 。

由于我现已设置了 sudo 指令不需求输入暗码,所以这儿 sudo !! 就能直接输出内容。假如没有设置的话,需求输入当时这个用户的暗码,例如本例中,我就应该输入 ubuntu 用户的登录暗码。

两次相邻的 sudo 操作,假如间隔在 5min 之内,第二次输入 sudo 不需求从头输入暗码;假如超越 5min,那么再输入 sudo 时,又需求输入暗码。所以一个比较省劲的办法是设置 sudo 操作不需求暗码。后边介绍怎么设置。

sudo 除了以 root 用户的权限履行指令外,还有其它几个用法,这儿做简单介绍。

切换到 root 用户:

sudo su -

这种办法也能以 login-shell 的办法切换到 root 用户,可是它和 su – 办法是由区别的:

前者输入 sudo su – 后,需求供给当时用户的登录暗码,也便是 ubuntu 用户的暗码;后者输入 su – 后,需求供给 root 用户的登录暗码。还有一个指令:

sudo -i

这个指令和 sudo su – 效果共同,也是切换到 root 用户,也是需求供给当时用户(ubuntu 用户)的登录暗码。

咱们现在切换到 test_user 用户,尝试显现 /etc/shadow 文件的内容:

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:                                       # test_user 的暗码
$ sudo cat /etc/shadow
[sudo] password for test_user:                  # test_user 的暗码
test_user is not in the sudoers file.  This incident will be reported.
$

咱们会看到倒数第二行中的错误提示信息,咱们无法检查 /etc/shadow 的内容,这是为什么?为什么 ubuntu 能够运用 sudo 可是 test_user 不行呢?

这就涉及到 sudo 的作业原理了。

sudo 作业原理

一个用户能否运用 sudo 指令,取决于 /etc/sudoers 文件的设置。

从上一节中咱们现已看到,ubuntu 用户能够正常运用 sudo ,可是 test_user 用户却无法运用,这是由于 /etc/sudoers 文件里没有装备 test_user。

/etc/sudoers 也是一个文本文件,可是因其有特定的语法,咱们不要直接用 vim 或许 vi 来修改它,需求用 visudo 这个指令。输入这个指令之后就能直接修改 /etc/sudoers 这个文件了。

需求说明的是,只有 root 用户有权限运用 visudo 指令。

咱们先来看下输入 visudo 指令后显现的内容。

输入(root 用户):

root@VM-0-14-ubuntu:~# visudo

输出:

# User privilege specification
root    ALL=(ALL:ALL) ALL

# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL

# Allow members of group sudo to execute any command
%sudo   ALL=(ALL:ALL) ALL

# See sudoers(5) for more information on \"#include\" directives:

#includedir /etc/sudoers.d
ubuntu  ALL=(ALL:ALL) NOPASSWD: ALL
解说下每一行的格式
第一个标明用户名,如 root 、ubuntu 等;
接下来等号左面的 ALL 标明允许从任何主机登录当时的用户账户;
等号右边的 ALL 标明:这一行行首对一个的用户能够切换到体系中任何一个其它用户;
行尾的 ALL 标明:当时行首的用户,能以 root 用户的身份下达什么指令,ALL 标明能够下达任何指令。

咱们还留意到 ubuntu 对应的那一行有个 NOPASSWD 关键字,这便是标明 ubuntu 这个用户在恳求 sudo 时不需求输入暗码,到这儿就解说了前面的问题。

同时咱们留意到,这个文件里并没有 test_user 对应的行,这也就解说了为什么 test_user 无法运用 sudo 指令。

接下来,咱们尝试将 test_user 增加到 /etc/sudoers 文件中,使 test_user 也能运用 sudo 指令。咱们在最终一行增加:

test_user  ALL=(ALL:ALL)  ALL       # test_user 运用 sudo 需求供给 test_user 的暗码

接下来咱们再在 test_user 账户下履行 sudo :

ubuntu@VM-0-14-ubuntu:~$ su - test_user
Password:
$ tail -n 3 /etc/shadow
tail: cannot open \'/etc/shadow\' for reading: Permission denied
$ sudo tail -n 3 /etc/shadow                   # 加上 sudo
ntp:*:17752:0:99999:7:::
mysql:!:18376:0:99999:7:::
test_user:$6$.ZY1lj4m$ii0x9CG8h.JHlh6zKbfBXRuolJmIDBHAd5eqhvW7lbUQXTRS//89jcuTzRilKqRkP8YbYW4VPxmTVHWRLYNGS/:18406:0:99999:7:::
$

能够看到,现在现已能够运用 sudo 了。

思考

咱们现已看到了,假如一个用户在 /etc/sudoers 文件中,那么它就具有 sudo 权限,就能经过 sudo su – 或许 sudo -i 等指令切换到 root 用户了,那这时这个用户就变成 root 用户了,那这不对体系形成很大的威胁吗?

实际上的确是这样的。所以假如在修改 /etc/sudoers 文件赋予某种用户 sudo 权限时,必需求确定该用户是可信任的,不会对体系形成恶意损坏,否则将一切 root 权限都赋予该用户将会有非常大的风险。

当然,root 用户也能够修改 /etc/sudoers 运用户只具有一部分权限,即只能履行一小部分指令。

二者的差异对比

咱们现已看到:

运用 su – ,供给 root 账户的暗码,能够切换到 root 用户;
运用 sudo su – ,供给当时用户的暗码,也能够切换到 root 用户
两种办法的差异也显而易见:假如咱们的 Linux 体系有许多用户需求运用的话,前者要求一切用户都知道 root 用户的暗码,这显然是非常风险的;后者是不需求露出 root 账户暗码的,用户只需求输入自己的账户暗码就能够,而且哪些用户能够切换到 root,这完全是受 root 控制的(root 经过设置 /etc/sudoers 实现的),这样体系就安全许多了。

一般都是引荐运用sudo办法。

准备作业
su 指令介绍及首要用法
sudo 指令介绍及首要用法
二者的差异对比
目录