“Sudo”
是
Unix/Linux
平台上的一个非常有用的工具,它允许系统管理员分配给普通用户一些合理的
“
权利
”
,让他们执行一些只有超级用户或其他特许用户才能完成的任务,比如:运行一些像
mount
,
halt
,
su
之类的命令,或者编辑一些系统配置文件,像
/etc/mtab
,
/etc/samba/smb.conf
等。这样以来,就不仅减少了
root
用户的登陆次数和管理时间,也提高了系统安全性。
一、
sudo
的特点
sudo
扮演的角色注定了它要在安全方面格外谨慎,否则就会导致非法用户攫取
root
权限。同时,它还要兼顾易用性,让系统管理员能够更有效,更方便地使用它。
sudo
设计者的宗旨是:给用户尽可能少的权限但仍允许完成他们的工作。所以,
sudo
有以下特点:
# 1. sudo
能够限制指定用户在指定主机上运行某些命令。
# 2. sudo
可以提供日志,忠实地记录每个用户使用
sudo
做了些什么,并且能将日志传到中心主机或者日志服务器。
# 3. sudo
为系统管理员提供配置文件,允许系统管理员集中地管理用户的使用权限和使用的主机。它默认的存放位置是
/etc/sudoers
。
# 4.sudo
使用时间戳文件来完成类似
“
检票
”
的系统。当用户执行
sudo
并且输入密码后,用户获得了一张默认存活期为
5
分钟的
“
入场券
”
(默认值可以在编译的时候改变)。超时以后,用户必须重新输入密码。
二、
sudo
的适用条件
由于
su
对切换到超级权限用户
root
后,权限的无限制性,所以
su
并不能担任多个管理员所管理的系统。如果用
su
来切换到超级用户来管理系统,也不能明确哪些工作是由哪个管理员进行的操作。特别是对于服务器的管理有多人参与管理时,最好是针对每个管理员的技术特长和管理范围,并且有针对性的下放给权限,并且约定其使用哪些工具来完成与其相关的工作,这时我们就有必要用到
sudo
。
通过
sudo
,我们能把某些超级权限有针对性的下放,并且不需要普通用户知道
root
密码,所以
sudo
相对于权限无限制性的
su
来说,还是比较安全的,所以
sudo
也能被称为受限制的
su
;另外
sudo
是需要授权许可的,所以也被称为授权许可的
su
;
sudo
执行命令的流程是当前用户切换到
root
(或其它指定切换到的用户),然后以
root
(或其它指定的切换到的用户)身份执行命令,执行完成后,直接退回到当前用户;而这些的前提是要通过
sudo
的配置文件
/etc/sudoers
来进行授权;
三、从编写
sudo
配置文件
/etc/sudoers
开始
sudo
的配置文件是
/etc/sudoers
,我们可以用他的专用编辑工具
visodu
,此工具的好处是在添加规则不太准确时,保存退出时会提示给我们错误信息;配置好后,可以用切换到您授权的用户下,通过
sudo -l
来查看哪些命令是可以执行或禁止的;
/etc/sudoers
文件中每行算一个规则,前面带有
#
号可以当作是说明的内容,并不执行;如果规则很长,一行列不下时,可以用
\
号来续行,这样看来一个规则也可以拥有多个行;
/etc/sudoers
的规则可分为两类;一类是别名定义,另一类是授权规则;别名定义并不是必须的,但授权规则是必须的;
四、
/etc/sudoers
配置文件中别名规则
别名规则定义格式如下:
Alias_Type NAME = item1, item2, ...
或
Alias_Type NAME = item1, item2, item3 : NAME = item4, item5
别名类型(
Alias_Type
):别名类型包括如下四种
Host_Alias
定义主机别名;
User_Alias
用户别名,别名成员可以是用户,用户组(前面要加
%
号)
Runas_Alias
用来定义
runas
别名,这个别名指定的是
“
目的用户
”
,即
sudo
允许切换至的用户;
Cmnd_Alias
定义命令别名;
NAME
就是别名了,
NMAE
的命名是包含大写字母、下划线以及数字,但必须以一个大写字母开头,比如
SYNADM
、
SYN_ADM
或
SYNAD0
是合法的,
sYNAMDA
或
1SYNAD
是不合法的;
item
按中文翻译是项目,在这里我们可以译成成员,如果一个别名下有多个成员,成员与成员之间,通过半角
,
号分隔;成员在必须是有效并事实存在的。什么是有效的呢?比如主机名,可以通过
w
查看用户的主机名(或
ip
地址),如果您只是本地机操作,只通过
hostname
命令就能查看;用户名当然是在系统中存在的,在
/etc/paswd
中必须存在;对于定义命令别名,成员也必须在系统中事实存在的文件名(需要绝对路径);
item
成员受别名类型
Host_Alias
、
User_Alias
、
Runas_Alias
、
Cmnd_Alias
制约,定义什么类型的别名,就要有什么类型的成员相配。我们用
Host_Alias
定义主机别名时,成员必须是与主机相关相关联,比如是主机名(包括远程登录的主机名)、
ip
地址(单个或整段)、掩码等;当用户登录时,可以通过
w
命令来查看登录用户主机信息;用
User_Alias
和
Runas_Alias
定义时,必须要用系统用户做为成员;用
Cmnd_Alias
定义执行命令的别名时,必须是系统存在的文件,文件名可以用通配符表示,配置
Cmnd_Alias
时命令需要绝对路径;其中
Runas_Alias
和
User_Alias
有点相似,但与
User_Alias
绝对不是同一个概念,
Runas_Alias
定义的是某个系统用户可以
sudo
切换身份到
Runas_Alias
下的成员;我们在授权规则中以实例进行解说;别名规则是每行算一个规则,如果一个别名规则一行容不下时,可以通过
\
来续行;同一类型别名的定义,一次也可以定义几个别名,他们中间用
:
号分隔,
五、
/etc/sudoers
中的授权规则
授权规则是分配权限的执行规则,我们前面所讲到的定义别名主要是为了更方便的授权引用别名;如果系统中只有几个用户,其实下放权限比较有限的话,可以不用定义别名,而是针对系统用户直接直接授权,所以在授权规则中别名并不是必须的;
授权规则并不是无章可寻,我们只说基础一点的,比较简单的写法,如果您想详细了解授权规则写法的,请参看
man sudoers
授权用户
主机
=
命令动作
这三个要素缺一不可,但在动作之前也可以指定切换到特定用户下,在这里指定切换的用户要用
( )
号括起来,如果不需要密码直接运行命令的,应该加
NOPASSWD:
参数,但这些可以省略;举例说明;
实例一:
beinan ALL=/bin/chown,/bin/chmod
如果我们在
/etc/sudoers
中添加这一行,表示
beinan
可以在任何可能出现的主机名的系统中,可以切换到
root
用户下执行
/bin/chown
和
/bin/chmod
命令,通过
sudo -l
来查看
beinan
在这台主机上允许和禁止运行的命令;
值得注意的是,在这里省略了指定切换到哪个用户下执行
/bin/shown
和
/bin/chmod
命令;在省略的情况下默认为是切换到
root
用户下执行;同时也省略了是不是需要
beinan
用户输入验证密码,如果省略了,默认为是需要验证密码。
为了更详细的说明这些,我们可以构造一个更复杂一点的公式;
授权用户
主机
=[(
切换到哪些用户或用户组
)] [
是否需要密码验证
]
命令
1,[(
切换到哪些用户或用户组
)] [
是否需要密码验证
] [
命令
2],[(
切换到哪些用户或用户组
)] [
是否需要密码验证
] [
命令
3]....
实例二:
beinan ALL=(root) /bin/chown, /bin/chmod
如果我们把第一个实例中的那行去掉,换成这行;表示的是
beinan
可以在任何可能出现的主机名的主机中,可以切换到
root
下执行
/bin/chown
,可以切换到任何用户招执行
/bin/chmod
命令,通过
sudo -l
来查看
beinan
在这台主机上允许和禁止运行的命令;
实例三:
beinan ALL=(root) NOPASSWD: /bin/chown,/bin/chmod
如果换成这个例子呢?表示的是
beinan
可以在任何可能出现的主机名的主机中,可以切换到
root
下执行
/bin/chown
,不需要输入
beinan
用户的密码;并且可以切换到任何用户下执行
/bin/chmod
命令,但执行
chmod
时需要
beinan
输入自己的密码;通过
sudo -l
来查看
beinan
在这台主机上允许和禁止运行的命令;
关于一个命令动作是不是需要密码,我们可以发现在系统在默认的情况下是需要用户密码的,除非特加指出不需要用户需要输入自己密码,所以要在执行动作之前加入
NOPASSWD:
参数;
有可能有的弟兄对系统管理的命令不太懂,不知道其用法,这样就影响了他对
sudoers
定义的理解,下面我们再举一个最简单,最有说服务力的例子;
实例四:用户组在
/etc/sudoers
中写法;
如果用户组出现在
/etc/sudoers
中,前面要加
%
号,比如
%beinan
,中间不能有空格;
%beinan ALL=/usr/sbin/*,/sbin/*
如果我们在
/etc/sudoers
中加上如上一行,表示
beinan
用户组下的所有成员,在所有可能的出现的主机名下,都能切换到
root
用户下运行
/usr/sbin
和
/sbin
目录下的所有命令;