如何防止 chgrp 清除“setuid 位”?

如何防止 chgrp 清除“setuid 位”?

我们有基于 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)的主张

通过chowning 或chgrping,您可以更改可执行文件的安全设置,这足以清除任何特权提升属性。 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

相关内容