Schreiben Sie ein Shell-Skript für ssh auf einen Remote-Computer und führen Sie Befehle aus


97

Ich habe zwei Fragen:

  1. Es gibt mehrere Remote-Linux-Computer, und ich muss ein Shell-Skript schreiben, das auf jedem Computer denselben Befehlssatz ausführt. (Einschließlich einiger Sudo-Operationen). Wie kann dies mithilfe von Shell-Skripten erreicht werden?
  2. Wie geht man vor, wenn man zur Remote-Computer-Authentifizierung auffordert?

Die Remote-Computer sind VMs, die während des Laufs erstellt wurden, und ich habe nur ihre IPs. Daher kann ich keine Skriptdatei im Voraus auf diesen Computern ablegen und sie von meinem Computer aus ausführen.


Ich denke an die Bereitstellung eines agentenähnlichen Programms auf Remote-Linux-Computern, die die Verbindung zum Server über eine Network-Socket- (oder SSL-) Verbindung / durch regelmäßige Abfrage zum Server aufrechterhalten.
Raptor

Ich muss eine Reihe von Befehlen nur einmal ausführen, daher ist es nicht erforderlich, die Verbindung aufrechtzuerhalten
Balanivash

"keine Skripte" bedeutet "überhaupt keine Dateien", nehme ich an? Wie gehen Sie mit der Authentifizierung um? Sie können die Überprüfung des Host-Fingerabdrucks deaktivieren (siehe meine Antwort), erhalten jedoch weiterhin eine interaktive Kennwortabfrage, wenn Sie keinen öffentlichen / privaten Schlüssel eingerichtet haben.
Andreas Fester

1
Andreas: ja überhaupt keine Dateien. Die passwd-Eingabeaufforderung kann expectwie folgt behandelt werden: " erwarten" ? assword: "
Balanivash

Antworten:


141

Es gibt mehrere Remote-Linux-Computer, und ich muss ein Shell-Skript schreiben, das auf jedem Computer denselben Befehlssatz ausführt. (Einschließlich einiger Sudo-Operationen). Wie kann dies mithilfe von Shell-Skripten erreicht werden?

Sie können dies mit ssh tun, zum Beispiel:

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

Wie geht man vor, wenn man zur Remote-Computer-Authentifizierung auffordert?

Sie können die StrictHostKeyChecking=noOption zu ssh hinzufügen :

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

Dadurch wird die Hostschlüsselprüfung deaktiviert und der Hostschlüssel automatisch zur Liste der bekannten Hosts hinzugefügt. Wenn Sie nicht möchten, dass der Host zur bekannten Hosts-Datei hinzugefügt wird, fügen Sie die Option hinzu -o UserKnownHostsFile=/dev/null.

Beachten Sie, dass dadurch bestimmte Sicherheitsüberprüfungen deaktiviert werden , z. B. der Schutz vor Man-in-the-Middle-Angriffen. Es sollte daher nicht in einer sicherheitsrelevanten Umgebung angewendet werden.


Was ist die Skriptsprache? Sie können natürlich auch sshvon jedem Shell-Skript aus anrufen
Andreas Fester

Was ist, wenn Sie auch STRG + C ausführen und ssh auf mehreren Servern fortsetzen möchten? In einigen Servern wird beispielsweise nach einem Kennwort gefragt, in anderen nach einem Nein, sodass das Skript dort hängen bleibt. Gibt es eine Möglichkeit, etwas Ähnliches wie -o zu tun, um eine STRG-Taste c oder eine STRG-Taste d auszuführen?
Chanafot

5

Es gibt verschiedene Möglichkeiten, damit umzugehen.

Am liebsten installiere ich http://pamsshagentauth.sourceforge.net/ auf den Remote-Systemen und auch Ihren eigenen öffentlichen Schlüssel. (Finden Sie heraus, wie Sie diese auf der VM installieren können. Irgendwie haben Sie ein ganzes Unix-System installiert. Was sind noch ein paar Dateien?)

Wenn Ihr SSH-Agent weitergeleitet wird, können Sie sich jetzt ohne Kennwort bei jedem System anmelden.

Und noch besser, dieses Pam-Modul authentifiziert sich für Sudo mit Ihrem SSH-Schlüsselpaar, sodass Sie bei Bedarf mit Root-Rechten (oder den Rechten anderer Benutzer) ausgeführt werden können.

Sie müssen sich keine Gedanken über die Interaktion mit dem Hostschlüssel machen. Wenn es sich bei der Eingabe nicht um ein Terminal handelt, schränkt ssh lediglich Ihre Fähigkeit ein, Agenten weiterzuleiten und sich mit Kennwörtern zu authentifizieren.

Sie sollten sich auch Pakete wie Capistrano ansehen . Schauen Sie sich auf jeden Fall auf dieser Seite um. Es enthält eine Einführung in Remote-Scripting.

Einzelne Skriptzeilen könnten ungefähr so ​​aussehen:

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

4

Installieren Sie sshpass mit, apt-get install sshpassbearbeiten Sie das Skript und ordnen Sie die IP-Adressen , Benutzernamen und das Kennwort Ihres Linux-Computers in der entsprechenden Reihenfolge. Führen Sie danach das Skript aus. Das ist es ! Dieses Skript installiert VLC auf allen Systemen.

#!/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

Verwenden Sie $ SSHPASS, um das Kennwort zu exportieren, damit es nicht im Skript angezeigt wird. Ref: tecmint.com/...
Hexy

2

Wenn Sie Perl-Code schreiben können, sollten Sie Net :: OpenSSH :: Parallel verwenden .

Sie können die Aktionen, die auf jedem Host ausgeführt werden müssen, deklarativ beschreiben, und das Modul kümmert sich um alle beängstigenden Details. Das Ausführen von Befehlen sudowird ebenfalls unterstützt.


2

Diese Arbeit für mich.

Syntax: ssh -i pemfile.pem Benutzername @ IP-Adresse 'Befehl_1; Befehl 2; Befehl 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'

1

Für diese Art von Aufgaben verwende ich wiederholt Ansible , mit dem kohärente Bash-Skripte in mehreren Containets oder VMs dupliziert werden können. Ansible (genauer gesagt Red Hat ) hat jetzt ein zusätzliches Webinterface AWX, das die Open-Source-Edition ihres kommerziellen Tower ist.

Ansible: https://www.ansible.com/
AWX: https://github.com/ansible/awx
Ansible Tower: kommerzielles Produkt, Sie werden wahrscheinlich zuerst den kostenlosen Open-Source-AWX erkunden, anstatt den 15-tägigen Free-Trail des Turms


1

Es gibt mehrere Möglichkeiten, die Befehle oder das Skript auf mehreren Remote-Linux-Computern auszuführen. Ein einfacher und einfacher Weg ist über pssh (paralleles SSH-Programm).

Pssh : ist ein Programm zum parallelen Ausführen von SSH auf einer Reihe von Hosts. Es bietet Funktionen wie das Senden von Eingaben an alle Prozesse, das Übergeben eines Kennworts an ssh, das Speichern der Ausgabe in Dateien und das Zeitlimit.

Beispiel & Verwendung:

Stellen Sie eine Verbindung zu Host1 und Host2 her und drucken Sie "Hallo, Welt" von jedem:

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

Führen Sie Befehle über ein Skript auf mehreren Servern aus:

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

Verwenden und Ausführen eines Befehls ohne Überprüfen oder Speichern von Hostschlüsseln:

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

Wenn die Datei hosts.txt eine große Anzahl von Einträgen enthält, z. B. 100, kann die Parallelitätsoption auch auf 100 gesetzt werden, um sicherzustellen, dass die Befehle gleichzeitig ausgeführt werden:

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

Optionen :
-I: Eingabe lesen und an jeden SSH-Prozess senden.
-P: Weist pssh an, die Ausgabe beim Eintreffen anzuzeigen.
-h: Liest die Datei des Hosts.
-H: [user @] host [: port] für Single-Host.
-i: Standardausgabe und Standardfehler anzeigen, wenn jeder Host abgeschlossen ist
-x Argumente : Übergibt zusätzliche SSH-Befehlszeilenargumente
-o Option: Kann verwendet werden, um Optionen in dem in der Konfigurationsdatei verwendeten Format anzugeben. (/ etc / ssh / ssh_config ) (~ / .ssh / config)
-p Parallelität: Verwenden Sie die angegebene Anzahl als maximale Anzahl gleichzeitiger Verbindungen.
-q Leiser Modus: Bewirkt, dass die meisten Warn- und Diagnosemeldungen unterdrückt werden.
-t: Zeitüberschreitung bei Verbindungen nach der angegebenen Anzahl von Sekunden. 0 bedeutet, dass pssh keine Zeitüberschreitung für Verbindungen verursacht

Wie geht man vor, wenn man zur Remote-Computer-Authentifizierung auffordert?

Deaktivieren Sie StrictHostKeyChecking, um die RSA-Authentifizierungsaufforderung zu verarbeiten.
-o StrictHostKeyChecking = no

Quelle : man pssh


0

Das hat bei mir funktioniert. Ich habe eine Funktion gemacht. Fügen Sie dies in Ihr Shell-Skript ein:

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

sshcmd USER HOST COMMAND

Wenn Sie mehrere Computer haben, auf denen Sie denselben Befehl ausführen möchten, wiederholen Sie diese Zeile mit einem Semikolon. Wenn Sie beispielsweise zwei Maschinen haben, würden Sie dies tun:

sshcmd USER HOST COMMAND ; sshcmd USER HOST COMMAND

Ersetzen Sie USER durch den Benutzer des Computers. Ersetzen Sie HOST durch den Namen des Computers. Ersetzen Sie COMMAND durch den Befehl, den Sie auf dem Computer ausführen möchten.

Hoffe das hilft!


-1

Sie können diesem Ansatz folgen:

  • Stellen Sie mit Expect Script eine Verbindung zum Remote-Computer her . Wenn Ihr Computer dies nicht unterstützt, können Sie dasselbe herunterladen. Das Schreiben von Expect-Skripten ist sehr einfach (Google, um Hilfe zu erhalten)
  • Fügen Sie alle Aktionen, die auf dem Remote-Server ausgeführt werden müssen, in ein Shell-Skript ein.
  • Rufen Sie das Remote-Shell-Skript vom Expect-Skript auf, sobald die Anmeldung erfolgreich war.

Wie ich in der Frage erwähnt habe, werden die Remote-Maschinen während des Laufs erstellt und ich kann vorher kein Skript auf der Maschine haben.
Balanivash

In diesem Fall setzen Sie alle Aktionen in das Expect-Skript. Das Expect-Skript kann auch Befehle auf dem Remote-Host ausführen.
rai.skumar
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.