Wie kann ich meinen SSH-Pub-Schlüssel an eine Liste von Servern weitergeben, ohne mein Kennwort immer wieder eingeben zu müssen?

26

Ich habe kürzlich den Benutzernamen / das Kennwort für eine Liste von Servern erhalten und möchte meinen öffentlichen SSH-Schlüssel an diese Server weitergeben, damit ich mich leichter anmelden kann.

Damit es klar ist:

  • Auf den Remoteservern ist kein öffentlicher Schlüssel vorhanden, mit dem ich dies automatisieren kann
  • Dies ist das erste Mal, dass ich mich bei diesen Servern anmelde, und ich möchte nicht ständig meine Anmeldeinformationen eingeben müssen, um darauf zuzugreifen
  • Ich möchte mein Passwort auch nicht immer wieder ssh-copy-idin einer for-Schleife eingeben .
slm
quelle
1
Es ist der gleiche Benutzername und das gleiche Passwort für alle Server?
Roaima
@roaima - yup! Dieses Detail hat mich ebenfalls überrascht, aber so ist dieses spezielle Rechenzentrums-Setup und so machen sie es.
slm
@ ott-- - überprüfe die Frage noch einmal. Ich sage ausdrücklich, dass ich keine for-Schleife durchführen möchte, und pumpe ssh-copy-idmein Passwort immer wieder durch.
slm
Siehe auch Skript zur Automatisierung von scp im Netzwerk
Gilles 'SO - hör auf, böse zu sein'
2
Dies ist ein perfekter Anwendungsfall für das Konfigurationsmanagement. Schau dir Marionette, Koch, Ansible oder Salz an.
Spuder

Antworten:

31

Anstatt Ihr Kennwort mehrmals einzugeben, können Sie mit psshund dessen -ASchalter einmal danach fragen und das Kennwort dann an alle Server in einer Liste weiterleiten.

ANMERKUNG: Bei dieser Methode können Sie diese jedoch nicht verwenden. Daher müssen Sie ssh-copy-idIhre eigene Methode zum Anhängen Ihrer SSH-Pub-Schlüsseldatei an die Datei Ihres Remote-Kontos rollen ~/.ssh/authorized_keys.

Beispiel

Hier ist ein Beispiel, das die Arbeit erledigt:

$ cat ~/.ssh/my_id_rsa.pub                    \
    | pssh -h ips.txt -l remoteuser -A -I -i  \
    '                                         \
      umask 077;                              \
      mkdir -p ~/.ssh;                        \
      afile=~/.ssh/authorized_keys;           \
      cat - >> $afile;                        \
      sort -u $afile -o $afile                \
    '
Warning: do not enter your password if anyone else has superuser
privileges or access to your account.
Password:
[1] 23:03:58 [SUCCESS] 10.252.1.1
[2] 23:03:58 [SUCCESS] 10.252.1.2
[3] 23:03:58 [SUCCESS] 10.252.1.3
[4] 23:03:58 [SUCCESS] 10.252.1.10
[5] 23:03:58 [SUCCESS] 10.252.1.5
[6] 23:03:58 [SUCCESS] 10.252.1.6
[7] 23:03:58 [SUCCESS] 10.252.1.9
[8] 23:03:59 [SUCCESS] 10.252.1.8
[9] 23:03:59 [SUCCESS] 10.252.1.7

Das obige Skript ist im Allgemeinen so aufgebaut:

$ cat <pubkey> | pssh -h <ip file> -l <remote user> -A -I -i '...cmds to add pubkey...'

psshDetails auf hohem Niveau

  • cat <pubkey> gibt die öffentliche Schlüsseldatei an aus pssh
  • psshverwendet den -ISchalter, um Daten über STDIN aufzunehmen
  • -l <remote user> ist das Konto des Remote-Servers (wir gehen davon aus, dass Sie auf allen Servern in der IP-Datei denselben Benutzernamen haben)
  • -Afordert Sie psshauf, nach Ihrem Kennwort zu fragen und es dann für alle Server zu verwenden, mit denen eine Verbindung hergestellt wird
  • -ierzählt pssheher eine Ausgabe an STDOUT zu senden als Speicher in Dateien (dessen Standardverhalten)
  • '...cmds to add pubkey...'- Das ist der schwierigste Teil des Geschehens, also werde ich das von selbst aufschlüsseln (siehe unten).

Befehle, die auf Remote-Servern ausgeführt werden

Dies sind die Befehle, psshdie auf jedem Server ausgeführt werden:

'                                         \
  umask 077;                              \
  mkdir -p ~/.ssh;                        \
  afile=~/.ssh/authorized_keys;           \
  cat - >> $afile;                        \
  sort -u $afile -o $afile                \
'
In Ordnung:
  • Setzen Sie die umask des Remote-Benutzers auf 077, damit alle Verzeichnisse oder Dateien, die wir erstellen, die entsprechenden Berechtigungen haben, und zwar wie folgt:

    $ ls -ld ~/.ssh ~/.ssh/authorized_keys
    drwx------ 2 remoteuser remoteuser 4096 May 21 22:58 /home/remoteuser/.ssh
    -rw------- 1 remoteuser remoteuser  771 May 21 23:03 /home/remoteuser/.ssh/authorized_keys
  • Erstellen Sie das Verzeichnis ~/.sshund ignorieren Sie die Warnung, wenn es bereits vorhanden ist

  • Setzen Sie eine Variable $afilemit dem Pfad zur Datei authorized_keys
  • cat - >> $afile - Eingaben von STDIN nehmen und an authorized_keys-Datei anhängen
  • sort -u $afile -o $afile - Sortiert die authorized_keys-Datei eindeutig und speichert sie

ANMERKUNG: Das letzte Bit behandelt den Fall, in dem Sie die obigen Schritte mehrmals auf denselben Servern ausführen. Dadurch wird verhindert, dass Ihr Pubkey mehrmals angehängt wird.

Beachten Sie die einzelnen Ticks!

Achten Sie auch besonders darauf, dass alle diese Befehle in einfachen Anführungszeichen stehen. Das ist wichtig, da wir erst $afileausgewertet werden möchten , nachdem es auf dem Remote-Server ausgeführt wurde.

'               \
   ..cmds...    \
'

Ich habe das Obige erweitert, damit es hier leichter zu lesen ist, aber ich führe es im Allgemeinen in einer einzigen Zeile aus:

$ cat ~/.ssh/my_id_rsa.pub | pssh -h ips.txt -l remoteuser -A -I -i 'umask 077; mkdir -p ~/.ssh; afile=~/.ssh/authorized_keys; cat - >> $afile; sort -u $afile -o $afile'

Bonusmaterial

Durch die Verwendung von können psshSie darauf verzichten, Dateien erstellen zu müssen und entweder dynamischen Inhalt mithilfe von bereitzustellen, -h <(...some command...)oder Sie können eine Liste von IPs mithilfe eines anderen psshSwitches von erstellen -H "ip1 ip2 ip3".

Beispielsweise:

$ cat .... | pssh -h <(grep -A1 dp15 ~/.ssh/config | grep -vE -- '#|--') ...

Das oben Genannte könnte verwendet werden, um eine Liste von IPs aus meiner ~/.ssh/configDatei zu extrahieren . Sie können natürlich auch verwenden printf, um dynamische Inhalte zu generieren:

$ cat .... | pssh -h <(printf "%s\n" srv0{0..9}) ....

Beispielsweise:

$ printf "%s\n" srv0{0..9}
srv00
srv01
srv02
srv03
srv04
srv05
srv06
srv07
srv08
srv09

Sie können auch verwenden seq, um formatierte Zahlenfolgen zu generieren!

Referenzen & ähnliche Tools zu pssh

Wenn Sie nicht wie oben beschrieben verwenden möchten, stehen Ihnen pssheinige andere Optionen zur Verfügung.

slm
quelle
2
Drei kleinere Ergänzungen: (1) psshist ein Python-Skript und kann mit installiert werden pip install pssh. (2) Sie können auch sshSchlüssel auf allen Servern gleichzeitig ssh-keygendurchlaufen pssh. (3) Nach dem Generieren der Schlüssel können Sie die Schlüssel "all-to-all" verteilen, indem Sie alle öffentlichen Schlüssel in einer Schleife auf den lokalen Computer authorized_keyskopieren, sie zu einem gemeinsamen zusammenfügen und auf jeden Computer kopieren. ssh_agentIch ssh_addkann mit den Passwörtern helfen.
lcd047
@ lcd047 - danke, ich werde diese später heute in das A aufnehmen!
slm
1
Ich denke, dieses Skript eignet sich für die unbrauchbare Verwendung von cataward (of old): Um eine Pipeline mit dem Inhalt einer Datei zu starten, können Sie einfach die Eingabe von dieser Datei umleiten.
Marc van Leeuwen
1
@MarcvanLeeuwen - Ich würde eher zustimmen, aber ich wollte, dass jeder, der über zukünftige Suchanfragen darauf stößt, besser versteht, wie der Pubkey weitergereicht wird pssh.
slm
1
@MarcvanLeeuwen: Es ist nicht mehr nutzlos , wenn Sie es tun , wie folgt: cat ~/.ssh/*.pub | .... Es kann sein oder auch nicht, was Sie in dieser Situation wollen.
lcd047
7

Alternative verwendet xargs, sshpassund ssh-copy-id:

Angenommen, Ihre Anmeldeinformationen befinden sich in credentials.txt im Format user:password@server:

$ cat credentials.txt
root:insecure@192.168.0.1
foo:insecure@192.168.0.2
bar:realsecure@192.168.0.3

Du könntest es tun:

tr ':@' '\n' < credentials.txt \
| xargs -L3 sh -c 'sshpass -p $1 ssh-copy-id $0@$2'

Hinweis: Denken Sie daran, credentials.txt nach der Verwendung zu entfernen !

FloHimself
quelle
2
Und wenn es für alle Server derselbe Benutzername und dasselbe Passwort ist, können Sie ihn einfach direkt hartcodieren und nur eine Liste von IP-Adressen lesen :-)
Falco
6

ClusterSSH bietet auf jedem Computer ein Fenster und ein gemeinsames Fenster zur Steuerung aller Fenster.

Wenn wir über 10 Maschinen sprechen, wird dies funktionieren. Wenn wir über 100 Maschinen sprechen, wird es zu viele Fenster geben.

Das Schöne an ClusterSSH ist, dass Sie, wenn ein Computer nicht zu 100% mit dem Rest identisch ist, einfach auf das Fenster klicken und nur Tastatureingaben an diesen Computer senden können, bevor Sie wieder Tastatureingaben an alle Computer senden.

Ole Tange
quelle
6

Die Verwendung von Ansible ist recht einfach. Ersetzen Sie einfach <USER>mit dem echten Anmeldenamen

$ cd /path/to/public/key

$ cat<<END > hosts
  host1.example.com
  10.10.10.10
  END

$ ansible -i hosts all --ask-pass -u <USER> -m authorized_key \
      -a "user=<USER> key='$(cat id_rsa.pub)'"        
Daniel Wakefield
quelle
0

Einige Dinge, die möglicherweise die Rechnung passen könnten:

Wie in anderen Antworten erwähnt, sshpassist wahrscheinlich die einfachste Lösung.

Richlv
quelle
-1

Hier haben Sie zwei Möglichkeiten:

  • Sie können eine Datei mit allen IP-Adressen der Server erstellen und dann die folgenden Schritte ausführen

    while read -r ip;do
      ssh-copy-id -i .ssh/id_rsa.pub $ip
    done < servers.txt

Angenommen servers.txtist die Datei mit IPs / Hostnamen.

  • Sie können alle Ihre IPs / Hostnamen in eine Schleife einfügen und ssh-copy-idwie folgt ausführen :

    for i in hostname1 hostname2
      do ssh-copy-id -i .ssh/id_rsa.pub $i
    done
Tolga Ozses
quelle
Das widerspricht völlig den Anforderungen des OPs: "Ich möchte mein Passwort auch nicht immer wieder ssh-copy-idin einer for-Schleife eingeben ."
OldTimer
Ich glaube nicht, dass es einen anderen Weg gibt, es sei denn, OP ist bereit, physisch auf alle Server zu kopieren.
Tolga Ozses