maneira adequada de sudo sobre ssh


150

Eu tenho um script que executa outro script via SSH em um servidor remoto usando o sudo. No entanto, quando eu digito a senha, ela aparece no terminal. (Caso contrário, funciona bem)

ssh user@server "sudo script"

Qual é a maneira correta de fazer isso para que eu possa digitar a senha do sudo pelo SSH sem que a senha apareça enquanto digito?


2
quanto a mim, a razão para procurar uma maneira de sudoing através ssh foi que ela não estava funcionando quando se tenta algo como ssh <user@server> sudo <script>, como eu estava recebendo o errosudo: no tty present and no askpass program specified
knocte

Respostas:


244

Outra maneira é usar a -topção para ssh:

ssh -t user@server "sudo script"

Veja man ssh:

 -t      Force pseudo-tty allocation.  This can be used to execute arbi-
         trary screen-based programs on a remote machine, which can be
         very useful, e.g., when implementing menu services.  Multiple -t
         options force tty allocation, even if ssh has no local tty.

2
Bom, eu sabia da opção -t, mas não sabia que funcionava para os prompts do sudo.

3
qual é a opção -t?
Vince


3
Não está funcionando aqui: ssh -t localhost <<< "sudo touch file;"EDIT Aparentemente, é importante que você realmente forneça o comando como um parâmetro, não através do padrão in (o que faz sentido em retrospectiva).
Expiação limitada

o -tmétodo também mostrará saída colorida de comandos que normalmente o fazem.
precisa saber é o seguinte

24

Consegui automatizá-lo totalmente com o seguinte comando:

echo pass | ssh -tt user@server "sudo script"

Vantagens:

  • nenhuma solicitação de senha
  • não mostrará a senha no histórico do bash da máquina remota

Com relação à segurança: como Kurt disse, a execução desse comando mostrará sua senha no histórico local do bash, e é melhor salvar a senha em um arquivo diferente ou salvar o comando all em um arquivo .sh e executá-lo. NOTA: O arquivo precisa ter as permissões corretas para que somente os usuários permitidos possam acessá-lo.


8
Ele aparecerá no histórico do bash do sistema local, incluindo a senha. Melhor para armazenar a senha em um arquivo e gato o arquivo.
Kurt Fitzner #

4
Cara, eu sabia -t, mas eu não tinha lido o manual com atenção suficiente para ver que você poderia passá-lo duas vezes! É isso que estou procurando há meses! Como uma adição de segurança, simplesmente defino uma variável de senha antes de executar read -s -p "Password: " pw, e o fiz echo "$pw" | ..... Agora eu coloquei isso em um script útil para mim :).
kael

Funcionou como charme para mim!
MiKr13 12/09/19

Por que você simplesmente não configura o sudo sem senha para quaisquer usuários e comandos específicos que você precisa executar? Este não é um problema SSH ...
nomen

@nomen sua solução também é válida, mas requer etapas extras. Se eu tiver muitos dispositivos sem um usuário sudo sem senha, posso criar um script de automação usando esta solução. Às vezes, você trabalha em um sistema que não possui e não quer ou não pode fazer alterações; outras, há outras considerações.
ofirule

6

Supondo que você não queira nenhum prompt de senha :

ssh $HOST 'echo $PASSWORD | sudo -S $COMMMAND'

Exemplo

ssh me@localhost 'echo secret | sudo -S echo hi' # outputs 'hi'

14
Isso é / muito / perigoso, pois a senha em texto sem formatação termina na linha de comando. As linhas de comando são públicas e podem ser vistas por qualquer outro usuário e processo no sistema. Por exemplo, "ps auxwwwww" de um usuário sem privilégios mostrará todos os processos em execução e as linhas de comando que os executaram.
Kurt Fitzner #

3
Sem mencionar colocar sua senha (em texto sem formatação) no arquivo bash_history.
Layne Bernardo

4

Sudo sobre SSH passando uma senha, não é necessário tty:

Você pode usar o sudo sobre ssh sem forçar o ssh a ter um pseudo-tty (sem o uso da opção ssh "-t") dizendo ao sudo para não exigir uma senha interativa e apenas pegar a senha do stdin. Você faz isso usando a opção "-S" no sudo. Isso faz com que o sudo escute a senha no stdin e pare de ouvir quando vir uma nova linha.

Exemplo 1 - Comando Remoto Simples

Neste exemplo, enviamos um whoamicomando simples :

$ ssh user@server cat \| sudo --prompt="" -S -- whoami << EOF
> <remote_sudo_password>
root

Estamos dizendo ao sudo para não emitir um prompt e receber sua entrada do stdin. Isso faz com que a senha do sudo passe completamente silenciosa, de modo que a única resposta que você recebe é a saída whoami.

Essa técnica tem o benefício de permitir que você execute programas através do sudo over ssh, os quais requerem entrada stdin. Isso ocorre porque o sudo está consumindo a senha na primeira linha do stdin e, em seguida, permitindo que qualquer programa executado continue a pegar o stdin.

Exemplo 2 - Comando remoto que requer seu próprio stdin

No exemplo a seguir, o comando remoto "cat" é executado através do sudo, e estamos fornecendo algumas linhas extras através do stdin para o gato remoto exibir.

$ ssh user@server cat \| sudo --prompt="" -S -- "cat" << EOF
> <remote_sudo_password>
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2

A saída demonstra que a <remote_sudo_password>linha está sendo consumida pelo sudo e que o gato executado remotamente está exibindo as linhas extras.

Um exemplo de onde isso seria benéfico é se você deseja usar o ssh para passar uma senha para um comando privilegiado sem usar a linha de comando. Digamos, se você deseja montar um contêiner criptografado remoto sobre ssh.

Exemplo 3 - Montagem de um contêiner VeraCrypt remoto

Neste script de exemplo, estamos montando remotamente um contêiner VeraCrypt através do sudo sem nenhum texto extra de solicitação:

#!/bin/sh
ssh user@server cat \| sudo --prompt="" -S -- "veracrypt --non-interactive --stdin --keyfiles=/path/to/test.key /path/to/test.img /mnt/mountpoint" << EOF
SudoPassword
VeraCryptContainerPassword
EOF

Deve-se observar que em todos os exemplos de linha de comando acima (tudo, exceto o script), a << EOFconstrução na linha de comando fará com que tudo que for digitado, incluindo a senha, seja gravado no arquivo .bash_history da máquina local . Portanto, é altamente recomendável que, para uso no mundo real, você o faça inteiramente por meio de um script, como o exemplo veracrypt acima, ou, se na linha de comando, coloque a senha em um arquivo e redirecione-o através do ssh.

Exemplo 1a - Exemplo 1 sem senha de linha de comando local

O primeiro exemplo seria assim:

$ cat text_file_with_sudo_password | ssh user@server cat \| sudo --prompt="" -S -- whoami
root

Exemplo 2a - Exemplo 2 sem senha de linha de comando local

e o segundo exemplo seria:

$ cat text_file_with_sudo_password - << EOF | ssh va1der.net cat \| sudo --prompt="" -S -- cat
> Extra line1
> Extra line2
> EOF
Extra line1
Extra line2

Colocar a senha em um arquivo separado é desnecessário se você estiver colocando a coisa toda em um script, pois o conteúdo dos scripts não termina no seu histórico. Ainda pode ser útil, no entanto, caso você queira permitir que usuários que não devem ver a senha executem o script.


No comando ssh remote, por que você precisa executar cate canalizar os resultados no sudo? Você pode apenas usar sudocomo o principal comando remoto ssh?
Joanpau 21/05/19

@joanpau A inicial caté usada para canalizar a senha do usuário para o sudo do outro lado. Se o usuário puder executar o sudo sem uma senha, isso não será necessário, mas não sugiro essa configuração. O motivo pelo qual é canalizado é impedir que a senha seja exibida na linha de comando do sistema remoto. As linhas de comando não são seguras; qualquer usuário pode ver todas as linhas de comando ps auxwww.
Kurt Fitzner 23/05/19

Estou solicitando cato comando ssh cat \| sudo --prompt="" -S.... Se as -Sforças sudopara ler a senha do stdin, o gato e o cachimbo são necessários? O comando ssh poderia ser simplesmente sudo --prompt="" -S...?
joanpau 4/06/19

@jonpau Esse comando cat está usando o stdin e o conduz através do sudo para passar a senha do sudo. Está mostrando como você pode canalizar a senha do sudo através do ssh via stdin com segurança.
Kurt Fitzner 5/06/19

1

A melhor maneira é ssh -t user@server "sudo <scriptname>", por exemplo ssh -t user@server "sudo reboot". Ele solicitará a senha do usuário primeiro e depois a raiz (já que estamos executando o script ou comando com privilégio de raiz.

Espero que tenha ajudado e esclarecido sua dúvida.




-1

Eu enfrentei um problema,

user1@server1$ ssh -q user1@server2 sudo -u user2 rm -f /some/file/location.txt

Output:
sudo: no tty present and no askpass program specified

Então eu tentei com

#1
vim /etc/sudoers
Defaults:user1    !requiretty

não funcionou

#2
user1   ALL=(user2)         NOPASSWD: ALL

que funcionou corretamente!


Isso realmente não realiza o que está sendo solicitado. A idéia é ainda exigir a senha, mas permitir que ela seja digitada sobre ssh. O que você fez é apenas dar acesso total ao usuário1 ao usuário2, sem uma senha. Isso é bom para aplicativos específicos, mas não é a melhor idéia como solução geral.
Possum

-7

Dependendo do seu uso, obtive sucesso com o seguinte:

ssh root@server "script"

Isso solicitará a senha root e, em seguida, execute o comando corretamente.


26
Caramba, SSH como root? Essa é uma má idéia por todos os tipos de razões.
darkfeline

12
Lembre-se de que ssh não é telnet. Não é mais perigoso ssh como root do que seria para ssh como outro usuário e execute o sudo. Sua senha é criptografada da mesma maneira na conexão ssh.
Stéphane

22
Stéphane está absolutamente correto no que diz respeito à segurança da senha. No entanto, usando raiz em vez de sudo, você perde a trilha de auditoria que acompanha o sudo. Além disso, o acesso root pode não estar disponível.
Djikyb
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.