Как предотвратить очистку «setuid bit» командой chgrp?

Как предотвратить очистку «setuid bit» командой chgrp?

У нас есть образы 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, соответственно)

Используя chowning ​​или chgrping, вы меняете настройки безопасности для исполняемого файла, и это достаточная причина для очистки любых атрибутов повышения привилегий. Сила 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

Связанный контент