Linux: Como encontrar utilizadores com acesso total de sudo (numa lista de máquinas)

(Nota: há, de certeza, formas bem melhores de fazer isto — está à vontade para sugerir algumas nos comentários. Isto é apenas um script que escrevi há tempos, quando um colega de trabalho perguntou se haveria uma forma de fazer isto para os servidores que administramos.)

A situação: administras 1000 ou mais servidores, e tu a tua equipa são os únicos que supostamente devem poder fazer “sudo su” para root (ao invés de apenas correr comandos específicos, em geral relacionados com aplicações administradas por outras equipas, o que normalmente não é um problema). No entanto, às vezes é conveniente fornecer temporariamente acesso total de root a um utilizador ou grupo de utilizadores, por exemplo para fazer a instalação inicial das aplicações, mas depois esse acesso é retirado quando a máquina passa a produção.

O problema: é fácil esquecermo-nos disso, e dessa forma o acesso temporário torna-se permanente (sim, há outras formas de contornar isso, como o uso de uma sintaxe específica para esses acessos que inclui um comentário no fim da linha, em combinação com um comando configurado no daemon de “at” para retirar o acesso no fim do período temporário, mas para já vamos pôr isso de parte). Não seria útil a capacidade de passar por um grupo de máquinas, possivelmente até todo o parque Linux da empresa, e detectar esses acessos de sudo “esquecidos”?

Aqui vai um script em bash:

#!/bin/bash

# sudo su -
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | egrep "/bin/su \-$" && exit 1
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | egrep "/bin/su \-\," && exit 1
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | egrep "/bin/su \- \," && exit 1

# sudo su
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | egrep "/bin/su$" && exit 2
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | egrep "/bin/su\," && exit 2
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | egrep "/bin/su \," && exit 2

# sudo <shell>
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | grep "(ALL)" | egrep "/bin/bash|/bin/sh|/bin/dash|/bin/ksh" && exit 3

# sudo <everything>
grep -v "%sysadmins" /etc/sudoers | grep -v "^#" | grep -v "^root" | grep "(ALL)" | grep "ALL=(ALL)" | egrep "ALL$" && exit 4

echo Tudo OK!
exit 0

Notas:

  • como disse acima, isto é algo feito em pouco tempo; de certeza que há formas bem melhores de alcançar o mesmo resultado. Está à vontade para sugerir algumas. 🙂
  • o script abre uma excepção para um grupo “sysadmins”, que supostamente está autorizado a fazer “sudo su” para root sem problemas. Altera ou remove essa parte, conforme necessário.
  • a ideia, obviamente, é correr este script numa lista de servidores — possivelmente todos os que administras –, e de seguida verificar os exit codes (qualquer coisa diferente de 0 significa que alguém (sem ser os excepcionados) pode usar o sudo para obter uma shell de root) ou o output (qualquer coisa diferente da string “Tudo OK!” significa…). Se a tua empresa já usa um sistema para correr scripts em muitas máquinas, usa-o; caso contrário há sempre o pssh, ou um ciclo “for” em bash — por exemplo, cria um ficheiro “encontrar-sudoers.sh” com o script, e depois faz o seguinte: for i in `cat servers.txt`; do ssh root@$i < encontrar-sudoers.sh ; done
  • o método no ponto anterior, no entanto, requer que as máquinas tenham o serviço de ssh a permitir logins como root, o que em geral não é boa ideia. Assumindo que isso está (correctamente) bloqueado (PermitRootLogin no), mas que tens um utilizador que pode fazer sudo para root sem pedir password, podes fazer algo como: for i in `cat servers.txt`; do cat encontrar-sudoers.sh | ssh user@$i "cat - | sudo /bin/bash"; done
  • Se tens de introduzir uma password para fazer sudo para root, e a criação de um utilizador excepcionado não é uma opção, então terás um problema. Assumindo que não queres que o script passe a ser interactivo (obrigado a escrever uma vez uma password por máquina), então terás de arranjar outra alternativa; neste momento não estou a ver nenhuma que não introduza ela própria um novo problema de segurança. Mas de certeza que o sítio onde trabalhas já tem uma forma de correr scripts de forma não interactiva em muitas máquinas, não é? (Caso contrário, lamento…)

Deixar uma resposta