Linux sudo
2019-12-16 21:40:56 阿炯

sudo命令用来以其他身份来执行命令,预设的身份为root。在/etc/sudoers中设置了可执行sudo指令的用户,若其未经授权的用户企图使用sudo,则会发出警告的邮件给管理员。用户使用sudo时,必须先输入密码,之后有5分钟的有效期限,超过期限则必须重新输入密码。它的全称意思是超级用户做的(super user do!)。Linux sudo主要是用于把部分权限分给特定的用户使用,同时又限定特定用户不能超过权限使用范围。sudo针对单个命令授予临时权限,并记录日志。只有root用户才能打开的配置文件/etc/sudoers。

配置sudo必须通过编辑它的配置文件(/etc/sudoers),而且只有超级用户才可以修改它,还必须使用visudo编辑。之所以使用visudo有两个原因,一是它能够防止两个用户同时修改它;二是它也能进行有限的语法检查。所以即使只有你一个超级用户,也最好用visudo来检查一下语法。

切换到 root 账号,输入命令 visudo,就会默认使用 vi 打开 /etc/sudoers。仿照 root ALL=(ALL) ALL 在下方输入 [username] ALL=(ALL) ALL 即添加完成。
user ALL=(ALL) ALL
username   ALL=(ALL)       ALL // 允许用户sudo访问权
%wheel     ALL=(ALL)       ALL // 允许wheel组的所有用户sudo访问权

输入的是错误的(ALL 大小写),当尝试保存的时候,visudo 给了提示。

visudo 提示
输入 e 后重新编辑,保存成功。

每次都需要输入密码的话,有些麻烦,下面修改文件取消密码。切换到 root 账号,输入 visudo,如下修改:
user ALL=(ALL)NOPASSWD: ALL

修改完成后,再切换到 user 账号进行测试,再次使用 sudo 的时候,没有提示输入密码即执行成功。

配置sudo的2种方式

1、visudo  编辑
visudo: 编辑sudo配置文件(相当于 vi /etc/sudoers,但是不建议用,注意检查语法)

visudo -c 检查语法命令,有报错可能导致系统起不来,所以编辑之前需要备份,编辑后最好检查一下用法。

visudo编辑/etc/sudoers条目格式:
who    which_hosts=(runas)    [TAG:]command

简单的解释:某个用户(who)能以另一个用户的身份(runas)通过那些(远程来的)主机(which_hosts)执行什么命令(command)。

who、which_hosts、runas、command支持别名(相当于组的概念),别名必须全部且只能使用大写英文字母的组合。

who的别名规范:User_Alias  USERSALIAS = ......(.....可以是用户的用户名、%组名、其他用用户的别名(也就是嵌入)

which_hosts的别名规范:Host_Alias  HOSTALIAS = .....(....可以是主机名、hostIP、network/netmask)

Runas_Alias的别名规范:EXEUSERS = .....(.....可以是用户名、%组名、其他Runas别名)

Cmnd_Alias的别名规范: CMD = .....(.....可以是命令的绝对路径、目录(此目录内的所有命令)、其它事先定义过的命令别名)

TAG主要有NOPASSWD(不要用户输入密码)、PASSWD(用户输入密码;默认是要输入密码,输入密码为who的密码。

2、vi /etc/sudoers,但是visudo功能更强大
Syntax:    user    MACHINE=COMMANDS      # sudo 语法
root    ALL=(ALL)       ALL    #  (All)表示允许用户以哪个用户的权限做事情
omd     ALL=(ALL)       ALL    #  omd用户在任何机器上,可以只需任何用户的任何命令 == root用户
omd     ALL=(ALL)     NOPASSWD: ALL    #  免密而且omd用户在任何机器上,可以只需任何用户的任何命令
freeoa     ALL=(ALL)   /bin/cp,/bin/touch    # 只允许freeoa用户只需root用户的cp,touch命令

取消sudo必须需要tty才能执行的限制

编辑 /etc/sudoers,找到'Defaults    requiretty',然后注释掉这行,sudo命令执行日志记录在/var/log/secure文件中。

注:/etc/sudoers 这个是一个权限很小的文件(440),此文件建议不要以vim等命令来编辑,最好直接用命令visudo。

sudo常用参数:
-l : 登录用户下面,执行sudo -l  显示当前用户有哪些权限
-k:删除/var/db/sudo/下面对应的时间戳的信息,下次执行sudo需要输入当前用户的密码
    --> 系统默认也是5分钟失效
    --> 配置免密是另一种情况 NOPASSWD: ALL远程sudo(有条件限制的)

sudo原理

普通用户运行sudo -> 检查/var/db/sudo/下是否有时间戳文件(执行成功后会创建,且免密5分钟),并检查是否已经过期
未过期 -> 检查/etc/sudoers里面是否配置了运行sudo和执行相应命令的权限
    ->有权限 ->执行命令并且返回结果 ->退出
    ->无权限 ->退出

过期 -> 输入当前用户自己的口令 ->检查/etc/sudoers里面是否配置了运行sudo和执行相应命令的权限
    ->有权限 ->执行命令并且返回结果 ->退出
    ->无权限 ->退出

sudo配置的注意事项:
1.命令别名下的成员必须是文件或者是目录的绝对路径

2.别名是包含大写字母,数字,下划线,如果是字母就必须全部大写

3.一个别名下有多个成员,成员与成员之间必须使用逗号分隔,且成员必须有效的存在

4.别名成员受Host_Alias,User_Alias,Cmnd_Alias,Runas_Alias别名类型制约,定义什么类型的别名,就要有什么类型的成员匹配

5.别名规则是每行算一个规则,如果一个别名规则一行容不下是,可以通过“\”来续行

6.指定切换的用户要用()括起来,如果省略括号,默认是root   

7.如果不需要输入密码可以输入NOPASSWD:ALL

8.禁止的命令可以通过!来进行限制,根据测试,先执行后面的命令,所以禁止的命令必须放在允许执行的命令的后面

9.用户组前面必须用%号

10.所有的授权ALL字符都必须是大写

11.允许执行的命令都是有顺序的,命令的顺序是从后向前生效,所以禁止的命令尽量向后放

sudo管理的2个文件
/var/db/sudo/
/etc/sudoers

常用选项

-b:在后台执行
-h:显示帮助
-H:将HOME环境设置为新身份的HOME环境
-i:以目标用户登录一个shell
-k:结束密码有效期
-l:列出当前用户可执行的命令
-p:改变询问密码的提示符号
-s <shell> 执行指定的Shell
-u <user> 以指定用户执行命令或编辑文件
-v:延长密码有效期5分钟
-V:显示sudo版本信息

一些选项的解析

像任何命令一样,sudo也有几个不错的选项,让sudo处理更多情况:
sudo -b:将在后台运行命令。这对那些运行中显示大量实时输出的命令非常有用。
sudo -s:将运行使用提升权限指定的外壳,让您显示#提示符(不要忘了退出)
sudo su - 会让你成为root用户,并加载自定义用户环境变量。


sudo vs su

su 命令的主要作用是让你可以在已登录的会话中切换到另外一个用户,换言之,这个工具可以让你在不登出当前用户的情况下登录为另外一个用户。su 命令经常被用于切换到超级用户或 root 用户(因为在命令行下工作,经常需要 root 权限),但是 - 正如前面所提到的 - su 命令也可以用于切换到任意非 root 用户。一般 su 命令需要输入目标用户的密码,在输入正确的密码之后,su 命令会在终端的当前会话中打开一个子会话。

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

su 命令手册页很清楚地说明了这一点:
    可选参数 - 可提供的环境为用户在直接登录时的环境。

因此会觉得使用 su - 登录更有意义。但是, su 命令也是有用的,那么大家可能会想知道它在什么时候用到。以下内容摘自 ArchLinux wiki 网站 - 关于 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]

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

sudo 和 su 命令之间的区别

关于密码

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

很明显,就安全而言,sudo 命令更好。例如,考虑到需要 root 访问权限的多用户使用的计算机。在这种情况下,使用 su 意味着需要与其他用户共享 root 用户密码,这显然不是一种好习惯。此外,如果要撤销特定用户的超级用户/root 用户的访问权限,唯一的办法就是更改 root 密码,然后再告知所有其他用户新的 root 密码。而使用 sudo 命令就不一样了,你可以很好的处理以上的两种情况。鉴于 sudo 命令要求输入的是其他用户自己的密码,所以不需要共享 root 密码。同时想要阻止特定用户访问 root 权限,只需要调整 sudoers 文件中的相应配置即可。

默认行为

两个命令之间的另外一个区别是其默认行为。sudo 命令只允许使用提升的权限运行单个命令,而 su 命令会启动一个新的 shell,同时允许使用 root 权限运行尽可能多的命令,直到明确退出登录。因此,su 命令的默认行为是有风险的,因为用户很有可能会忘记他们正在以 root 用户身份进行工作,于是无意中做出了一些不可恢复的更改(例如:对错误的目录运行 rm -rf 命令!)。关于为什么不鼓励以 root 用户身份进行工作的详细内容,请参考这里http://askubuntu.com/questions/16178/why-is-it-bad-to-login-as-root。

日志记录

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

灵活性

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

sudo su

大概是因为使用 su 命令或直接以 root 用户身份登录有风险,所以一些 Linux 发行版(如Ubuntu)默认禁用 root 用户帐户,鼓励用户在需要 root 权限时使用 sudo 命令;然而还是可以成功执行 su 命令,而不用输入 root 用户的密码。运行以下命令:sudo su

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

注意:如果你想在系统中启用 root 用户帐户就必须手动设置 root 用户密码,可以使用以下命令:
sudo passwd root


配置文件示例

## Sudoers allows particular users to run various commands as
## the root user, without needing the root password.
## 该文件允许特定用户像root用户一样使用各种各样的命令,而不需要root用户的密码
##
## Examples are provided at the bottom of the file for collections
## of related commands, which can then be delegated out to particular
## users or groups.
## 在文件的底部提供了很多相关命令的示例以供选择,这些示例都可以被特定用户或
## 用户组所使用
##
## This file must be edited with the 'visudo' command.
## 该文件必须使用"visudo"命令编辑
 
## Host Aliases
## Groups of machines. You may prefer to use hostnames (perhaps using
## wildcards for entire domains) or IP addresses instead.
## 对于一组服务器,你可能会更喜欢使用主机名(可能是全域名的通配符)
## 、或IP地址,这时可以配置主机别名
# Host_Alias     FILESERVERS = fs1, fs2
# Host_Alias     MAILSERVERS = smtp, smtp2
 
## User Aliases
## These aren't often necessary, as you can use regular groups
## (ie, from files, LDAP, NIS, etc) in this file - just use %groupname
## rather than USERALIAS
## 这并不很常用,因为你可以通过使用组来代替一组用户的别名
# User_Alias ADMINS = jsmith, mikem
 
## Command Aliases
## These are groups of related commands...
## 指定一系列相互关联的命令(当然可以是一个)的别名,通过赋予该别名sudo权限,
## 可以通过sudo调用所有别名包含的命令,下面是一些示例
 
## Networking 网络操作相关命令别名
# Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial<br>#, /sbin/iwconfig, /sbin/mii-tool
 
## Installation and management of software 软件安装管理相关命令别名
# Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
 
## Services 服务相关命令别名
# Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig
 
## Updating the locate database 本地数据库升级命令别名
# Cmnd_Alias LOCATE = /usr/bin/updatedb
 
## Storage 磁盘操作相关命令别名
# Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
 
## Delegating permissions 代理权限相关命令别名
# Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp
 
## Processes 进程相关命令别名
# Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall
 
## Drivers 驱动命令别名
# Cmnd_Alias DRIVERS = /sbin/modprobe
 
# Defaults specification
 
#
# Disable "ssh hostname sudo <cmd>", because it will show the password in clear.
# You have to run "ssh -t hostname sudo <cmd>".
# 一些环境变量的相关配置,具体情况可见man soduers
Defaults    requiretty
##设为默认的目标用户,69行是系统自带的,是对所有用户的默认,如果设sunmeng为默认目标用户,则语法为:Defaults:foobar runas_default=rene (冒号必不可少)
Defaults    env_reset
 
Defaults    env_keep =  "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"
Defaults    env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"
Defaults    env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"
Defaults    env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"
Defaults    env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"
 
Defaults    secure_path = /sbin:/bin:/usr/sbin:/usr/bin
 
## Next comes the main part: which users can run what software on
## which machines (the sudoers file can be shared between multiple systems).
## 下面是规则配置:什么用户在哪台服务器上可以执行哪些命令(sudoers文件可以在多个系统上共享)
## Syntax(语法):
##
## user    MACHINE=COMMANDS 用户 登录的主机=(可以变换的身份) 可以执行的命令
##
## The COMMANDS section may have other options added to it.
## 命令部分可以附带一些其它的选项
##
## Allow root to run any commands anywhere
## 允许root用户执行任意路径下的任意命令
root    ALL=(ALL)     ALL
##第一个ALL是指网络中的主机,我们后面把它改成了主机名。第二个括号里的ALL是指目标用户,也就是以谁的身份去执行命令。最后一个ALL当然就是指命令名了。
 
## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
## 允许sys中户组中的用户使用NETWORKING等所有别名中配置的命令
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS
 
## Allows people in group wheel to run all commands
## 允许wheel用户组中的用户执行所有命令
%wheel    ALL=(ALL)    ALL
 
## Same thing without a password
## 允许wheel用户组中的用户在不输入该用户的密码的情况下使用所有命令
# %wheel    ALL=(ALL)    NOPASSWD: ALL
## Allows members of the users group to mount and unmount the cdrom as root
## 允许users用户组中的用户像root用户一样使用mount、unmount、chrom命令
# %users  ALL=/sbin/mount /mnt/cdrom, /sbin/umount /mnt/cdrom
## Allows members of the users group to shutdown this system
## 允许users用户组中的用户关闭localhost这台服务器
# %users  localhost=/sbin/shutdown -h now
 
## Read drop-in files from /etc/sudoers.d (the # here does not mean a comment)
## 读取放置在/etc/sudoers.d/文件夹中的文件(此处的#不意味着这是一个声明)
#includedir /etc/sudoers.d


给普通用户使用sudo的授权

使用打开sudoers的专属命令visudo,添加如下相关配置

## Allow root to run any commands anywhere
## 允许root用户执行任意路径下的任意命令
root    ALL=(ALL)     ALL
##第一个ALL是指网络中的主机,我们后面把它改成了主机名。第二个括号里的ALL是指目标用户,也就是以谁的身份去执行命令。最后一个ALL当然就是指命令名了。
tset        ALL=(ALL)        ALL

## Allows members of the 'sys' group to run networking, software,
## service management apps and more.
## 允许sys中户组中的用户使用NETWORKING等所有别名中配置的命令
# %sys ALL = NETWORKING, SOFTWARE, SERVICES, STORAGE, DELEGATING, PROCESSES, LOCATE, DRIVERS

## Allows people in group wheel to run all commands
## 允许wheel用户组中的用户执行所有命令
%wheel    ALL=(ALL)    ALL
%testgroup      ALL=(root)                  ALL

## Same thing without a password
## 允许wheel用户组中的用户在不输入该用户的密码的情况下使用所有命令
# %wheel    ALL=(ALL)    NOPASSWD: ALL
test        ALL=(root)        NOPASSWD:ALL


参考来源:
深入理解 sudo 与 su 之间的区别