Linux【5】-用户管理7-让渡用户权限(sudoers/sudo)

在很多情况下,在多人共管主机,某些用户请求执行某些需要 root 权限的命令或者干脆就是你忙不过来的时候,你就得让其他人获得 root 权限了。但将 系统的 root 密码告诉很多人显然不是一个好的选择,这往往成为悲剧事件的开端。那么我们该如何做呢,sudo 命令给我们提供了一个不需要 root 密码也能执 行 root 权限命令的途径。

sudo 命令允许规定的用户能够以在许可范围内以其他用户身份执行规定的命令。所以,通过 sudo 命令系统管理员可以分配给普通用户一些合理的“权利”, 让他们执行一些只有 root 或其他特许用户才能完成的任务,比如:运行一些像mount,halt,shutdown 之类的命令,或者编辑一些系统配置文件,像/etc/mtab, /etc/samba/smb.conf 等。这样以来,就不仅减少了 root 用户的登陆次数和管理时间,也提高了系统安全性。sudo 命令有以下特点:

  • sudo 命令能够限制指定用户在指定主机上运行某些命令。
  • sudo 命令可以提供日志,忠实地记录每个用户使用 sudo 命令做了些什么,并且能将日志传到中心主机或者日志服务器。
  • sudo 命令为系统管理员提供配置文件,允许系统管理员集中地管理用户的使用权限和使用的主机。它默认的存放位置是/etc/sudoers。
  • sudo 命令使用时间戳文件来完成类似“检票”的系统。当用户执行 sudo 命令并且输入密码后,用户获得了一张默认存活期为 5 分钟的“入场券”(默认值 可以在编译的时候改变)。超时以后,用户必须重新输入密码。

一、sudo命令

我们知道,使用 su 命令可以让普通用户切换到 root 身份去执行某些特权命令,但存在一些问题,比如说: 仅仅为了一个特权操作就直接赋予普通用户控制系统的完整权限; 当多人使用同一台主机时,如果大家都要使用 su 命令切换到 root 身份,那势必就需要 root 的密码,这就导致很多人都知道 root 的密码;

考虑到使用 su 命令可能对系统安装造成的隐患,最常见的解决方法是使用 sudo 命令,此命令也可以让你切换至其他用户的身份去执行命令。

相对于使用 su 命令还需要新切换用户的密码,sudo 命令的运行只需要知道自己的密码即可,甚至于,我们可以通过手动修改 sudo 的配置文件,使其无需任何密码即可运行。

sudo 命令默认只有 root 用户可以运行,该命令的基本格式为: [root@localhost ~]# sudo [-b] [-u 新使用者账号] 要执行的命令

常用的选项与参数:

-b  :将后续的命令放到背景中让系统自行运行,不对当前的 shell 环境产生影响。
-u  :后面可以接欲切换的用户名,若无此项则代表切换身份为 root 。
-l:此选项的用法为 sudo -l,用于显示当前用户可以用 sudo 执行那些命令。

【例 1】

[root@localhost ~]#  grep sshd /etc/passwd
sshd:x:74:74:privilege-separated SSH:/var/empty/sshd:/sbin.nologin
[root@localhost ~]#  sudo -u sshd touch /tmp/mysshd
[root@localhost ~]#  ll /tmp/mysshd
-rw-r--r-- 1 sshd sshd 0 Feb 28 17:42 /tmp/mysshd

本例中,无法使用 su - sshd 的方式成功切换到 sshd 账户中,因为此用户的默认 Shell 是 /sbin/nologin。这时就显现出 sudo 的优势,我们可以使用 sudo 以 sshd 的身份在 /tmp 目录下创建 mysshd 文件,可以看到,新创建的 mysshd 文件的所有者确实是 sshd。

【例 2】

[root@localhost ~]#  sudo -u vbird1 sh -c "mkdir ~vbird1/www; cd ~vbird1/www; \
>  echo 'This is index.html file' > index.html"
[root@localhost ~]#  ll -a ~vbird1/www
drwxr-xr-x 2 vbird1 vbird1 4096 Feb 28 17:51 .
drwx------ 5 vbird1 vbird1 4096 Feb 28 17:51 ..
-rw-r--r-- 1 vbird1 vbird1   24 Feb 28 17:51 index.html

这个例子中,使用 sudo 命令切换至 vbird1 身份,并运行 sh -c 的方式来运行一连串的命令。

前面说过,默认情况下 sudo 命令只有 root 身份可以使用,那么,如何让普通用户也能使用它呢?

解决这个问题之前,先给大家分析一下 sudo 命令的执行过程。sudo命令的运行,需经历如下几步: 当用户运行 sudo 命令时,系统会先通过 /etc/sudoers 文件,验证该用户是否有运行 sudo 的权限; 确定用户具有使用 sudo 命令的权限后,还要让用户输入自己的密码进行确认。出于对系统安全性的考虑,如果用户在默认时间内(默认是 5 分钟)不使用 sudo 命令,此后使用时需要再次输入密码; 密码输入成功后,才会执行 sudo 命令后接的命令。

显然,能否使用 sudo 命令,取决于对 /etc/sudoers 文件的配置(默认情况下,此文件中只配置有 root 用户)。所以接下来,我们学习对 /etc/sudoers 文件进行合理的修改。

二、修改 /etc/sudoers 文件

一开始系统默认仅有 root 可以执行 sudo 命令,我们需要通过修改/etc/sudoers 文件来让别的用户也能够执行 sudo 命令。

用 vi /etc/sudoers 打开/etc/sudoers 文件,在没有改动的情况下文件大约有 100 多行,在其中找到一行,如下所示:

## Allow root to run any commands anywhere
root ALL=(ALL) ALL #找到这一行
intern01 ALL=(ALL) ALL #添加这行
#表示 intern01 用户可以在任何地方(远程终端)登录,以任意用户身份执行任何命令
#第一列代表可使用sudo命令的用户名,这里是root ; 第二个字段表示登陆用户的来源主机名称,等号后面是可让渡权限的用户列表;第三列是用户可使用的命令列表

也可以只给部分权限:

## Allow root to run any commands anywhere
root ALL=(ALL) ALL #找到这一行
intern01 localhost=(root) /sbin/shutdown -h -5
#表示 intern01 用户可以在本地登录,以 root 用户身份执行/sbin/shutdown -5 now 这个命
令,命令得以绝对路径的方式指定

这样一个一个用户指定太过麻烦,也可以按用户组指定:

## Allow root to run any commands anywhere
root ALL=(ALL) ALL #找到这一行
%group_p 192.168.56.130=(root) /sbin/shutdown -h -5
#表示从属于 group_p 用户组的 用户可以在 192.168.56.130 主机上登录,以 root 用户身
份执行/sbin/shutdown -5 now 这个命令

事实上,我们甚至可以免除用户输入自己密码的步骤:

## Allow root to run any commands anywhere
root ALL=(ALL) ALL #找到这一行
%group_p 192.168.56.130=(root) NOPASSWD:/sbin/shutdown -h -5
#表示从属于 group_p 用户组的 用户可以在 192.168.56.130 主机上登录,以 root 用户身
份执行/sbin/shutdown -5 now 这个命令,并且无需输入用户密码
  • 虽然说如果 sudo 命令允许规定的用户能够以在许可范围内以其他用 户身份执行规定的命令,但是它最常还是用在让普通用户能够以 root 身份执行一些命令;
  • sudo 命令不带-u 选项,默认为切换到 root 用户身份,也即 “sudo fdisk ” 等价于“su –u root fdisk”

sudo 找不到命令

sudo有时候会出现找不到命令,而明明PATH路径下包含该命令,让人疑惑。其实出现这种情况的原因,主要是因为当 sudo以管理权限执行命令的时候,linux将PATH环境变量进行了重置,当然这主要是因为系统安全的考虑,但却使得sudo搜索的路径不是我们想要的PATH变量的路径,当然就找不到我们想要的命令了。两种方法解决该问题:

首先,都要打开sudo的配置文件:

sudo visudo

1.可以使用 secure_path 指令修改 sudoers 中默认的 PATH为你想要的路径。这个指令指定当用户执行 sudo 命令时在什么地方寻找二进制代码和命令。这个选项的目的显然是要限制用户运行 sudo 命令的范围,这是一种好做法。

2.将Defaults env_reset改成

Defaults !env_reset

取消掉对PATH变量的重置,然后在.bashrc中最后添加

alias sudo='sudo env PATH=$PATH' 

这样sudo执行命令时所搜寻的路径就是系统的PATH变量中的路径,如想添加其他变量也是类似。

具体案例:

运行一命令在普通用户下可行,切换到root用户依然可行,但在普通用户下使用sudo执行时,提示Command not found。

修改/etc/sudoers文件,找到类似下面的一行:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin  

将要执行的命令所在的目录添加到后面,即可,如:

Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin  

参考资料

个人公众号,比较懒,很少更新,可以在上面提问题,如果回复不及时,可发邮件给我: tiehan@sina.cn

Sam avatar
About Sam
专注生物信息 专注转化医学