¿Cómo evitar que chgrp borre el “bit setuid”?

¿Cómo evitar que chgrp borre el “bit setuid”?

Tenemos imágenes de Linux basadas en RH; en los cuales tengo que "aplicar" algún "archivo especial" para poder actualizarlos a la última versión de desarrollo de nuestro producto.

La persona que creó el archivo pensó que dentro de nuestra imagen base, algunos permisos son incorrectos; entonces nos dijeron que corriéramos

sudo chgrp -R nobody /whatever

Eso lo hicimos; y más tarde, cuando nuestra aplicación se estaba ejecutando, surgieron problemas oscuros.

Lo que encontré más tarde: la llamada achgrpvoluntadclarola información del bit setuid en nuestros binarios dentro de /lo que sea.

Y el problema real es: algunos de nuestros binariosdebetenga ese bit setuid configurado para que funcione correctamente.

En pocas palabras: ¿hay alguna manera de ejecutar el comando "chgrp"?sinmatando mis bits setuid?

Acabo de ejecutar lo siguiente en mi Ubuntu local; conduciendo al mismo resultado:

mkdir sticky
cd sticky/
touch blub
chmod 4755 blub 
ls -al blub 

--> me muestra el nombre del archivo con fondo rojo --> entonces, sí, setuid

chgrp -R myuser .
ls -al blub 

--> me muestra el nombre del archivo sin fondo rojo --> setuid desapareció

Respuesta1

Si desea implementar su chgrp -R nobody /whatevermanteniendo el bit setuid, puede usar estos dos findcomandos

find /whatever ! -type l -perm -04000 -exec chgrp nobody {} + \
                                      -exec chmod u+s {} +
find /whatever ! -type l ! -perm -04000 -exec chgrp nobody {} +

La find ... -perm 04000opción selecciona archivos con el bit setuid configurado. Luego, el primer comando aplica chgrpy luego a chmodpara restablecer el bit setuid que se ha eliminado. El segundo se aplica chgrpa todos los archivos que no tienen un bit setuid.

En cualquier caso, no desea llamar chgrpo chmodutilizar enlaces simbólicos, ya que eso afectaría a sus objetivos, de ahí el archivo ! -type l.

Respuesta2

Borrar los bits SUID y SGID en chgrp(o chown) es perfectamente razonable. Es una medida de seguridad para evitar problemas de seguridad. Para SGID (en ejecutables, supongo) significaejecute este programa con el grupo efectivo del propietario del grupo.

Si cambia el propietario del grupo, en términos de seguridad y control de acceso esto es algo completamente diferente, es decir, en lugar de ejecutarse con un grupo efectivo, uvwel programa ahora se ejecuta con un grupo efectivo xyz.

Por lo tanto, debe restaurar el bit SUID o SGID explícitamente en el momento del cambio de propiedad.

Anexo: Sobre la afirmación de que chgrp (o chown) solo debe borrar SGID (o SUID, resp.)

Al chownhacer ing o chgrping, cambia la configuración de seguridad de un ejecutable, y esta es razón suficiente para borrar cualquier atributo que eleve privilegios. El poder de Unix proviene de la simplicidad conceptual, y la seguridad de Unix ya es bastante complicada. Con este fin, eliminar SUID y SGID en cualquier cambio de propiedad es simplemente una red de seguridad; después de todo, en la historia de Unix/Linux hubo bastantes vulnerabilidades debido a configuraciones equivocadas de SUID o SGID.

Así que no hay ninguna razón más profunda por la que Unix se comporte de esta manera, es sólo una decisión de diseño conservadora.

Respuesta3

La limpieza del setuidbit setgid(al menos en Linux) en directorios que no la realiza el kernel tras la chown()llamada al sistema realizada por chgrp, no por chgrpsí mismo. Entonces la única manera es restaurarlo después.

También borra las capacidades de seguridad.

Entonces, en 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
)

Y ejecuta (como root):

chown_preseve_sec :newgroup file1 file2...

para cambiar el grupo mientras intenta conservar los permisos.

De forma recursiva, podrías hacer:

# 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=-

(Todo eso supone que nada esté alterando los archivos al mismo tiempo).

Respuesta4

Como es habitual en la administración, hay muchos caminos por recorrer.

La solución que puse en marcha es la siguiente:

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

información relacionada