Forçar o SSH a usar um shell específico

29

Existe alguma maneira de forçar o SSH a usar um shell específico na extremidade remota, independentemente do shell padrão do usuário?

Eu tentei soluções semelhantes a:

ssh host.domain.com /bin/bash -c 'complicated, multi-line command'

mas, infelizmente, o shell padrão na extremidade remota é responsável por analisar a parte "complicado, comando de várias linhas", e estou tendo dificuldades em evitá-lo o suficiente para funcionar tanto para usuários de shell Bash quanto C.

plinehan
fonte

Respostas:

8

Eu não acredito que isso seja possível, pelo menos com sistemas baseados em openssh. Se você tiver a capacidade, uma solução melhor pode ser a de sftp de um arquivo de script de shell e, em seguida, executá-lo com o método que você postou. Teria a vantagem de minimizar a quantidade de escape necessária, mas deixaria um arquivo para trás que precisaria ser removido (talvez como a última etapa do script).

sysadmin1138
fonte
1
Isto é o que eu finalmente fiz, mas usando scp. Uma ótima ideia.
21810 plinehan
16

Use um heredoc:

ssh host.domain.com /bin/bash << EOF
big ugly commands
lots of them
EOF
Ignacio Vazquez-Abrams
fonte
você não deve usar "-s" no bash para ler comandos do stdin?
Weboide
Nem sempre é necessário.
Ignacio Vazquez-Abrams
Eu votaria nisso se pudesse, porque isso impede que os comandos tenham acesso ao stdin e a pergunta era sobre invocar um shell específico.
Eric Woodruff
3
@ EricWoodruff, ... invocar um shell específico (neste caso, bash) é exatamente o que isso mostra como fazer.
Charles Duffy
1
FYI você também pode fazer cat /tmp/tempfile_containing_your_script ssh ${hostname} /bin/bash. Portanto, em vez de uma etapa, você tem duas etapas: etapa 1 copie seu script em um arquivo, etapa 2 cato script para ssh.
Trevor Boyd Smith
10

Use logins baseados em chave, não com senha. Em seguida, você pode adicionar (uma lista de) "comandos forçados" à sua chave pública ssh (no campo "opções" no caso do SSH1) que está instalada no servidor (no arquivo ~ / .ssh / allowed_keys para SSH1 , ~ / .ssh2 / autorização para SSH2).

Faça seu comando forçado para que o shell desejado seja chamado ...

Mais: você pode associar no máximo um comando forçado a uma determinada chave. Se você precisar de vários comandos forçados para diferentes propósitos, precisará configurar chaves diferentes. (É claro que você pode colocar várias coisas em um script, que você chama por comando forçado. Mas lembre-se de que comandos forçados sempre são executados para uma determinada conta / chave se o usuário efetuar login, independentemente de pedir algo diferente para executar. Se você ainda deseja honrar o comando original solicitado, veja como explorar a $SSH_ORIGINAL_COMMANDvariável ...)

Leia sobre "comandos forçados" via Google .

Kurt Pfeifle
fonte
Coisa boa. Esse gráfico na página O'Reilly é muito bom. No meu caso particular, no entanto, quero poder forçar isso para qualquer usuário, não apenas para os usuários que configuraram suas chaves corretamente. Também não tenho raiz nas máquinas servidoras, portanto não consigo editar arquivos como /etc/sshrc.
plinehan
Bem, é sempre o servidor (ou melhor: aquele que exerce controle sobre o servidor) quem dá os tiros quando você se conecta ao seu serviço .... O 'proprietário' do servidor decide o que pode ser feito com ele. - Você não pode forçar nada 'para nenhum usuário' se não tiver privilégios mais altos que eles.
Kurt Pfeifle
Se o cliente puder executar comandos arbitrários, também poderá executar um shell arbitrário como um comando.
22416 Eric
@KurtPfeifle que apontam para O'Reilly está quebrado
Brian Vandenberg
@BrianVandenberg: Thx pela dica. Eu removi esse link agora.
Kurt Pfeifle
2

Você pode usar a -topção para forçar a alocação de uma pseudo-tty para o programa que deseja iniciar, como se estivesse executando o shell padrão. Em seguida, passe o shell que você deseja como um argumento antigo simples.

Com essa técnica, você pode não apenas usar qualquer shell instalado, mas também abrir o vim e outros programas que requerem um TTY, a partir de um único comando. O que é legal se você estiver escrevendo um script de shell que o conecta em algum lugar e abre um arquivo no vim, htop ou algo assim.

me@my-machine $ ssh root@myhost -t bash
root@myhost:~# exit
Connection to myhost closed.
me@my-machine $ ssh root@myhost -t sh
# exit
Connection to myhost closed.
me@my-machine $ 

Não tenho certeza se esse é um shell de logon, mas há opções para fazer o bash agir como um shell de logon, portanto, seu shell pode ter isso também.

Fábio Santos
fonte
1

Surpreendentemente, vejo resultados diferentes com o seguinte:

executar no traço:

ssh eric@172.17.1.241 /bin/bash -c "echo <(cat)"                                              
sh: 1: Syntax error: "(" unexpected

vs bash:

ssh eric@172.17.1.241 '/bin/bash -c "echo <(cat)"'                                            
/dev/fd/63

Mostrar o comando completo entre aspas está funcionando conforme o esperado.

Eric Woodruff
fonte
1
Não é de todo surpreendente. O daemon ssh remoto é executado efetivamente sh -c "$*". Assim, você está correndo sh -c "/bin/bash -c echo <(cat)"; o echocomando em si é o único argumento passado para -c, e o <(cat)é um argumento completamente separado.
Charles Duffy
0

Há algum tempo, enfrentei uma situação semelhante em que precisava usar o coprocesso ksh para sqlplus e só tinha um ssh através do qual leituras e gravações deveriam ocorrer.

Uma maneira de fazer isso é canalizar todo o comando dependente em uma linha (use;) para / usr / bin / ksh na máquina remota. por exemplo:

host="user@host"

db_conn="ora_user/passwd"

a="select * from dual;"

frmt="set heading off echo off feedback off verify off pagesize 0 termout off"

var=$(ssh ${host} "echo 'sqlplus -silent /nolog |&; sql_pid=\$!; print -p \"conn ${db_conn}\"; print -p \"${frmt}\"; print -p \"${a}\"; print -p \"exit\"; wait \$sql_pid' > /remote_dir/kshcmd.txt; awk '{print \$0}' /remote_dir/kshcmd.txt | /usr/bin/ksh")
aws
fonte