星期四, 二月 15, 2007

sudo (1)

sudo 有诸多好处:
1. 管理员能够在不告诉用户 root 密码的前提下,授予他们某些特定类型的超级用户权限,这正是许多系统管理员所梦寐以求的。
2. 在这种情况下,我们也就可以定义多个系统管理员,来执行不同的任务。
3. 如果需要取消某人的管理权限(例如离职),那么相对来说也比较简单一点,只需要锁定相应帐号即可(usermod -L $user, 或在 /etc/passwd 文件中的密码项部分开始处插入"!",最好不要使用 userdel -r $user)。当然,如果没有集中的认证如 Kerberos,那么还是需要在每一台主机上执行这项操作的。
4. 减小误操作的机会和损失。

Ubuntu 默认的 /etc/sudoers 文件内容(因为 Ubuntu 默认采用 sudo 并且禁止 root 登录的,比较典型):
# User privilege specification 
root ALL=(ALL) ALL
# Members of the admin group may gain root privileges
%admin ALL=(ALL) ALL
这太过于简单,做一个复杂点的来适应服务器系统管理的需要:
......
# Cmnd alias specification
Cmnd_Alias SYSCMD=/bin/*,/sbin/*,/usr/bin/*,/usr/sbin/*,/usr/local/bin/*,/usr/local/sbin/*
Cmnd_Alias COPY_BIN=/*/cp */bin/* *,/*/cp * */bin/*,/*/cp */sbin/* *,/*/cp * */sbin/*
Cmnd_Alias MOVE_BIN=/*/mv */bin/* *,/*/mv * */bin/*,/*/mv */sbin/* *,/*/mv * */sbin/*
Cmnd_Alias LINK_BIN=/*/ln */bin/* *,/*/ln * */bin/*,/*/ln */sbin/* *,/*/ln * */sbin/*
Cmnd_Alias RENAME=/*/rename,
Cmnd_Alias VISUDO=/usr/sbin/visudo,/*/vi* /etc/sudoers
# Cmnd_Alias VISUDO=/*/visudo
Cmnd_Alias CHOWN=/*/chown *
Cmnd_Alias CHMOD=/*/chmod *
Cmnd_Alias USER_CMD=/usr/bin/passwd,\
/usr/sbin/useradd,\
/usr/sbin/usermod,\
/usr/sbin/groupadd,\
/usr/sbin/groupmod,\
/usr/bin/chage -m ? -W [3-7] * ?*

# Defaults specification

# User privilege specification
root ALL=(ALL) ALL
%admins ALL=(%root) SYSCMD,!COPY_BIN,!MOVE_BIN,!LINK_BIN,!VISUDO,!CHOWN,!CHMOD,!USER_CMD
sysadm ALL=(%root) NOPASSWD:ALL

......
这里重点是 Cmnd_Alias 部分,因为涉及到安全的很多问题。首先 SYSCMD 定义所有的系统命令,%admin 组可以执行这些命令,并且只能执行这些命令,即所有 bin 和 sbin 目录下的程序。

这样做是为了阻止这些用户通过 sudo 以 root 身份运行后面的一些敏感操作,包括 visudo, chown, chmod, passwd, useradd, groupadd, usermod, groupmod, chage 等。只是不明白为什么用 /*/visudo 不能匹配?如果仅仅只是用"!"定义不能执行这些命令是不够的,因为这些命令可以被拷贝到 /tmp 或 $HOME 下,然后改个名字就可以运行,所以必须定义只能运行 SYSCMD 范围之内的命令。

另外,这也可以提醒人们编写质量更高的脚本。如果一个脚本不够资格放在 bin 目录下,那最好还是不要用它吧,在 /root 下一大堆丑陋的脚本将极大的降低系统环境的复用性,导致熵增大。

但这样仍然不够,因为用户还可以把 /usr/sbin/visudo 拷贝成 /usr/sbin/VISUDO,还是可以运行,所以必须禁止一切针对 SYSCMD 的拷贝和改名动作。COPY_BIN, MOVE_BIN, LINK_BIN, RENAME 被用来做这件事情,同时它还阻止向 SYSCMD 的拷贝以防使用 hack 版本覆盖原文件。

然后增加用户和组:
sh# useradd -u 123 sysadm
sh# groupadd -u 124 admins
sh# useradd sysadm01
sh# useradd -G admins sysadm01
这样看上去万无一失了
sh$ sudo /bin/cp /bin/cp /tmp
Sorry, user sysadm01 is not allowed to execute '/bin/cp /bin/cp /tmp' as root on stor.shopex.cn.
sh$ sudo /bin/cp /usr/sbin/visudo /tmp/
Sorry, user sysadm01 is not allowed to execute '/bin/cp /usr/sbin/visudo /tmp/' as root on stor.shopex.cn.
sh$ sudo cp /usr/sbin/visudo /tmp/
Sorry, user sysadm01 is not allowed to execute '/bin/cp /usr/sbin/visudo /tmp/' as root on stor.shopex.cn.
sh$ sudo cp -r /usr/sbin/visudo /tmp/
# 看看加一个参数在中间会不会有影响!
Sorry, user sysadm01 is not allowed to execute '/bin/cp -r /usr/sbin/visudo /tmp/' as root on stor.shopex.cn.
但实际上还是不够。不信运行下面这几条命令:
sh$ cd /usr/sbin
sh$ sudo cp visudo /tmp
sh$ sudo cp visudo VISUDO # [1]
sh$ sudo cp /tmp/VISUDO ./VISUDO # [2]
显然 sudo 无法检查匹配的路径,这样就完全绕过了前面的安全设定;而且 sudo 的匹配只是针对命令字符串的匹配,并且不支持正则表达式。对[1]还可以处理,虽然没有正则,但可以多加几条规则也可以避免,但对[2]就完全无能为力了,因为完全可以从别的系统上传一个 VISUDO 到 /tmp,然后切换到 /usr/sbin 绕开 !COPY_BIN 限制!

对此,我想唯一的解决办法就是使用 tripware + sudo.log,但如果 sudo.log 被抹掉?而且我的 sudo.log 里面没有任何记录!?

没有评论: