Execute apenas partes de um script como sudo, digitando a senha apenas uma vez

14

Estou escrevendo um script (na verdade uma combinação de scripts e makefile) que instala dependências externas: alguns apt-getcomandos, alguns gitclonando, construindo, instalando, adicionando usuários a grupos, ...

Algumas das operações nesses scripts requerem permissões de superusuário, outras não.

Até agora, eu executei todo o processo de criação com o sudo, mas ele tem algumas desvantagens:

  • gitrepos clono get rootcomo proprietário, o que significa que não posso modificá-los posteriormente sem sudoouchown
  • os scripts que adicionam usuários a grupos não sabem qual usuário adicionar desde que whoamiretornaroot

Qual é a melhor maneira de executar como superusuário apenas os comandos que exigem isso? Idealmente, o processo ainda exigiria que eu digite minha sudosenha, mas apenas uma vez no início do processo de instalação. Esquecê-lo-ia no final, mas mantenha-o o tempo todo até lá (pode levar várias horas).

As soluções que encontrei online incluem:

  • sudo -vno início do script, mas se eu entendi corretamente, isso expira. Meu script pode estar em execução por algumas horas
  • executando o script com sudo, mas os comandos que não precisam de superusuário sudo -u $(logname) <command>. É isso que faço agora, mas parece que deveria ser o contrário.

Idealmente, eu gostaria que meu script:

  1. solicitar credenciais de superusuário
  2. executar comandos normais como o usuário conectado
  3. execute comandos sudo com as credenciais inseridas na etapa 1
  4. sudo -k fechar a sessão de superusuário
Gauthier
fonte
2
Você ainda pode executar tudo como sudo, e seu script pode verificar a SUDO_USERvariável de ambiente. Se presente, ele conterá o nome de usuário do usuário que está chamando o sudo. Então você pode (como root) mostrar $ SUDO_USER: $ SUDO_GID $ your_files. Da mesma forma, você pode verificar essas variáveis ​​para que seus comandos adduser saibam qual usuário adicionar.
roadmr 13/02/2015
... ou execute tudo como root e use su $SUDO_USER -c commandos comandos para executar como usuário normal.
Rmano 17/02

Respostas:

7

Como você tem acesso ao sudo, crie um arquivo sudoers para si mesmo e exclua-o quando o script estiver concluído:

# grant this user access to the sudo commands without passwords
# add all required cmds to the CMDS alias
sudo tee /etc/sudoers.d/$USER <<END
$USER $(hostname) = NOPASSWD: /usr/bin/apt-get, /usr/sbin/adduser, /bin/rm, ...
END

# your script goes here
sudo apt-get install ...
git clone ...
sudo adduser group2 $USER
sudo adduser group1 $USER
: ...

# then, remove the sudo access
sudo /bin/rm /etc/sudoers.d/$USER
sudo -k
Glenn Jackman
fonte
2

Uma maneira, que eu geralmente não recomendaria, é ler a senha você mesmo e usar sudoa -Sopção para passar a senha como e quando necessário:

#! /bin/bash
IFS= read -rsp 'Enter your password: ' password
git clone ...
sudo -S apt-get install foo -y <<<"$password"

De man sudo:

 -S, --stdin
             Write the prompt to the standard error and read the password
             from the standard input instead of using the terminal device.
             The password must be followed by a newline character.
muru
fonte
1
Isso é seguro? echo "$password"??
αғsнιη
@KasiyA echo "$password"não seria, mas heredocs e herestrings são um pouco mais seguros. Eles não são visíveis na linha de comando mostrada pelas ferramentas usuais.
Muni
1
Eu acho que, estritamente falando, echo "$password"o lado esquerdo de um cachimbo está seguro em um script bash. echoé um shell embutido; /bin/echonão funciona quando é chamado simplesmente echo .... Algumas outras conchas têm um echoembutido ( dashpor exemplo), mas as conchas no estilo Bourne não são precisam ter uma. Então, eu acho que echo "$password" |é aceitável no bash, mas pode ser melhor evitado no caso de alguém portar o script para outro shell sem perceber o problema. Eu uso um não-portáteis [[, em vez de [em que o script para evitar o mesmo tipo de problema. @KasiyA
Eliah Kagan