
我們有基於 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