У нас есть образы Linux на основе RH, к которым мне приходится «применять» некий «специальный архив», чтобы обновить их до последней разрабатываемой версии нашего продукта.
Человек, создавший архив, решил, что в нашем базовом образе некоторые разрешения неверны; поэтому нам сказали запустить
sudo chgrp -R nobody /whatever
Мы так и сделали; и позже, когда наше приложение заработало, возникли непонятные проблемы.
Что я обнаружил позже: призыв кchgrpволяпрозрачныйинформация о бите setuid для наших двоичных файлов в /whatever.
А настоящая проблема в том, что некоторые из наших двоичных файловдолженДля корректной работы необходимо установить бит 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. Затем первая команда применяет chgrp
и затем a chmod
для восстановления сброшенного бита setuid. Вторая применяется chgrp
ко всем файлам, у которых нет бита setuid.
В любом случае, вам не следует вызывать chgrp
или chmod
для символических ссылок, поскольку это повлияет на их цели, поэтому ! -type l
.
решение2
Очистка битов SUID и SGID на chgrp
(или chown
) вполне разумна. Это мера безопасности, чтобы предотвратить проблемы безопасности. Для SGID (на исполняемых файлах, я полагаю) означаетзапустить эту программу с эффективной группой владельца группы.
Если вы измените владельца группы, то с точки зрения безопасности и контроля доступа это будет нечто совершенно иное, т. е. вместо запуска с эффективной группой uvw
программа теперь будет работать с эффективной группой xyz
.
Таким образом, вам придется явно восстанавливать бит SUID или SGID при смене владельца.
Приложение: По поводу утверждения, что chgrp (или chown) должен очищать только SGID (или SUID, соответственно)
Используя chown
ing или chgrp
ing, вы меняете настройки безопасности для исполняемого файла, и это достаточная причина для очистки любых атрибутов повышения привилегий. Сила Unix исходит из концептуальной простоты, а безопасность Unix и так довольно сложна. С этой целью удаление SUID и SGID при любой смене владельца — это просто страховочная сетка — в конце концов, в истории Unix/Linux было довольно много уязвимостей из-за ошибочных настроек SUID или SGID.
Так что нет никакой более глубокой причины, по которой Unix ведет себя таким образом, это просто консервативное решение по проектированию.
решение3
Очистка бита setuid
, setgid
(по крайней мере в Linux) на не-каталогах выполняется ядром при 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