Como inserir a senha apenas uma vez em um script bash que precisa do sudo

21

Dados

  • Quero que os usuários do operador nesta máquina montem seus próprios compartilhamentos cifs
  • O sudoersarquivo já contém o /bin/mount -t cifs //*/* /media/* -o username=*comando para todos os operadores
  • Quero que os usuários montem um cifscompartilhamento por meio de um script digitando a senha apenas uma vez, não duas.
  • A senha do sudo e a senha do cifs são idênticas.

O que eu já tenho

Este script funciona:

#!/bin/bash
sudo 'mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... mas exige que os usuários digitem a mesma senha duas vezes!

  • Uma vez para sudo
  • Uma vez para a própria montagem

Isso também funcionaria:

#!/bin/bash
echo -n Password: 
read -s szPassword
echo $szPassword | sudo -S sh -c 'echo $szPassword | mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER'

... mas isso exigiria que eu permitisse a todos os usuários da operadorasudo sh (grande problema de segurança)

Questão

Como montar um compartilhamento cifs no bash ¹ sem colocar shno sudoersarquivo nem criar um arquivo permanente / temporário ???

Nota 1: sem python, perl, C, Go, ... por favor?
Nota 2: Eu sei que posso remover a senha através do sudoersarquivo, mas estou tentando aumentar a segurança, não afrouxá-la, sem abrir mão da conveniência ...

Fabby
fonte
2
Que tal printf "%s\n" "$szPassword" "$szPassword" | sudo -S mount -t cifs / ...?
Muru
Tentando isso agora! @Muru
Fabby

Respostas:

24

Em vez disso, você deve fazer com que o usuário faça a chamada usando sudo as sudo script. basta verificar se o script está sendo executado como root, se não pedir

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root, use sudo "$0" instead" 1>&2
   exit 1
fi

Não tente capturar a senha dos seus usuários.

Braiam
fonte
1
Talvez esteja faltando alguma coisa, mas você pode explicar como isso reduz o número de solicitações de senha de dois para um? Caso contrário, não vejo como isso responde à pergunta.
Oliphaunt - reinstala Monica
@ Oliphaunt Não vejo duas solicitações de senha, você pode explicar isso? Além disso, essa resposta não é o que o OP deseja, mas o que ele precisa. É limpo e solução adequada quando você precisa executar comandos como root, e como outras utilidades que (verifique se a raiz, caso contrário socorrer)
Braiam
1
O problema do OP (como eu o entendo) é que o usuário solicita sua senha sudoe depois (após a autenticação com êxito) novamente mount. No caso de uso, essas senhas são idênticas, portanto, posso ver por que o OP gostaria que o usuário tivesse que digitar essa senha apenas uma vez. Não acredito que sua solução ajude com isso. Concordo que não se deve capturar senhas.
Oliphaunt - reinstala Monica
Obrigado, mas eu posso ter simplificado um pouco a pergunta: já é um script, já contém esse teste (exceto o 1>&2), está no arranque automático e costumava ser apenas um compartilhamento CIF, mas agora são três, então realmente uma senha é preciso. (Ele já contém esse teste no caso de outra pessoa, que não seja membro do grupo de operadores, tenta executá-lo)
Fabby
@ Fabby Eu ainda acho que você está abordando o problema incorretamente. Nesses casos, há um auxiliar para "lembrar" a senha de um compartilhamento CIFS / SMB com segurança (editando ~/.smbcredentialspor exemplo) e mesmo sem a necessidade do sudo (se você usar gvfs, umount ou polkit).
Braiam
7

Eu sou estúpido!

O seguinte script:

#!/bin/bash
read -p "Password: " -s szPassword
printf "%s\n" "$szPassword" | sudo --stdin mount -t cifs //192.168.1.1/home /media/$USER/home -o username=$USER,password="$szPassword"

apenas funciona e:

  1. Não cria nenhum arquivo contendo senhas
  2. Permite ao usuário digitar apenas uma senha para vários compartilhamentos (incluindo os do Windows)
  3. Não é necessário conceder privilégios extras. :-)
Fabby
fonte
1
1 pergunta: isso faz eco do comando na lista de processos?
Rinzwind
3
@Rinzwind como um built-in, não deve no bash ou zsh. O comando mount poderia, no entanto.
Muru
<<<também poderia ser usado em vez de printf , mas uma abordagem melhor seria abandonar readcompletamente e usar apenas sudo --stdinsozinha. Algo como $ printf "Type out your password\n" && sudo --stdin apt-get update Usuário ainda pode digitar a senha do sudo. e isso não será colocado na lista de processos. Mas é claro que há quantidade infinita de possíveis outros problemas de segurança, como keyloggers, vulnerabilidades potenciais em sudo, e blá e blá, blá e até o infinito
Sergiy Kolodyazhnyy
@SergiyKolodyazhnyy: Sinta-se livre para editar , cara!
Fabby
3

Não requer sudosenha para executar este comando; a solicitação de senha mountpermanece.

Em sudoers, inclua algo como

ALL        ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*

Após incluir isso, sudonão solicitará mais uma senha para este comando específico; o usuário ainda precisa fornecer uma senha para o mountcomando.

Nota : Eu peguei o comando literalmente do que você incluiu na pergunta; Não verifiquei se seus curingas permitiriam que os usuários fizessem algo desagradável. Leia a página de sudoersmanual para exemplos de maldade. Em particular, observe que essa linha sudoerspermite que o usuário adicione qualquer número de -oopções ou outros argumentos mount. Você pode repensar sua abordagem, por exemplo, adicionando um script como o @Braiam propõe e permitir executar isso sudosem autenticação extra. O script garante que os usuários possam executar apenas a forma específica mountque você deseja que eles executem.

Além disso, em vez de permitir isso para todos os usuários, você também pode limitar isso aos membros de um determinado grupo; por exemplo, você pode criar um grupo cifsmounte, em seguida, ter

%cifsmount ALL = NOPASSWD: /bin/mount -t cifs //*/* /media/* -o username=*
Oliphaunt - restabelecer Monica
fonte
@ Fabby Desculpe, mas o que há de tão perigoso nisso? Também posso estar detectando uma pitada de sarcasmo, não tenho certeza.
Oliphaunt - restabelece Monica
bem, mesmo que o sudo não exija uma senha, a montagem ainda pode exigir uma senha. O arquivo / etc / sudoers pode ser usado apenas para fazer com que o sudo não exija uma senha. Isso não afetaria se a montagem solicita uma senha. Se uma pessoa falha na montagem, o sudo acaba executando um comando que falha, o que provavelmente não é um problema.
TOOGAM
@TOOGAM Essa era minha intenção. Uma senha em vez de duas.
Oliphaunt - restabelece Monica
Minha intenção é manter um grupo de "operadores" no arquivo sudoers, para que, se um operador tentar montar suas próprias coisas, ele ainda precisará digitar uma senha, mas para montar as montagens de operador "padrão", ele apenas precisará digitar a senha uma vez em vez de 5 vezes ... Mas a sua solução de trabalho poder para os outros, de modo upvoted ... (e comentários originais removidos)
Fabby
1

Uma solução geral para esses problemas é colocar o seguinte preâmbulo no topo do seu sudo, exigindo scripts:

#!/bin/bash
case $EUID in
   0) : cool we are already root - fall through ;;
   *) # not root, become root for the rest of this session
      # (and ask for the sudo password only once)
      sudo $0 "$@" ;;
esac
# now the present process is effective-UID  (root)
# so there's no need to put sudo in front of commands

any more commands here will run as superuser ...

Obviamente, isso tem uma desvantagem: se alguns comandos no script não precisarem sudoser executados, haverá uma elevação desnecessária de privilégios aqui.

Enfim, pensei em compartilhar essa pequena dica. A coisa mais legal sobre isso é que, se você já é um usuário-uid root eficaz (por exemplo, se você já o chamou no sudo), ele faz a coisa certa com elegância. Também dar um erro e forçá-lo a redigitar / executar novamente (com sudo) é menos amigável.

Você também pode verificar a timestamp_timeoutvariável na man 5 sudoersqual é sudonecessário lembrar as credenciais do usuário por um número limitado de minutos (e pode ser fracionário).

arielf
fonte
Simplifiquei demais o script para obter uma resposta fácil: o script já contém: #test if root: if not: bail out if [[ $EUID -ne 0 ]]; then echo "This script must be run as root, use sudo "$0" instead" 1>&2 exit 1 fi O ponto é que ele também contém várias montagens, todas com a mesma senha (novamente: removidas), mas, de qualquer forma, obrigado ...
Fabby
1
O ponto é que a solução acima exigiria apenas uma digitação da senha (para sudo). Não deveria exigir outro. Além disso, é geral (e mais elegante do que dar um erro e ter que redigitar o comando com sudo) para todos os problemas semelhantes, mesmo quando eles exigem vários comandos (mais de dois) privilegiados.
Arielf 26/12/2015
Ele deve mas não faz ! ;-) Isso porque cada montagem CIFs compartilha também exige uma senha. (como pode ser diferente da senha Ubuntu, mas neste caso não é que os operadores de manter suas senhas do Windows e Ubuntu sincronizado)
Fabby