escrever um script de shell para ssh para uma máquina remota e executar comandos

97

Eu tenho duas perguntas:

  1. Existem várias máquinas Linux remotas, e preciso escrever um script de shell que executará o mesmo conjunto de comandos em cada máquina. (Incluindo algumas operações de sudo). Como isso pode ser feito usando script de shell?
  2. Ao enviar por ssh para a máquina remota, como lidar com quando ele solicitar autenticação de impressão digital RSA.

As máquinas remotas são VMs criadas em execução e eu apenas tenho seus IPs. Portanto, não posso colocar um arquivo de script de antemão nessas máquinas e executá-los em minha máquina.

Balanivash
fonte
Penso em implantar um programa semelhante a um agente em máquinas Linux remotas, que mantêm a conexão com o servidor por meio de conexão de soquete de rede (ou SSL) / por pesquisa periódica para o servidor.
Raptor
Preciso executar um conjunto de comandos apenas uma vez, portanto, não é necessário manter a conexão
Balanivash
"nenhum script" significa "nenhum arquivo", suponho? Como você lida com a autenticação? Você pode desabilitar a verificação de impressão digital do host (veja minha resposta), mas você ainda receberá um prompt de senha interativo se não tiver configurado uma chave pública / privada.
Andreas Fester
1
Andreas: sim. nenhum arquivo. o prompt passwd pode ser tratado usando expectcomo `esperar" ? assword: "`
Balanivash

Respostas:

141

Existem várias máquinas Linux remotas, e preciso escrever um script de shell que executará o mesmo conjunto de comandos em cada máquina. (Incluindo algumas operações de sudo). Como isso pode ser feito usando script de shell?

Você pode fazer isso com ssh, por exemplo:

#!/bin/bash
USERNAME=someUser
HOSTS="host1 host2 host3"
SCRIPT="pwd; ls"
for HOSTNAME in ${HOSTS} ; do
    ssh -l ${USERNAME} ${HOSTNAME} "${SCRIPT}"
done

Ao enviar por ssh para a máquina remota, como lidar com quando ele solicitar autenticação de impressão digital RSA.

Você pode adicionar a StrictHostKeyChecking=noopção de ssh:

ssh -o StrictHostKeyChecking=no -l username hostname "pwd; ls"

Isso desabilitará a verificação da chave do host e adicionará automaticamente a chave do host à lista de hosts conhecidos. Se você não quiser que o host seja adicionado ao arquivo de hosts conhecidos, adicione a opção -o UserKnownHostsFile=/dev/null.

Observe que isso desativa certas verificações de segurança , por exemplo, proteção contra ataques man-in-the-middle. Portanto, não deve ser aplicado em um ambiente sensível à segurança.

Andreas Fester
fonte
Qual é a linguagem de script? Você também pode chamar sshde qualquer script de shell
Andreas Fester
e se você também quiser fazer um CTRL + C e continuar ssh para vários servidores ?. por exemplo, em alguns servidores está pedindo senha e em outros não, então o script vai ficar preso aí. existe uma maneira de fazer algo semelhante a -o para fazer CTRL c ou CTRL d?
Chanafot
5

Existem várias maneiras de lidar com isso.

Minha maneira favorita é instalar http://pamsshagentauth.sourceforge.net/ nos sistemas remotos e também sua própria chave pública. (Descubra uma maneira de instalá-los na VM, de alguma forma, você tem um sistema Unix inteiro instalado, o que são mais alguns arquivos?)

Com o seu agente ssh encaminhado, agora você pode fazer login em todos os sistemas sem uma senha.

E ainda melhor, esse módulo pam autenticará para sudo com seu par de chaves ssh para que você possa executar com direitos de root (ou de qualquer outro usuário) conforme necessário.

Você não precisa se preocupar com a interação da chave do host. Se a entrada não for um terminal, o ssh apenas limitará sua capacidade de encaminhar agentes e autenticar com senhas.

Você também deve procurar pacotes como o Capistrano.Definitivamente, dê uma olhada nesse site; ele contém uma introdução ao script remoto.

As linhas de script individuais podem ter a seguinte aparência:

ssh remote-system-name command arguments ... # so, for exmaple,
ssh target.mycorp.net sudo puppet apply
DigitalRoss
fonte
4

Instale o sshpass usando, apt-get install sshpassentão edite o script e coloque os IPs, nomes de usuário e senha de suas máquinas Linux na respectiva ordem. Depois disso, execute o script. É isso aí ! Este script instalará o VLC em todos os sistemas.

#!/bin/bash
SCRIPT="cd Desktop; pwd;  echo -e 'PASSWORD' | sudo -S apt-get install vlc"
HOSTS=("192.168.1.121" "192.168.1.122" "192.168.1.123")
USERNAMES=("username1" "username2" "username3")
PASSWORDS=("password1" "password2" "password3")
for i in ${!HOSTS[*]} ; do
     echo ${HOSTS[i]}
     SCR=${SCRIPT/PASSWORD/${PASSWORDS[i]}}
     sshpass -p ${PASSWORDS[i]} ssh -l ${USERNAMES[i]} ${HOSTS[i]} "${SCR}"
done
Arjun G Perambra
fonte
use $ SSHPASS para exportar a senha para evitar a exibição no script. Ref: tecmint.com/…
Hexy
2

Se você é capaz de escrever código Perl, deve considerar o uso de Net :: OpenSSH :: Parallel .

Você seria capaz de descrever as ações que devem ser executadas em cada host de maneira declarativa e o módulo cuidará de todos os detalhes assustadores. sudoTambém há suporte para a execução de comandos .

salva
fonte
2

Este trabalho para mim.

Sintaxe: ssh -i pemfile.pem user_name @ ip_address 'command_1; comando 2; comando 3 '

#! /bin/bash

echo "########### connecting to server and run commands in sequence ###########"
ssh -i ~/.ssh/ec2_instance.pem ubuntu@ip_address 'touch a.txt; touch b.txt; sudo systemctl status tomcat.service'
Viraj Wadate
fonte
1

Para este tipo de tarefas, eu uso repetidamente Ansible, que permite duplicar scripts bash coerentemente em vários contêineres ou VM. Ansible (mais precisamente Red Hat ) agora tem uma interface da web adicional AWX que é a edição de código aberto de sua Torre comercial.

Ansible: https://www.ansible.com/
AWX: https://github.com/ansible/awx
Ansible Tower: produto comercial, você provavelmente irá explorar o AWX de código aberto gratuito, em vez da trilha gratuita de 15 dias da torre

Fibo
fonte
1

Existem várias maneiras de executar os comandos ou script nas várias máquinas Linux remotas. Uma maneira simples e fácil é via pssh (programa ssh paralelo)

pssh : é um programa para executar ssh em paralelo em vários hosts. Ele fornece recursos como o envio de entrada para todos os processos, passagem de uma senha para ssh, salvamento da saída em arquivos e tempo limite.

Exemplo e uso:

conecte-se ao host1 e host2 e imprima "hello, world" de cada um:

 pssh -i -H "host1 host2" echo "hello, world"

Execute comandos por meio de um script em vários servidores:

pssh -h hosts.txt -P -I<./commands.sh

Use e execute um comando sem verificar ou salvar as chaves do host:

pssh -h hostname_ip.txt -x '-q -o StrictHostKeyChecking=no -o PreferredAuthentications=publickey -o PubkeyAuthentication=yes' -i  'uptime; hostname -f'

Se o arquivo hosts.txt tiver um grande número de entradas, digamos 100, a opção de paralelismo também pode ser definida como 100 para garantir que os comandos sejam executados simultaneamente:

pssh -i -h hosts.txt -p 100 -t 0 sleep 10000

Opções :
-I: Lê a entrada e envia para cada processo ssh.
-P: Diz ao pssh para exibir a saída assim que ela chegar.
-h: Lê o arquivo do host.
-H: [usuário @] host [: porta] para host único.
-i: Exibe a saída padrão e o erro padrão conforme cada host conclui
-x args: Passa argumentos de linha de comando SSH extras
-o opção: Pode ser usado para fornecer opções no formato usado no arquivo de configuração. (/ etc / ssh / ssh_config ) (~ / .ssh / config)
-p paralelismo: Use o número fornecido como o número máximo de conexões simultâneas
-q Modo silencioso: Faz com que a maioria das mensagens de aviso e diagnóstico sejam suprimidas.
-t: Estabelece o tempo limite das conexões após um determinado número de segundos. 0 significa que o pssh não irá desligar nenhuma conexão

Ao enviar por ssh para a máquina remota, como lidar com quando ele solicitar autenticação de impressão digital RSA.

Desative o StrictHostKeyChecking para lidar com o prompt de autenticação RSA.
-o StrictHostKeyChecking = não

Fonte : man pssh

Skanda Shastry
fonte
0

Isso funcionou para mim. Eu fiz uma função. Coloque isso em seu script de shell:

sshcmd(){
    ssh $1@$2 $3
}

sshcmd USER HOST COMMAND

Se você tiver várias máquinas nas quais deseja executar o mesmo comando, deverá repetir essa linha com um ponto e vírgula. Por exemplo, se você tiver duas máquinas, faria isso:

sshcmd USER HOST COMMAND ; sshcmd USER HOST COMMAND

Substitua USER pelo usuário do computador. Substitua HOST pelo nome do computador. Substitua COMMAND pelo comando que você deseja executar no computador.

Espero que isto ajude!

Contribuidor Anônimo
fonte
-1

Você pode seguir esta abordagem:

  • Conecte-se à máquina remota usando o Expect Script . Se sua máquina não oferece suporte, você pode fazer o download do mesmo. Escrever o script Expect é muito fácil (google para obter ajuda sobre isso)
  • Coloque todas as ações que precisam ser executadas no servidor remoto em um script de shell.
  • Chame o script de shell remoto a partir do script de espera quando o login for bem-sucedido.
rai.skumar
fonte
Como mencionei na pergunta, as máquinas remotas são criadas durante a execução e não posso ter nenhum script na máquina de antemão.
Balanivash de
Nesse caso, coloque todas as ações no script Esperar. O script Expect também pode executar comandos no host remoto.
rai.skumar