我们有基于 RH 的 Linux 镜像;我必须“应用”一些“特殊存档”才能将它们升级到我们产品的最新开发版本。
创建存档的人认为在我们的基础映像中,某些权限是错误的;所以我们被告知要跑
sudo chgrp -R nobody /whatever
我们做到了;后来,当我们的应用程序运行时,出现了一些难以理解的问题。
我后来发现:调用chgrp将要清除/whatever 中二进制文件的 setuid 位信息。
实际问题是:我们的一些二进制文件必须设置 setuid 位才能正常运行。
长话短说:有没有办法运行“chgrp”命令没有杀死我的 setuid 位?
我刚刚在本地 Ubuntu 上运行了以下命令;导致相同的结果:
mkdir sticky
cd sticky/
touch blub
chmod 4755 blub
ls -al blub
--> 显示红色背景的文件名 --> 所以,是的,setuid
chgrp -R myuser .
ls -al blub
--> 显示没有红色背景的文件名 --> setuid 消失了
答案1
如果您想chgrp -R nobody /whatever
在保留 setuid 位的同时实现您可以使用这两个find
命令
find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
-exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +
该find ... -perm 04000
选项拾取设置了 setuid 位的文件。然后,第一个命令应用 a chgrp
,然后应用 achmod
来恢复已取消的 setuid 位。第二个适用chgrp
于所有没有 setuid 位的文件。
在任何情况下,您都不想在符号链接上调用chgrp
或 ,chmod
因为这会影响它们的目标,因此! -type l
.
答案2
清除chgrp
(或chown
)上的 SUID 和 SGID 位是完全合理的。这是为了防止安全问题而采取的安全措施。对于 SGID(我认为是在可执行文件上)意味着使用组所有者的有效组运行此程序。
如果您更改组所有者,那么就安全性和访问控制而言,这是完全不同的,即uvw
程序现在使用 effective group 运行,而不是使用 effective group 运行xyz
。
因此,您必须在所有权更改时显式恢复 SUID 或 SGID 位。
附录:关于 chgrp(或 chown)应该只清除 SGID(或 SUID)的主张
通过chown
ing 或chgrp
ing,您可以更改可执行文件的安全设置,这足以清除任何特权提升属性。 Unix 的强大源于概念的简单性,而 Unix 的安全性已经相当棘手。为此,在任何所有权变更时删除 SUID 和 SGID 只是一个安全网 - 毕竟,在 Unix/Linux 的历史上,由于错误的 SUID 或 SGID 设置而存在相当多的漏洞。
所以 Unix 的行为方式没有更深层次的原因,这只是一个保守的设计决策。
答案3
setuid
非目录上的,位(至少在 Linux 上)的清除setgid
是由内核在chown()
完成系统调用时完成的chgrp
,而不是由其chgrp
本身完成。所以唯一的办法就是事后恢复。
它还清除了安全功能。
所以,在 GNU Linux 上:
chown_preserve_sec() (
newowner=${1?}; shift
for file do
perms=$(stat -Lc %a -- "$file") || continue
cap=$(getfattr -m '^security\.capability$' --dump -- "$file") || continue
chown -- "$newowner" "$file" || continue
[ -z "$cap" ] || printf '%s\n' "$cap" | setfattr --restore=-
chmod -- "$perms" "$file"
done
)
并运行(如root
):
chown_preseve_sec :newgroup file1 file2...
更改组,同时尝试保留权限。
递归地,你可以这样做:
# save permissions (and ACLs). Remove the "# owner" and "# group" lines
# to prevent them being restored!
perms=$(getfacl -RPn . | grep -vE '^# (owner|group): ')
# save capabilities
cap=$(getfattr -Rhm '^security\.capability$' --dump .)
chgrp -RP nobody .
# restore permissions, ACLs and capabilities
printf '%s\n' "$perms" | setfacl --restore=-
[ -z "$cap" ] || printf '%s\n' "$cap" | setfattr -h --restore=-
(这都是假设没有任何其他情况同时破坏文件的情况)。
答案4
像往常一样,在管理方面有很多方法可以走。
我提出的解决方案是这样的:
cd /home/me
getfacl -R /whatever > whatever-permissions.org 2> /dev/null
# A) change lines starting with # group: root
# to # group: whatineed
sed 's/^# group: root/# group: whatineed/g' whatever-permissions.org > whatever-permissions.new
# B) change lines with group::x.y
# to group::xwy
# (where x, y mean: whatever was there before)
sed 's/^group::\(.\).\(.\)/group::\1w\2/g' whatever-permissions.new > whatever-permissions.new
cd /
setfacl --restore /home/me/whatever-permissions.new