Como evitar que o chgrp apague o “setuid bit”?

7

Temos imagens Linux baseadas em RH; em que eu tenho que "aplicar" algum "arquivo especial", a fim de atualizá-los para a versão mais recente de desenvolvimento do nosso produto.

A pessoa que criou o arquivo descobriu que, dentro da nossa imagem de base, algumas permissões estão erradas; então nos disseram para rodar

sudo chgrp -R nobody /whatever

Nós fizemos isso; e mais tarde, quando nosso aplicativo está em execução, surgiram problemas obscuros.

O que eu encontrei mais tarde: a chamada para chgrp irá limpar as informações do bit setuid em nossos binários dentro de / whatever.

E o problema real é: alguns de nossos binários devem ter esse bit setuid configurado para funcionar corretamente.

Longa história: existe uma maneira de executar o comando "chgrp" sem matar meus bits setuid?

Eu apenas corri o seguinte no meu Ubuntu local; levando ao mesmo resultado:

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

- > mostra-me o nome do arquivo com fundo vermelho - > então, sim, setuid

chgrp -R myuser .
ls -al blub 

- > mostra-me o nome do arquivo sem fundo vermelho - > setuid se foi

    
por GhostCat 30.09.2016 / 13:05

4 respostas

6

Se você quiser implementar seu chgrp -R nobody /whatever enquanto retém o bit setuid, você pode usar estes dois comandos find

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

A opção find ... -perm 04000 seleciona arquivos com o conjunto de bits setuid. O primeiro comando, em seguida, aplica o chgrp e, em seguida, um chmod para restabelecer o bit setuid que foi desativado. O segundo aplica chgrp a todos os arquivos que não possuem um bit setuid.

Em qualquer caso, você não deseja chamar chgrp ou chmod em links simbólicos, pois isso afetaria seus destinos, portanto, o ! -type l .

    
por 30.09.2016 / 14:25
4

A limpeza do setuid , setgid bit (pelo menos no Linux) em não diretórios é feita pelo kernel após a chamada do sistema chown() feita por chgrp , não pelo chgrp em si. Então, a única maneira é restaurá-lo depois.

Também limpa os recursos de segurança.

Então, no 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
)

E execute (como root ):

chown_preseve_sec :newgroup file1 file2...

para alterar o grupo enquanto tenta preservar as permissões.

Recursivamente, você pode fazer:

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

(isso é tudo presumindo que nada é bagunçar os arquivos ao mesmo tempo).

    
por 30.09.2016 / 14:42
4

Limpar os bits SUID e SGID em chgrp (ou chown ) é perfeitamente razoável. É uma medida de segurança para evitar problemas de segurança. Para SGID (em executáveis, eu presumo) significa rodar este programa com um grupo efetivo do dono do grupo .

Se você alterar o proprietário do grupo, em termos de segurança e controle de acesso isso é algo totalmente diferente, ou seja, em vez de executar com o grupo efetivo uvw , o programa agora é executado com grupo efetivo xyz .

Assim, você precisa restaurar o bit SUID ou SGID explicitamente na alteração de propriedade.

Adendo: Sobre a alegação de que chgrp (ou chown) deve apenas limpar SGID (ou SUID, resp.)

Por chown ing ou chgrp ing você altera a configuração de segurança de um executável, e isso é razão suficiente para limpar qualquer atributo de elevação de privilégio. O poder do Unix vem da simplicidade conceitual, e a segurança do Unix já é bastante complicada. Para este fim, remover o SUID e o SGID em qualquer alteração de propriedade é simplesmente uma rede de segurança - afinal, na história do Unix / Linux, havia algumas vulnerabilidades devido a configurações incorretas de SUID ou SGID.

Portanto, não há nenhuma razão mais profunda para o Unix se comportar dessa maneira, é apenas uma decisão de design conservadora.

    
por 30.09.2016 / 14:49
1

Como de costume na administração, há muitos caminhos a seguir.

A solução que eu coloquei é assim:

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::w/g' whatever-permissions.new > whatever-permissions.new

cd /
setfacl --restore /home/me/whatever-permissions.new
    
por 30.09.2016 / 16:04