sudo
表示 “superuser do”。它允许已验证的用户以其他用户的身份来运行命令。其他用户可以是普通用户或者超级用户。然而,绝大部分时候我们用它来以提升的权限来运行命令。
sudo
命令与安全策略配合使用,默认安全策略是 sudoers
,可以通过编辑文件 /etc/sudoers
来配置。其安全策略具有高度可拓展性。人们可以开发和分发他们自己的安全策略作为插件。
sudo
与 su 的区别
在 GNU/Linux 中,有两种方式可以用提升的权限来运行命令:
- su 命令
- sudo 命令
su 表示 “switch user”。使用 su 命令,我们可以切换到 root 用户并且执行命令,但是这种方式存在一些缺点:
- 需要与他人共享 root 的密码
- 无法审查用户执行的命令
- 对于 root 用户,不能授予有限的访问权限
sudo
以独特的方式解决了这些问题:
- 不需要共享 root 用户的密码,普通用户可以使用自己的密码提升权限来执行命令
sudo
用户的所有操作都会被记录下来,管理员可以随时审查 sudo 用户执行了哪些操作- 可控的
sudo
用户的访问,我们可以限制用户只能执行某些命令
在基于 Debian 的 GNU/Linux 中,所有活动都记录在 /var/log/auth.log
文件中
使用 sudo
为普通用户添加 sudo 权限
/etc/sudoers
文件记录着谁可以用 sudo 命令来提升权限,添加普通用户为 sudo
用户
-
编辑 /etc/sudoers 文件最有效的方式是使用
visudo
命令:sudo visudo
-
添加以下行来允许用户 einverne 有
sudo
权限:einverne ALL=(ALL) ALL %admin ALL=(ALL) ALL
上述命令中:
- einverne 表示用户名,带有
%admin
的表示 admin 用户组授予 sudo 访问权限 - 第一个 ALL 指示允许从任何终端、机器访问
sudo
- 第二个 (ALL) 指示
sudo
命令被允许以任何用户身份执行 - 第三个 ALL 表示所有命令都可以作为 root 执行
如果打开默认的 visudo
可以发现已经配置这样一行
root ALL=(ALL:ALL) ALL
这一行表示的含义是,用户 root, 登录任何 hostname, 可以在任何用户或者组下运行任何命令。
user hostname=(runas-user:runas-group) command
这里有一个需要稍微注意的地方,括号中能看到有 (ALL)
和 (ALL:ALL)
的区别,如果仅仅使用 (ALL)
那么,sudo 无法使用 -g
来指定用户组运行程序。1
如果发现在该配置中已经配置了 %admin ALL=(ALL) ALL
,那么把用户加入到该 admin 组中,就不需要另外配置该用户了。
usermod -aG sudo einverne
注:/etc/sudoers
文件必须以 visudo
命令来修改,该命令可以防止因为文件格式错误而导致问题,如果visudo
默认的编辑器不是你常用的编辑,可以通过如下方法来修改
sudo update-alternatives --config editor
将用户添加到 sudo 组
上面提到编辑 /etc/sudoers
文件给用户添加 sudo 权限,不过还有一种更加简单的方法就是将用户添加到 sudo 或者 admin 组,修改 /etc/group
文件,然后在其中添加
sudo:x:27:username,username1
然后该 username 用户提升到 sudo 组(默认 sudo 组应该在 /etc/sudoers 中配置好权限)即可使用 sudo 命令。
使用 sudo 提升权限执行命令
要用提升的权限执行命令,只需要在命令前加上 sudo
,如下所示:
sudo cat /etc/passwd
当你执行这个命令时,它会询问用户 einverne 的密码,而不是 root 用户的密码。
使用 sudo 以其他用户身份执行命令
除此之外,我们可以使用 sudo
以另一个用户身份执行命令。例如,在下面的命令中,用户 einverne 以用户 demo 的身份执行命令:
sudo -u demo whoami
[sudo] password for einverne:
demo
内置命令行为
sudo
的一个限制是 —— 它无法使用 Shell 的内置命令。例如, history 记录是内置命令,如果你试图用 sudo
执行这个命令,那么会提示如下的未找到命令的错误:
sudo history
[sudo] password for einverne:
sudo: history: command not found
为了克服上述问题,我们可以访问 root shell,并在那里执行任何命令,包括 Shell 的内置命令。
要访问 root shell, 执行下面的命令:
sudo bash
执行完这个命令后——您将观察到提示符变为井号(#)。
技巧
这里将列举一些常用的 sudo 小技巧,可以用于日常任务。
以 sudo 用户执行之前的命令
让我们假设你想用提升的权限执行之前的命令,那么下面的技巧将会很有用:
sudo !4
上面的命令将使用提升的权限执行历史记录中的第 4 条命令。
在 Vim 里面使用 sudo 命令
很多时候,我们编辑系统的配置文件时,在保存时才意识到我们需要 root 访问权限来执行此操作。因为这个可能让我们丢失我们对文件的改动,我们可以在 Vim 中使用下面的命令来解决这种情况:
:w !sudo tee %
上述命令中:
- 冒号 (:) 表明我们处于 Vim 的退出模式
- 感叹号 (!) 表明我们正在运行 shell 命令
sudo
和 tee 都是 shell 命令- 百分号 (%) 表明从当前行开始的所有行
使用 sudo 执行多个命令
至今我们用 sudo
只执行了单个命令,但我们可以用它执行多个命令。只需要用分号 (;) 隔开命令,如下所示:
sudo -- bash -c 'pwd; id;'
上述命令中
- 双连字符 (–) 停止命令行切换
- bash 表示要用于执行命令的 shell 名称
- -c 选项后面跟着要执行的命令
查看 sudo 可以使用的命令
使用 -l
参数可以用来查看当前用户可执行的 sudo 命令
sudo -l
运行 sudo 命令时免去输入密码
当第一次执行 sudo
命令时,它会提示输入密码,默认情形下密码会被缓存 15 分钟。可以使用 NOPASSWD 关键字来禁用密码认证:
# User privilege specification
username ALL=(ALL) NOPASSWD:ALL 单独配置一个用户
# Allow members of group sudo to execute any command
%sudo ALL=(ALL) NOPASSWD:ALL 配置一组用户
解释一下该文件可以发现,每一行定义了一个配置,用户组需要使用 %
来区分。
限制 sudo 用户执行某些命令
为了提供受控访问,我们可以限制 sudo
用户只能执行某些命令。例如,下面的行只允许执行 echo 和 ls 命令 。
einverne ALL=(ALL) NOPASSWD: /bin/echo /bin/ls
深入了解 sudo
让我们进一步深入了解 sudo
命令。
ls -l /usr/bin/sudo
-rwsr-xr-x 1 root root 145040 Jun 13 2017 /usr/bin/sudo
如果仔细观察文件权限,则发现 sudo
上启用了 setuid 位。当任何用户运行这个二进制文件时,它将以拥有该文件的用户权限运行。在所示情形下,它是 root 用户。
为了显示这一点,我们可以使用 id 命令,如下所示:
id
uid=1002(einverne) gid=1002(einverne) groups=1002(einverne)
当我们不使用 sudo
执行 id 命令时,将显示用户 einverne 的 id。
sudo id
uid=0(root) gid=0(root) groups=0(root)
但是,如果我们使用 sudo
执行 id 命令时,则会显示 root 用户的 id。
reference
- https://www.networkworld.com/article/3236499/linux/some-tricks-for-using-sudo.html
- http://linux.cn/article-9559-1.html