概述
sudoers文件的作用是控制用户可以执行哪些指令。它是Linux系统管理员的重要一课喔。
文件的组成
sudoers文件由三部分组成:
- sudoers的默认配置,主要设置sudo的一些缺省值(本文不会对这些默认配置进行介绍,若有兴趣可以自己man 5 sudoers然后搜defaults)
- alias(别名),可以看作是变量的定义啦,本文也会全面的说说别名的定义。
- 规则定义,sudoers文件的重点啦,本文会着重说明规则的定义。
Alias(别名)
一共有四种类型的别名,这些类型可以看作它们是数据类型啦哈。- User_Alias
- Runas_Alias
- Host_Alias
- Cmnd_Alias
这里的NAME就可以看作是变量名咯。注意,NAME必须是要以大写字母开头,而且只能包含有大写字母,数字,下划线呢。那么User_List,Runas_List,Host_List,Cmnd_List又是什么呢?其实就是以“,"分隔的一个数组啦,只不过这四个别名表示的数组内容都会不同啦。
现在分别看看User_List,Runas_List,Host_List,Cmnd_List的每个数组元素可以是些什么值吧!User:[!][username |#uid |%groupname | +netgroup |%:nonunix_group |User_Alias]Runas:[!][username|#uid |%groupname | +netgroup |Runas_Alias]Host:[!][hostname | ip_addr | network(/netmask)? | netgroup | Host_Alias]Cmnd:[!][commandname| directory| "sudoedit" | Cmnd_Alias]
看看上面的元素名就可以知道大概什么意思了吧?这里着重拿些可能有疑问的出来说说。 叹号'!'表示取反的意思啦。 每个元素都可以是之前定义过的别名变量啦,所以会有User_List,Runas_List,Host_List,Cmnd_List这些元素啦。 directory表示有可以进入该目录并执行命令的权限啦 "sudoedit"表示允许用户使用sudo -e选项。
如果还没搞懂的话,可以看下面的别名定义的例子: User_Alias USER_TEST=tim,#501,%svn,+webgroup,%:nonunix,!nouser Runas_Alias RUNAS_TEST=tim,#501,%svn,!+webgroup Host_Alias HOST_TEST=!www.baidu.com,localhost,127.0.0.1 Cmnd_Alias CMND_TEST=Cmnd_Alias CMDS=/bin/passwd,/bin/ls,/home/svn
User Specification(用户规则)
用户规则定义的语法如下: User_List Host_List=(Runas_List1:Runas_List2) SELinux_Spec Tag_Spec Cmnd_List,... 下面对上面的语法进行说明一下: User_List(必填项):指的是该规则是针对哪些用户的。 Host_List(必填项):指的是该规则针对来自哪些主机的用户。 Runas_List1(可选项):表示可以用sudo -u来切换的用户 Runas_List2(可选项):表示可以用sudo -g来切换的用户组 SELinux_Spec(可选项):表示SELinux相关的选项,可选值为ROLE=role 或 TYPE=type。本人对SELinux不太熟,以后再补充这里吧。 Tag_Spec(可选项):用于控制后面Cmnd_List的一些选项啦,可选值有下面这些,具体自己man一下吧,这里就不啰嗦了。'NOPASSWD:' | 'PASSWD:' | 'NOEXEC:' | 'EXEC:' | 'SETENV:' | 'NOSETENV:' | 'LOG_INPUT:' | 'NOLOG_INPUT:' | 'LOG_OUTPUT:' | 'NOLOG_OUTPUT:'
...(可选项):表示可以有多个(Runas_List1:Runas_List2) SELinux_Spec Tag_Spec Cmnd_List段的意思了。
Notice:如果Runas_List1和Runas_List2都没填的话,默认是以root用户执行
如果不是很理解的话,可以对比着文章后面举的例子来看下,应该难不倒聪明的我们!
杂项
sudoers文件下的通配符
通配符只可以用在主机名、文件路径、命令行的参数列表中。下面是可用的通配符:
*:匹配任意数量的字符
?:匹配一个任意字符
[...]:匹配在范围内的一个字符
[!...]:匹配不在范围内的一个字符
\x:用于转义特殊字符
在使用通配符时有以下的注意点:
1.使用[:alpha:]等通配符时,要转义冒号':',如:[\:alpha\:]
2.当通配符用于文件路径时,不能跨'/'匹配,如:/usr/bin/*能匹配/usr/bin/who但不能匹配/usr/bin/X11/xterm
3.如果指令的参数列表是""时,匹配不包含任何参数的指令。
4.ALL这个关键字表示匹配所有情况。
man sudoers下的例子解析
# 用户别名定义
User_Alias FULLTIMERS = millert, mikef, dowdy
User_Alias PARTTIMERS = bostley, jwfox, crawl
User_Alias WEBMASTERS = will, wendy, wim
#用户切换别名定义
Runas_Alias OP = root, operator
Runas_Alias DB = oracle, sybase
Runas_Alias ADMINGRP = adm, oper
#主机别名定义
Host_Alias SPARC = bigtime, eclipse, moet, anchor :\
SGI = grolsch, dandelion, black :\
ALPHA = widget, thalamus, foobar :\
HPPA = boa, nag, python
Host_Alias CUNETS = 128.138.0.0/255.255.0.0
Host_Alias CSNETS = 128.138.243.0, 128.138.204.0/24, 128.138.242.0
Host_Alias SERVERS = master, mail, www, ns
Host_Alias CDROM = orion, perseus, hercules
#指令别名定义
Cmnd_Alias DUMPS = /usr/bin/mt, /usr/sbin/dump, /usr/sbin/rdump,\
/usr/sbin/restore, /usr/sbin/rrestore
Cmnd_Alias KILL = /usr/bin/kill
Cmnd_Alias PRINTING = /usr/sbin/lpc, /usr/bin/lprm
Cmnd_Alias SHUTDOWN = /usr/sbin/shutdown
Cmnd_Alias HALT = /usr/sbin/halt
Cmnd_Alias REBOOT = /usr/sbin/reboot
Cmnd_Alias SHELLS = /usr/bin/sh, /usr/bin/csh, /usr/bin/ksh, \
/usr/local/bin/tcsh, /usr/bin/rsh, \
/usr/local/bin/zsh
Cmnd_Alias SU = /usr/bin/su
Cmnd_Alias PAGERS = /usr/bin/more, /usr/bin/pg, /usr/bin/less
#开始定义规则
#root用户及wheel用户组下的所有用户都可以从任何主机连接进来以任意身份执行任意命令
root ALL = (ALL) ALL
%wheel ALL = (ALL) ALL
#FULLTIMERS这个用户别名中定义的用户可以从任何主机连接进来以任意身份执行任意命令,而且在切换用户或用户组时不需要输入密码
FULLTIMERS ALL = NOPASSWD: ALL
#PARTTIMERS这个用户别名中定义的用户可以从任何主机连接进来以root身份执行任意命令。
PARTTIMERS ALL = ALL
#The user jack may run any command on the machines in the CSNETS alias (the networks 128.138.243.0, 128.138.204.0, and 128.138.242.0). Of those
#networks, only 128.138.204.0 has an explicit netmask (in CIDR notation) indicating it is a class C network. For the other networks in CSNETS,
# the local machine’s netmask will be used during matching.
jack CSNETS = ALL
#lisa这个用户可以从CUNETS中定义的主机连接进来以root身份执行任意指令。
lisa CUNETS = ALL
#oprator这个用户可以从任何主机连接进来以root身份执行DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,sudoedit /etc/printcap, /usr/oper/bin/定义的指令
operator ALL = DUMPS, KILL, SHUTDOWN, HALT, REBOOT, PRINTING,\
sudoedit /etc/printcap, /usr/oper/bin/
#joe这个用户可以从任何主机连接进来,并且只能执行su operator指令
joe ALL = /usr/bin/su operator
#pete这个用户可以从HPPA定义的主机中连接进来并以root身份执行passwd的所有命令,除了passwd root
pete HPPA = /usr/bin/passwd [A-Za-z]*, !/usr/bin/passwd root
#opers这个用户组下的所有用户可以从任何主机连接进来,并可以切换至ADMINGRP中定义的用户组进入/usr/sbin并执行命令
%opers ALL = (: ADMINGRP) /usr/sbin/
#bob这个用户可以从SPARC和SGI中定义的主机连接进来,并可以OP定义的用户执行任意指令
bob SPARC = (OP) ALL : SGI = (OP) ALL
#jim这个用户可以从biglab这个netgroup中连接进来,并执行任意指令
jim +biglab = ALL
#secretaries这个netgroup下的所有用户可以从任意主机连接进来,并以root身份执行PRINTING,/usr/bin/adduser, /usr/bin/rmuser中定义的指令
+secretaries ALL = PRINTING, /usr/bin/adduser, /usr/bin/rmuser
#fred这个用户可以从任何主机连接进来并以DB别名定义的用户来执行所有指令,并且不需要输入密码
fred ALL = (DB) NOPASSWD: ALL
#john这个用户可以从ALPHA定义的主机中连接进来,并可以以root身份执行su指令,但不能执行su root和使用任何su选项
john ALPHA = /usr/bin/su [!-]*, !/usr/bin/su *root*
#jen这个用户可以从任何主机(除了SERVERS中定义的主机)连接进来,并以root身份执行任意指令
jen ALL, !SERVERS = ALL
#jill这个用户可以从SERVERS定义的主机连接进来,并以root身份进入/usr/bin/执行指令,但不能执行SU和SHELLS中定义的命令
jill SERVERS = /usr/bin/, !SU, !SHELLS
#steve这个用户可以从CSNETS中定义的主机连接进来,并以operator这个用户可以进入/usr/local/op_commands/执行指令
steve CSNETS = (operator) /usr/local/op_commands/