大家平时使用su命令切换用户时,有一个明显的安全问题就是一般用户必须知道欲切换用户的密码时才可以成功执行su命令。假设有这样一种情况,管理员希望系统中的某些用户可以使用部分只有管理员才可以使用的命令,这时如果使用使用su命令管理员就必须将自己的密码告诉这些用户,这样显然是不安全的。这时可以通过sudo命令解决这个问题,sudo命令的工作流程如下:
(1) 当用户执行sudo命令时,系统会检查/etc/sudoers文件,判断该用户是否有执行sudo命令的权限。
(2) 如果用户具有可执行sudo的权限,系统会提示用户“输入用户自己的密码”来确认。
(3) 如果密码输入成功,则开始sudo使用指定的用户执行指定的命令。
要注意的是使用sudo命令时用户输入的是自己的密码,而不是欲切换用户的密码。sudo命令可以使用户通过自己的密码、其他用户的身份执行的工作,而不必知道其他用户的密码。和su命令一样如果sudo命令的是root用户则不需要输入任何密码。
/etc/sudoers文件
在RHEL 5.x中默认只有root用户用户可以使用sudo命令,如果希望其他用户也可以使用sudo命令,必须由root用户使用“visudo”命令修改/etc/sudoers文件或直接使用vim编辑/etc/sudoers文件。
提示:由于root用户对/etc/sudoers文件的权限是只读,所以如果使用vim编辑/etc/sudoers文件后,保存时需要使用“!”强制保存。
/etc/sudoers文件默认的内容如下,在该文件中有一行“root ALL=(ALL) ALL”就是表示root用户可以使用sudo命令切换为任何用户。
[root@srv ~]# grep -v ^# /etc/sudoers | grep -v ^$
Cmnd_Alias NETWORKING = /sbin/route, /sbin/ifconfig, /bin/ping, /sbin/dhclient, /usr/bin/net, /sbin/iptables, /usr/bin/rfcomm, /usr/bin/wvdial, /sbin/iwconfig, /sbin/mii-tool
Cmnd_Alias SOFTWARE = /bin/rpm, /usr/bin/up2date, /usr/bin/yum
Cmnd_Alias SERVICES = /sbin/service, /sbin/chkconfig
Cmnd_Alias LOCATE = /usr/bin/updatedb
Cmnd_Alias STORAGE = /sbin/fdisk, /sbin/sfdisk, /sbin/parted, /sbin/partprobe, /bin/mount, /bin/umount
Cmnd_Alias DELEGATING = /usr/sbin/visudo, /bin/chown, /bin/chmod, /bin/chgrp
Cmnd_Alias PROCESSES = /bin/nice, /bin/kill, /usr/bin/kill, /usr/bin/killall
Cmnd_Alias DRIVERS = /sbin/modprobe
Defaults requiretty
Defaults env_reset
Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \
LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
_XKB_CHARSET XAUTHORITY"
root ALL=(ALL) ALL
如果希望其他用户也可以使用sudo命令可在/etc/sudoers文件中进行配置,配置格式如下。
用户或用户组 可登录的主机 =(可变换的身份)表示可执行的命令
下面看几个配置/etc/sudoers文件以使用指定用户可以使用sudo命令的例子。
#在/etc/sudoers文件中增加如下内容后,用户“user1”就可以以root用户的身份执行
#“chkconfig”命令。
user1 ALL=(root) /sbin/chkconfig
#在/etc/sudoers文件中增加如下内容后,用户“user1”就可以以root用户的身份
#执行所有命令,而且不需要输入用户“user1”的密码。“NOPASSWD:”选项表示不
#需要输入密码。
user1 ALL=(root) NOPASSWD:ALL
#在/etc/sudoers文件中增加如下内容后,用户组“gossipgirl”的所有成员就可以以root
#用户的身份执行所有命令。在指定用户组时必须使用“%”开头。
%gossipgirl ALL=(root) ALL
在/etc/sudoers文件中还包括以下几个常用选项:
(1) User_Alias,在上面的例子中已经看到可以在/etc/sudoers文件中通过“%”使用系统中已存在的用户组。如果有几个不属于同一个用户组的用户需要使用sudo命令执行一些操作可以通过“User_Alias”选项在/etc/sudoers文件中定义一个组(这个组只在/etc/sudoers文件中有效)。比如在/etc/sudoers文件中增加如下内容后,用户“user1”和“user2”都可以使用root用户的身份执行“chkconfig”命令。
#定义一个名为“TSTGRP”的组,在该组中包括用户“user1”和“user2”。
User_Alias TSTGRP= user1,user2
#“TSTGRP”的组用户可以使用root用户的身份执行“chkconfig”命令。
TSTGRP ALL=(root) /sbin/chkconfig
(2) Cmnd_Alias,如果需要在/etc/sudoers文件多次定义一组命令时可以使用Cmnd_Alias选项。比如在/etc/sudoers文件中增加如下内容后,“TSTCMD”就可以表示“/sbin/chkconfig”和“/sbin/iptables”命令。
#定义一个名为“TSTCMD”的命令别名,该命令别名中包括“/sbin/chkconfig”和
#“/sbin/iptables”命令。
Cmnd_Alias TSTCMD=/sbin/chkconfig, /sbin/iptables
#用户“user1”就可以以root用户的身份执行“TSTCMD”中定义的命令。
user1 ALL=(root) TSTCMD
(3) 拒绝命令选项,系统在读取/etc/sudoers文件时会严格匹配命令。可以使用这个特性只允许用户使用sudo命令执行命令的某些选项。比如在/etc/sudoers文件中增加如下内容。
#在/etc/sudoers文件中增加如下内容后,用户“user1”就可以以root用户的身份#执行“iptables”命令,但不允许使用“-nL”选项。
user2 ALL=(root) NOPASSWD:/sbin/iptables,!/sbin/iptables -nL
#在/etc/sudoers文件中增加如下内容后,用户“olivia”就可以以root用户的身份执行
#“passwd 用户名”命令修改其他用户的密码,但不允许使用“passwd”和“passwd root”
#命令。
olivia ALL = NOPASSWD:!/usr/bin/passwd,/usr/bin/passwd [A-Za-z]*,!/usr/bin/passwd root
sudo命令
在完成/etc/sudoers文件的配置后,用户就可以使用sudo命令以其他用户身份执行命令,该命令语法如下。
sudo [-u [<用户名>|#<UID>]] 命令
l -u [<用户名>|#<UID>]:指定执行指定命令的用户,如不指定则表示希望使root用户执行指定命令。
在第一执行sudo命令输入密码后,该密码会保存5分钟,也就在5分钟内再使用sudo命令是可不需要输入密码。下面看几个sudo命令的例子。
l 当前用户是“user1”。
[user1@srv ~]$ id
uid=500(user1) gid=500(user1) groups=500(user1)
l 使用root用户的身份执行“/sbin/iptables -L”命令。
[user1@srv ~]$ sudo -u root /sbin/iptables -L
Password: #输入密码,注意输入的是用户“user1”的密码,而不是用户root的密码。
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
[user1@srv ~]$ sudo -u root /sbin/iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination