Linux是一个多用户多任务的操作系统,往往会有多个用户共享系统。为了安全起见,需要通过useradd创建一些非root用户,只让他们拥有不完整的权限;如有必要,以提升的权限执行。sudo就是为了解决这个需求:这些非root用户不需要知道root密码,他们可以升级到root,执行一些root可以执行的命令。执行sudo-u将允许当前用户升级为的身份,然后执行以下,即使最初需要root权限。当权限提升到的身份时,命令以的身份执行,所以创建的文件默认属于的用户。因此,当userB执行以下命令时:sudo-uuserAtouch/tmp/belong-to-who.tmp创建的/tmp/belong-to-who.tmp文件属于用户userA。如果没有-u,默认使用root用户,而sudo大部分时候是为了升级为root,所以-u可以省略为:sudo注意:执行sudo时,输入passwordfor是当前用户的密码,而不是的密码。sudo-u与su-对比:前者需要输入当前用户的密码,升级为身份后返回当前用户执行命令;后者是输入目标用户的密码,切换到目标用户。赋予用户sudo操作权限关于linux用户和用户组管理的知识点本文不讨论。比如useradd、usermod、passwd、groupadd等命令不熟悉的可以移步链接,里面有详细的解释。通过useradd添加的用户没有sudo权限。在ubuntu/centos等系统中,需要将用户加入admin组、wheel组或sudo组。以root用户执行以下命令将用户添加到wheel/admin/sudo组:usermod-a-Gwheel如果提示wheel组不存在,需要先创建组:groupaddwheel使用公式说明/etc/sudoers的内容sudo的权限控制可以在/etc/sudoers文件中查看。如果要控制某个用户(或某组用户)只能在root权限下执行某些命令,或者允许某些用户不输入密码使用sudo,就需要知道这个文件。一般来说,如果通过cat/etc/sudoers命令查看文件,会看到如下几行代码:rootALL=(ALL:ALL)ALL%wheelALL=(ALL)ALL%sudoALL=(ALL:ALL)ALL编辑/etc/sudoers文件的代码公式可以概括为:授权用户/组host=[(切换到哪些用户或组)][是否需要密码验证]command1,command2,...every[]中的内容可以省略;命令与命令之间用逗号隔开;为方便说明,公式各部分称为字段1-字段5:授权用户/组host=[(切换到哪些用户或组)][是否需要密码验证]Command1,Command2,...字段1字段2=[(字段3)][字段4]字段5、字段3和字段4可以省略。在上面的默认示例中,不以%符号开头的“字段1”表示“要授权的用户”,例如示例中的root;以%符号开头的表示“要授权的组”,例如示例组中的%wheel和%sudo组。“Field2”表示允许登录的主机,ALL表示全部;如果此字段不是ALL,则表示授权用户只能在某些机器上登录此服务器执行sudo命令。例如:jackmycomputer=/usr/sbin/reboot,/usr/sbin/shutdown表示:普通用户jack在主机(或主机组)mycomputer上,可以通过sudo执行reboot和shutdown命令。“字段3”和“字段4”被省略。如果省略“Field3”,则相当于(root:root),表示可以通过sudo提升权限到root;如果是(ALL)或者(ALL:ALL),表示可以提升权限到(任意用户:任意用户组)。请注意,如果不省略“Field3”,则必须将其括在()双括号中。这样就可以区分是省略了“Field3”还是省略了“Field4”。“字段4”的可能值为NOPASSWD:。注意冒号:在NOPASSWD之后。表示执行sudo时不需要输入密码。例如:lucyALL=(ALL)NOPASSWD:/bin/useradd表示:普通用户lucy可以在任何主机上通过sudo执行/bin/useradd命令,不需要输入密码。又如:peterALL=(ALL)NOPASSWD:ALL表示:普通用户peter可以在任何主机上通过sudo执行任何命令,不需要输入密码。“字段5”是以逗号分隔的一系列命令,这些命令是授权给用户的操作;ALL表示允许所有操作。大家可能已经注意到,命令都使用了绝对路径,这是为了避免在目录下执行同名命令,造成安全隐患。如果您以以下不安全的格式编写授权:lucyALL=(ALL)chown,chmod,useradd那么用户可能会创建自己的程序,也命名为userad,并将其放在他的本地路径中,在此这样,他就可以使用root来执行这个“名为useradd的程序”。这是相当危险的!命令的绝对路径可以通过which命令查看:比如whichuseradd可以查看命令useradd的绝对路径:/usr/sbin/useradd公式还需要展开例1:papiALL=(root)NOPASSWD:/bin/chown,/usr/sbin/useradd意思是:用户papi可以在所有可能的主机上在root下执行/bin/chown而无需输入密码;但是需要运行/usr/sbin/useradd命令密码。这是因为NOPASSWD:只影响它之后的第一个命令:Command1。上面给出的公式只是一个简化版本,完整的公式如下:authorizeduser/grouphost=[(towhichusersorgroupstoswitchto)][是否需要密码验证]命令1,[(字段3)][字段4]命令2,...在有sudo操作的用户下,执行sudo-l查看允许还是禁止用户运行命令。通配符和取消命令示例2:papiALL=/usr/sbin/*,/sbin/*,!/usr/sbin/fdisk用示例2来说明通配符*的用法,加上!命令前表示取消命令。这个例子的意思是:用户papi可以在所有可能的主机上运行/usr/sbin和/sbin目录下的所有程序,fdisk除外。开始编辑“你说了那么多,但实际上,我要编辑/etc/sudoers文件,系统提示我没有权限,怎么办?”这是因为/etc/sudoers的内容非常敏感,文件是只读的。因此,在编辑此文件之前,请确保您知道自己在做什么。强烈建议通过visudo命令修改该文件。如果配置错误,会有提示。但是系统文档推荐的方法不是直接修改/etc/sudoers文件,而是将修改写在/etc/sudoers.d/目录下的文件中。如果使用这种方式修改sudoers,需要在/etc/sudoers文件的最后一行添加#includedir/etc/sudoers.d行(默认已经存在):#includedir/etc/sudoers.d注意#includedir这里的说明是一个整体,前面的#不能丢,不是注释,#后面不能有空格。/etc/sudoers.d/目录中不以~符号结尾或不包含.sign会被解析成/etc/sudoers的内容。文档是这样说的:#这将导致sudo读取和解析/etc/sudoers.d#目录中不以“~”结尾或不包含“.”的任何文件。character.#注意sudoers.d目录中必须至少有一个文件(这个#一个就可以),并且该目录中的所有文件都应该是模式0440.#还要注意,因为sudoers的内容可能有很大差异,所以没有尝试在升级时将此指令添加到现有的sudoers文件中。#最后,请注意,使用visudo命令是推荐的方式#来更新sudoers内容,因为它可以防止许多故障模式。什么都不会显示——甚至连普通的星号也不显示。有办法解决这个问题。打开/etc/sudoers文件并找到以下行:Defaultsenv_reset更改为:Defaultsenv_reset,pwfeedback更改sudo会话时间sudo命令可以运行多次。但是过一会儿,sudo命令会再次询问您的密码。默认为15分钟,可以调整。只需添加timestamp_timeout=minutes。时间以分钟为单位,-1表示永不过期,但强烈不推荐。比如我想把时间延长到1小时,我还是打开/etc/sudoers文件,找到下面一行:Defaultsenv_reset改为:Defaultsenv_reset,pwfeedback,timestamp_timeout=60