Linux下我们经常使用的SSH远程连接到系统进行操作,而为了安全,一般使用的是非root用户连接,只有在必要的时候,我们才会使用sudo切换到root帐户下进行操作,以保证系统尽可能的安全和不被损坏。然而,在有的时候我们通过普通用户SSH连接到Linux的时候,使用sudo来执行身份切换的时候,系统会报错(以下是CentOS6.4下的报错):
对不起,用户 yourusername 不能在 CentOS 上运行 sudo。
## 如果直接运行命令sudo command,则是如下错误
yourusername 不在 sudoers 文件中。此事将被报告。
或者
Sorry,user yourusername may not run sudo on CentOS
或者(直接sudo+命令):
yourusername is not in the sudoers file. This incident will be reported.
这种情况下,为了让我们的用户能够正常的使用sudo,需要通过修改/etc/sudoers文件。
#添加下面一行到:/etc/sudoers,即可让该用户使用sudo
yourusername ALL=(ALL) ALL
这种修改是将所有的权限都赋值给了yourusername,为了sudo这个命令,就这么ALL几下,似乎有点不负责任啊,有木有?
sudoers文件默认是只读的,因此不能直接修改。网上很多方法是使用chmod来修改sudoers的权限后再通过编辑器(vi/vim etc.)来修改sudoers内容,之后再将sudoers文件的权限恢复,来达到修改sudoers的目的。这种方法确实能够修改sudoers,但是却没有办法保证sudoers文件的正确性,如果修改出现错误,将导致sudoers(sudo)不能正常的工作。更正确的做法是直接使用sudoers的专用编辑器:visudo来编辑sudoers文件。
# visudo
## visudo默认的编辑器是vi,如果你需要修改你的默认编辑器,可以通过添加EDITOR="" 来修改。
# EDITOR="/usr/bin/vim -p -X" visudo
## 如果要永久改变默认编辑器,只要将EDITOR设置为环境变量
# export EDITOR="/usr/bin/vim -p -X"
使用visudo来编辑sudoers的好处是:当我们完成sudoers的编辑时,系统会自动检测我们sudoers的格式是否正确,从而保证sudoers文件的正确性。
其实,sudoers文件是非常简单的,其内容只包含两种,第一种是别名(Aliases,基本变量定义),第二种是用户规范描述(user specifications,指定某用户可以运行的内容)。而这两种内容都是通过扩展巴科斯范式(EBNF)1来进行定义。一旦定义了别名,在用户说明中,就可以使用别名来简化给用户定义运行内容。如果同一个用户在sudoers文件中能够找到多条说明,那么将使用找到的最后一条。
sudoers的别名包含四种:User_Alias,Runas_Alias,Host_Alias和Cmnd_Alias。
User_Alias是用户别名,这个和系统中的group有点类似。通过用户别名,在sudoers中,可以将一个或者多个用户用别名来替代。
## 定义一个用户别名
User_Alias OPERATORS = operator1,operator2,remote_admin
注意:
1. 等号后面的都是系统中的用户名,用户ID,组,组id等组成,多个用逗号分隔,具体信息可参看文后参考内容sudoers2
2. 别名只能是大写字母开头的,并由大写字母,下划线和数字组成的字符串
Runas_Alias和User_Alias类似,但不同的是Runas_Alias指明的是用户将要运行命令的身份。Runas_Alias可以包含Runas_Alias别名(User_Alias是包含User_Alias别名)。
同时要注意的是,上面两个别名在匹配的时候使用的是字符串匹配法则,也就是说,当两个不同用户名的用户,即使使用了同一个用户ID,在实际情况下,也会被认为是不同的。要避免这种情况,可以考虑使用用户的ID来替代用户名。如:
Runas_Alias ROOT = #0
## 所有的用户ID为0的,统归为ROOT别名
Host_Alias是主机别名,指定规则适用的主机列表。
Host_Alias SERVERS = 192.168.0.1, 192.168.0.2, server1
注意:
1. Host_Alias中,只能使用真实的地址,这就意味着127.0.0.1这种地址是永远不会被匹配到的。而localhost要只有在真有主机的主机名为localhost的时候才能被匹配。
2. 如果IP地址没有给定掩码,sudo自动会搜寻本地网卡上对应匹配的掩码地址来作为默认的网络掩码。
Cmnd_Alias是命令别名,指定用户能够运行的某一类命令的列表。可包含一个,或多个命令(带参数),目录,或者其他的命令别名。
Cmnd_Alias SHUTDOWN_CMDS = /sbin/poweroff, /sbin/reboot, /sbin/halt
##所有的关机命令
Cmnd_Alias ADMIN_CMDS = /usr/sbin/passwd, /usr/sbin/useradd, /usr/sbin/userdel, /usr/sbin/usermod, /usr/sbin/visudo
## 所有的用户管理命令
注意:
1. 命令列表中如果包含目录(以/结束),那么该目录下(不含子目录)的所有可执行文件都被赋予了执行权限,这和使用通配符*类似;
2. 命令列表中务必使用全路径名,如果不使用完全限定名,将意味着恶意用户可以创建同名文件并在切换后的用户下运行,这将给系统带来未知的安全风险;
3. 当命令列表中的命令需要带参数的时候,如果出现特殊字符(',',':','=','\'),将需要使用反斜杆('\')进行转义。
通过上面四种别名,我们能够定义出特定的用户,主机和命令列表,在实际运行中,我们如果要对这些特定的列表的某些运行时配置项3进行修改,我们可以通过Default来完成。
Default对于前面四种别名的限制格式各有不同,定义如下:
## EBNF
Default_Entry ::= ('Defaults' |'Default' '@' Host_List |'Default' ':' User_List | 'Default' '!' Cmnd_List | 'Default' '>' Runas_List ) Parameter_List
Parameter_List ::= (Parameter...