导读 | sudo 表示 “superuser do”,它允许已验证的用户以其他用户的身份来运行命令。其他用户可以是普通用户或者超级用户。 |
sudo 表示 “superuser do”,它允许已验证的用户以其他用户的身份来运行命令。其他用户可以是普通用户或者超级用户。然而,大部分时候我们用它来提权运行命令,以替代直接使用 root 用户的操作。sudo 命令与安全策略配合使用,安全策略可以通过文件 /etc/sudoers 来配置。其安全策略具有高度可拓展性,支持插件扩展。默认情况下 /etc/sudoers 是不能被任何人直接编辑的,因为它的权限是 440,虽然也可以对其赋予写权限后再编辑,但推荐使用 visudo 命令编辑该文件。
简述其使用工作流程和配置文件配置!
sudo 会读取和解析 /etc/sudoers 文件,查找调用命令的用户及其权限。
然后提示调用该命令的用户输入密码,或者也可以通过 NOPASSWD 标志来跳过密码验证。
之后,sudo 创建一个子进程,调用 setuid() 来切换到目标用户。
最好,它会在上述子进程中执行参数给定的 shell 或命令。
USER/GROUP HOST=(USER[:GROUP]) [NOPASSWD:] COMMANDS USER/GROUP: 表示需要被授权的用户或者组;如果是组则需要以 % 开头 HOST: 表示允许从哪些主机登录的用户运行 sudo 命令;ALL 表示允许从任何终端、机器访问 (USER[:GROUP]): 表示使用 sudo 可切换的用户或者组,组可以不指定;ALL 表示可以切换到系统的所有用户 NOPASSWD: 如果指定,则该用户或组使用 sudo 时不必输入密码 COMMANDS: 表示运行指定的命令;ALL 表示允许执行所有命令 #?允许?sudo?组执行所有命令 %sudo?ALL=(ALL:ALL)?ALL #?允许用户执行所有命令,且无需输入密码 escape?ALL?=(ALL)?NOPASSWD:?ALL #?仅允许用户执行?echo,?ls?命令 escape?ALL?=(ALL)?NOPASSWD:?/bin/echo?/bin/ls #?运行本机的用户执行关机命令 escape?localhost=/sbin/shutdown?-h?now #?允许?users?用户组中的用户像?root?用户一样使用?mount、unmount、chrom?命令 %users?ALL=/sbin/mount?/mnt/cdrom,?/sbin/umount?/mnt/cdrom
#?指定用户尝试输入密码的次数,默认值为3 Defaults?passwd_tries=5 #?设置密码超时时间,默认为?5?分钟 Defaults?passwd_timeout=2 默认?sudo?询问用户自己的密码,添加?targetpw?或?rootpw?配置可以让?sudo?询问?root?密码 Defaults?targetpw #?指定自定义日志文件 Defaults?logfile="/var/log/sudo.log" #?要在自定义日志文件中记录主机名和四位数年份,可以加上?log_host?和?log_year?参数 Defaults?log_host,?log_year,?logfile="/var/log/sudo.log" #?保持当前用户的环境变量 Defaults?env_keep?+=?"LANG?LC_ADDRESS?LC_CTYPE?COLORS?DISPLAY?HOSTNAME?EDITOR" Defaults?env_keep?+=?"ftp_proxy?http_proxy?https_proxy?no_proxy" #?安置一个安全的?PATH?环境变量 Defaults?secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
主要介绍使用 sudo 相关命令的使用技巧和问题处理方式!
当我使用 visudo 命令的时候,它总是用 nano 编辑器打开它,对应平时习惯使用 vi 或者 vim 的用户来说,显得有些别扭,以及操作不够自如。所以,如何更好的将 visudo 编辑器从 nano 更改为 vim 就变得非常重要了。
最佳的解决办法,就是调用命令,永久的将终端的编辑器更换成为 vim 编辑器,一劳永逸。我们只需要执行如下命令,输入自己需要的编辑器序号并按下回车键即可。下次执行 visudo 命令的时候,就会使用 vim 编辑器打开文件。
#?因为/etc/sudoers普通用户无法打开和使用 $?sudo?update-alternatives?--config?editor There?are?4?choices?for?the?alternative?editor?(providing?/usr/bin/editor). Selection????Path????????????????Priority???Status ------------------------------------------------------------ *?0????????????/bin/nano????????????40????????auto?mode 1????????????/bin/ed?????????????-100???????manual?mode 2????????????/bin/nano????????????40????????manual?mode 3????????????/usr/bin/vim.basic???30????????manual?mode 4????????????/usr/bin/vim.tiny????10????????manual?mode Press?enter?to?keep?the?current?choice[*],?or?type?selection?number:?3
其次的解决方法,就是通过环境变量修改当前终端的默认编辑器。
#?在.zshrc或.profile文件中 $?export?EDITOR=vim; #?希望执行对visudo生效 $?sudo?EDITOR=vim?visudo #?或者修改/etc/sudoers文件的默认编辑器 Defaults?editor=/usr/bin/vim
在使用 vim 的时候,当以普通用户打开一个只有 root 用户才有权限操作的文件时,在编辑完成之后保存时发现,这个文件没有权限修改。好不容易把文件编辑完了,却无法保存,就只能放弃,然后退出,再以 root 权限打开,重新编辑,是在痛苦!那有没有好的方法来解决这个问题呢?咳咳咳,肯定是有的。
#?Vim命令模式下执行即可强制保存
#?w:?表示保存文件
#?!:?表示执行外部命令
#?tee:?表示把数据重定向到给定文件和屏幕上
#?%:?在执行外部命令时,%会扩展成当前文件名
:w?!sudo?tee?%
上述方式非常完美的解决了不能保存只读文件的问题,但毕竟命令还是有些长,为了避免每次输入一长串的命令,可以将它映射为一个简单的命令加到 .vimrc 中。这样,简单的运行 :w!! 即可,命令后半部分 > /dev/null 作用为显式的丢掉标准输出的内容。
"?Allow?saving?of?files?as?sudo?when?I?forgot?to?start?vim?using?sudo.
cmap?w!!?w?!sudo?tee?>?/dev/null?%
Sudoedit 是一个内置命令,允许用户安全地编辑文件。根据 sudo 手册页,sudoedit 等效于使用 -e 命令行选项执行 sudo。
那么这个命令会做什么呢,它会首先创建你要编辑的文件的临时副本。然后,命令将搜索 SUDO_EDITOR,VISUAL 和 EDITOR 环境变量(按此顺序),以确定应调用哪个编辑器来打开刚刚创建的临时副本。用户完成修改工作后,更改将复制回原始文件。
#?Sudo命令手册页 -e,?--edit Edit?one?or?more?files?instead?of?running?a?command.?In?lieu?of?a?path?name, the?string?"sudoedit"?is?used?when?consulting?the?security?policy.?If?the?user is?authorized?by?the?policy,?the?followingsteps?are?taken: 1.?Temporary?copies?are?made?of?the?files?to?be?edited?with the?owner?set?to?the?invoking?user. 2.?The?editor?specified?by?the?policy?is?run?to?edit?the temporary?files.?The?sudoers?policy?uses?the SUDO_EDITOR,?VISUAL?and?EDITOR?environment?variables?(in that?order).?If?none?of?SUDO_EDITOR,?VISUAL?or?EDITOR are?set,?the?first?program?listed?in?the?editor sudoers(5)?option?is?used. 3.?If?they?have?been?modified,?the?temporary?files?are copied?back?to?their?original?location?and?the?temporary versions?are?removed. If?the?specified?file?does?not?exist,?it?will?be?created.?Note?that?unlike?most commands?run?by?sudo,?the?editor?is?run?with?the?invoking?user?is?environment unmodified.?If,?for?some?reason,?sudo?is?unable?to?update?a?file?with?its?edited version,?the?user?will?receive?a?warning?and?the?edited?copy?will?remain?in?a temporary?file.
其中 sudo 命令是权限委派的命令,在生产环境中是非常常用的,默认情况下 sudo 命令会话时间是在 15 分钟。要设置 sudo 密码超时的值,需要使用 passwd_timeout 参数进行设置。
可以以分钟设置为你所需的任何时间,它会在超时之前一直等待。如果要为每个执行的 sudo 命令弹出密码提示,你也可以将时间设置为 0,或者通过设置值 -1 永久禁用密码提示。
#?设置timeout时间
#?意味着sudo密码提示将会在用户使用20分钟后过期
Defaults????????env_reset,timestamp_timeout=20
如何我们管理的服务器,开发或者其他人员需要登录该服务器,进行环境调试或者问题复现等情况。这时,就需要我们给对应的用户开通登录的访问权限。但是如果我们直接编辑 /etc/sudoers 文件的话,之后当对方使用完成之后我就还需要手动进行清理。如果我们忘记的话,该开发或者其他人员将一直可以登录该服务器,会有一定程度的安全问题。
不幸的是,对应临时授权的话,/etc/sudoers 文件中没有对应的配置,可以对某个用户或者用户组进行指定范围的时间授权。当用户到达指定时间点之后,将拒绝该用户再次进行登录了。对应此种情况,我们可以通过 crontab 定时任务与 /etc/sudoers.d 目录的机制可以完美的解决上述问题。
我们通过定时任务的定时执行目录,来定时刷掉 /etc/sudoers.d/ 目录下的用户或者用户组的授权配置文件。比如,我们需要定时每日刷掉今日临时授权的用户或者用户,可以在 /etc/cron.daily 目录下面创建用于删除 /etc/sudoers.d/ 目录的 rm -rf 命令,之后在固定的时间会自动删除。对应授权用户,我们使用在 /etc/sudoers.d/ 目录下创建单独的配置文件,而不是直接修改 /etc/sudoers 文件。
#?Crontab有多种定时机制
#?下述分别表示每天、每时、每月、每周定时执行
$?ls?-dl?/etc/cron.*?|?grep?-v?cron.d$
drwxr-xr-x?2?root?root?4096?May?15?06:18?/etc/cron.daily
drwxr-xr-x?2?root?root?4096?Feb?14??2019?/etc/cron.hourly
drwxr-xr-x?2?root?root?4096?Feb?14??2019?/etc/cron.monthly
drwxr-xr-x?2?root?root?4096?Jun?18?09:57?/etc/cron.weekly
#?创建单独的授权配置文件
$?ls?-lh?/etc/sudoers.d/
-r--r-----?1?root?root?666?Oct??6??2017?lisi
-r--r-----?1?root?root?958?Jan?18??2018?zhangsan
#?查看授权配置文件的内容
$?cat?/etc/sudoers.d/zhangsan
ALL?ALL?=?(root)?NOPASSWD:?zhangsan
我们日常在使用 sudo 命令的时候,常常会遇到,当切换用户之后,发现之前设置的环境变量怎么不见了呢?这是因为,我们执行 sudo 命令之后会切换用户,如果保留环境变量会有一定的安全问题,系统会默认重置环境变量为安全的环境变量。先前设置的变量都会失效,只有少数配置文件中指定的环境变量能够保存下来。
我们可以看一下 sudo 配置文件 /etc/sudoers 来找找作用原因。我们执行如下命令之后,可以看到如下输入(有可能和我这里的不一样)。其中 env_reset 表示默认会重置环境变量,因此我们自定义的变量会在 sudo 命令执行之后失效,也就不会正确获取变量值了。而 env_keep 则表示用于保留部分环境变量不被重置,需要保留的变量就写入双引号之中,可自行追加需要保留的变量。最后就是 secure_path 变量,其作用就是包含的路径将被当做 sudo 环境的 PATH 变量来使用。如果在 sudo 环境无法找到某些命令,那么可以将这些命令的路径加入该配置项之中。
$?sudo?sed?'/^#/d;/^$/d'?/etc/sudoers Defaults????env_reset Defaults????env_keep?=??"COLORS?IDSPLAY?HOSTNAME?HISTSIZE?LS_COLORS" Defaults????env_keep?+=?"MAIL?PS1?PS2?QTDIR?USERNAME?LANG?LC_ADDRESS" Defaults????secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
我们知道原因之后,就可以针对上述情况作出不用的处理方式,来解决 sudo 命令找不到环境变量的问题。
第一种解决方法,就是在使用的时候,使用 -E 参数。加上 -E 选项后,用户可以在 sudo 执行时保留当前用户已存在的环境变量,不会被 sudo 重置。另外,如果用户对于指定的环境变量没有权限,则会报错。需要注意的是,在内部测试机器中,安全性要求不高的情况下使用。
$?sudo?sudo?-E
第二种解决方法,就是修改 sudo 配置文件。可以通过修改 /etc/sudoers 文件的 env_keep 和 secure_path 配置项,来指定 sudo 环境中需要保留的环境变量和路径。当然,我们也可以把配置文件的变量 !env_reset 给去掉,这样就不会有限制了。
$?sudo?vim?/etc/sudoers Defaults?!env_reset