escribir un script de shell para ssh en una máquina remota y ejecutar comandos

97

Tengo dos preguntas:

  1. Hay varias máquinas Linux remotas, y necesito escribir un script de shell que ejecutará el mismo conjunto de comandos en cada máquina. (Incluidas algunas operaciones sudo). ¿Cómo se puede hacer esto usando scripts de shell?
  2. Al enviar un mensaje a la máquina remota, cómo manejar cuando solicita la autenticación de huellas digitales RSA.

Las máquinas remotas son máquinas virtuales creadas sobre la marcha y solo tengo sus direcciones IP. Entonces, no puedo colocar un archivo de script de antemano en esas máquinas y ejecutarlas desde mi máquina.

Balanivash
fuente
Pienso en implementar un programa similar a un agente en máquinas remotas de Linux, que mantienen la conexión con el servidor mediante conexión de socket de red (o SSL) / mediante sondeo periódico al servidor.
Raptor
Necesito ejecutar un conjunto de comandos solo una vez, por lo que no es necesario mantener la conexión
Balanivash
"sin scripts" significa "sin archivos", supongo. ¿Cómo maneja la autenticación? Puede deshabilitar la verificación de huellas dactilares del host (consulte mi respuesta), pero aún recibe una solicitud de contraseña interactiva si no ha configurado una clave pública / privada.
Andreas Fester
1
Andreas: si. no hay archivos en absoluto. el indicador de contraseña se puede manejar usando expectcomo `esperar" ? assword: "`
Balanivash

Respuestas:

141

Hay varias máquinas Linux remotas, y necesito escribir un script de shell que ejecutará el mismo conjunto de comandos en cada máquina. (Incluidas algunas operaciones sudo). ¿Cómo se puede hacer esto usando scripts de shell?

Puede hacer esto con ssh, por ejemplo:

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

Al enviar un mensaje a la máquina remota, cómo manejar cuando solicita la autenticación de huellas digitales RSA.

Puede agregar la StrictHostKeyChecking=noopción a ssh:

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

Esto desactivará la verificación de la clave del host y agregará automáticamente la clave del host a la lista de hosts conocidos. Si no desea que el host se agregue al archivo de hosts conocidos, agregue la opción -o UserKnownHostsFile=/dev/null.

Tenga en cuenta que esto deshabilita ciertas comprobaciones de seguridad , por ejemplo, la protección contra un ataque de intermediario. Por lo tanto, no debe aplicarse en un entorno sensible a la seguridad.

Andreas Fester
fuente
¿Qué es el lenguaje de secuencias de comandos? Por supuesto, también puede llamar sshdesde cualquier script de shell
Andreas Fester
¿Qué pasa si también quieres hacer CTRL + C y continuar ssh a varios servidores? por ejemplo, en algunos servidores se solicita contraseña y en otros no, por lo que el script se atasca allí. ¿Hay alguna forma de hacer algo similar a -o para hacer CTRL c o CTRL d?
Chanafot
5

Hay varias formas de manejar esto.

Mi forma favorita es instalar http://pamsshagentauth.sourceforge.net/ en los sistemas remotos y también su propia clave pública. (Encuentre una manera de instalarlos en la VM, de alguna manera tiene instalado un sistema Unix completo, ¿qué son un par de archivos más?)

Con su agente ssh reenviado, ahora puede iniciar sesión en todos los sistemas sin una contraseña.

Y aún mejor, ese módulo pam se autenticará para sudo con su par de claves ssh para que pueda ejecutar con derechos de root (o de cualquier otro usuario) según sea necesario.

No necesita preocuparse por la interacción de la clave del host. Si la entrada no es una terminal, ssh limitará su capacidad para reenviar agentes y autenticarse con contraseñas.

También debería buscar paquetes como Capistrano. Definitivamente mire alrededor de ese sitio; tiene una introducción a las secuencias de comandos remotas.

Las líneas de secuencia de comandos individuales podrían verse así:

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

Instale sshpass usando, apt-get install sshpassluego edite el script y coloque las direcciones IP, los nombres de usuario y la contraseña de sus máquinas Linux en el orden respectivo. Después de eso, ejecute ese script. Eso es ! Este script instalará VLC en todos los 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
fuente
use $ SSHPASS para exportar la contraseña para evitar que se muestre en el script. Ref: tecmint.com/…
Hexy
2

Si puede escribir código Perl, debería considerar usar Net :: OpenSSH :: Parallel .

Podría describir las acciones que deben ejecutarse en cada host de manera declarativa y el módulo se encargará de todos los detalles aterradores. sudoTambién se admite la ejecución de comandos .

salva
fuente
2

Esto funciona para mí.

Sintaxis: ssh -i pemfile.pem nombre_usuario @ dirección_ip '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
fuente
1

Para este tipo de tareas, utilizo repetidamente Ansible que permite duplicar coherentemente scripts bash en varios contenedores o VM. Ansible (más precisamente Red Hat ) ahora tiene una interfaz web adicional AWX que es la edición de código abierto de su Tower comercial.

Ansible: https://www.ansible.com/
AWX: https://github.com/ansible/awx
Ansible Tower: producto comercial, probablemente explorará primero el AWX gratuito de código abierto, en lugar del free-trail de 15 días de la torre

Fibonacci
fuente
1

Hay varias formas de ejecutar los comandos o secuencias de comandos en las múltiples máquinas Linux remotas. Una forma simple y fácil es a través de pssh (programa ssh paralelo)

pssh : es un programa para ejecutar ssh en paralelo en varios hosts. Proporciona funciones como enviar entradas a todos los procesos, pasar una contraseña a ssh, guardar la salida en archivos y agotar el tiempo de espera.

Ejemplo y uso:

Conéctese a host1 y host2 e imprima "hola, mundo" de cada uno:

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

Ejecute comandos a través de una secuencia de comandos en varios servidores:

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

Utilice y ejecute un comando sin verificar ni guardar las claves de host:

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

Si el archivo hosts.txt tiene una gran cantidad de entradas, digamos 100, entonces la opción de paralelismo también puede establecerse en 100 para garantizar que los comandos se ejecuten simultáneamente:

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

Opciones :
-I: Leer entrada y enviar a cada proceso ssh.
-P: Le dice a pssh que muestre la salida a medida que llega.
-h: Lee el archivo del host.
-H: [usuario @] host [: puerto] para un solo host.
-i: muestra la salida estándar y el error estándar a medida que cada host completa
-x args: pasa argumentos de línea de comandos SSH adicionales
-o opción: puede usar para proporcionar opciones en el formato utilizado en el archivo de configuración. (/ etc / ssh / ssh_config ) (~ / .ssh / config)
-p paralelismo: use el número dado como el número máximo de conexiones simultáneas
-q Modo silencioso: provoca que se supriman la mayoría de los mensajes de advertencia y diagnóstico.
-t: Hace que las conexiones se agoten después del número de segundos especificado. 0 significa que pssh no agotará el tiempo de espera de ninguna conexión

Al enviar un mensaje a la máquina remota, cómo manejar cuando solicita la autenticación de huellas digitales RSA.

Deshabilite StrictHostKeyChecking para manejar la solicitud de autenticación RSA.
-o StrictHostKeyChecking = no

Fuente : man pssh

Skanda Shastry
fuente
0

Esto funcionó para mí. Hice una función. Pon esto en tu script de shell:

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

sshcmd USER HOST COMMAND

Si tiene varias máquinas en las que desea hacer el mismo comando, repetiría esa línea con un punto y coma. Por ejemplo, si tiene dos máquinas, haría esto:

sshcmd USER HOST COMMAND ; sshcmd USER HOST COMMAND

Reemplace USER con el usuario de la computadora. Reemplace HOST con el nombre de la computadora. Reemplace COMMAND con el comando que desea hacer en la computadora.

¡Espero que esto ayude!

Colaborador anónimo
fuente
-1

Puede seguir este enfoque:

  • Conéctese a la máquina remota usando Expect Script . Si su máquina no es compatible, puede descargar el mismo. Escribir el script de Expect es muy fácil (google para obtener ayuda sobre esto)
  • Ponga toda la acción que debe realizarse en el servidor remoto en un script de shell.
  • Invoque el script de shell remoto desde el script esperado una vez que el inicio de sesión sea exitoso.
rai.skumar
fuente
Como mencioné en la pregunta, las máquinas remotas se crean sobre la marcha y no puedo tener ningún script en la máquina de antemano.
Balanivash
En ese caso, ponga todas las acciones en el script Expect. El script Expect también puede ejecutar comandos en un host remoto.
rai.skumar