Come posso propagare la mia chiave pub SSH in un elenco di server senza dover inserire ripetutamente la mia password?


26

Di recente mi è stato concesso l'accesso a nome utente / password a un elenco di server e desidero propagare la mia chiave pubblica SSH su questi server, in modo da poter accedere più facilmente.

In modo che sia chiaro:

  • Non esiste alcuna chiave pubblica preesistente sui server remoti che posso utilizzare per automatizzare questo
  • Ciò costituisce la prima volta che accedo a questi server e mi piacerebbe non dover digitare costantemente le mie credenziali per accedervi
  • Né voglio digitare più volte la mia password usando ssh-copy-idin un ciclo for.

1
È lo stesso nome utente e password per tutti i server?
roaima,

@roaima - yup! Anche quel dettaglio mi ha sorpreso, ma è così che è questa particolare configurazione del data center ed è così che lo fanno.
slm

@ ott-- - ricontrolla il Q. Dichiaro esplicitamente che non voglio fare un ciclo for ssh-copy-id, pompando la mia password più e più volte.
slm


2
Questo è un caso d'uso perfetto per la gestione della configurazione. Guarda burattino, chef, ansible o sale.
spuder,

Risposte:


31

Anziché digitare la password più volte è possibile utilizzare psshe il relativo -Ainterruttore per richiederla una volta, quindi inviare la password a tutti i server in un elenco.

NOTA: l' utilizzo di questo metodo non ti consente di utilizzarlo ssh-copy-id, tuttavia, dovrai eseguire il rollup del tuo metodo per aggiungere il file della chiave pub SSH al file del tuo account remoto ~/.ssh/authorized_keys.

Esempio

Ecco un esempio che fa il lavoro:

$ 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

Lo script sopra è generalmente strutturato in questo modo:

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

psshDettagli di alto livello

  • cat <pubkey> genera il file della chiave pubblica su pssh
  • psshutilizza l' -Iinterruttore per inserire i dati tramite STDIN
  • -l <remote user> è l'account del server remoto (supponiamo che tu abbia lo stesso nome utente tra i server nel file IP)
  • -Adice psshdi chiedere la password e di riutilizzarla per tutti i server a cui si connette
  • -iindica psshdi inviare qualsiasi output a STDOUT anziché memorizzarlo in file (comportamento predefinito)
  • '...cmds to add pubkey...'- questa è la parte più delicata di ciò che sta succedendo, quindi la analizzerò da sola (vedi sotto)

Comandi in esecuzione su server remoti

Questi sono i comandi che psshverranno eseguiti su ciascun server:

'                                         \
  umask 077;                              \
  mkdir -p ~/.ssh;                        \
  afile=~/.ssh/authorized_keys;           \
  cat - >> $afile;                        \
  sort -u $afile -o $afile                \
'
In ordine:
  • imposta umask dell'utente remoto su 077, in modo che tutte le directory o i file che creeremo, abbiano le autorizzazioni impostate di conseguenza in questo modo:

    $ 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
    
  • crea la directory ~/.sshe ignora avvisandoci se è già lì

  • imposta una variabile, $afilecon il percorso del file authorized_keys
  • cat - >> $afile - accetta input da STDIN e accoda al file authorized_keys
  • sort -u $afile -o $afile - ordina in modo univoco il file authorized_keys e lo salva

NOTA: l' ultimo bit è quello di gestire il caso in cui si esegue più volte sopra con gli stessi server. Questo eliminerà il tuo pubkey dall'essere aggiunto più volte.

Nota le singole zecche!

Prestare particolare attenzione al fatto che tutti questi comandi sono nidificati all'interno di virgolette singole. Questo è importante, dal momento che non vogliamo $afileessere valutati fino a quando non viene eseguito sul server remoto.

'               \
   ..cmds...    \
'

Ho ampliato quanto sopra, quindi è più facile da leggere qui, ma in genere eseguo tutto su una sola riga in questo modo:

$ 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'

Materiale bonus

Utilizzando psshsi può rinunciare dover costruire i file e sia di fornire contenuti dinamici utilizzando -h <(...some command...)oppure è possibile creare un elenco di IP utilizzando un altro di pssh's interruttori, -H "ip1 ip2 ip3".

Per esempio:

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

Quanto sopra potrebbe essere utilizzato per estrarre un elenco di IP dal mio ~/.ssh/configfile. Ovviamente puoi anche usare printfper generare contenuti dinamici:

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

Per esempio:

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

Puoi anche usare seqper generare sequenze di numeri formattati!

Riferimenti e strumenti simili a pssh

Se non vuoi usare psshcome ho già fatto sopra, ci sono alcune altre opzioni disponibili.


2
Tre aggiunte minori: (1) psshè uno script Python e può essere installato con pip install pssh. (2) Si può anche generare sshle chiavi di tutti i server contemporaneamente eseguendo ssh-keygenattraverso pssh. (3) Dopo aver generato le chiavi è possibile distribuire le chiavi "tutto-in-tutto" copiando tutte le chiavi pubbliche in un ciclo sul computer locale, assemblandole in un comune authorized_keyse copiandole su ciascun computer. ssh_agent/ ssh_addpuò aiutarti con le password.
lcd047,

@ lcd047 - grazie, inserirò quelli nella A più tardi oggi!
slm

1
Penso che questo script sia idoneo all'uso inutile di cataward (di una volta): per avviare una pipeline con il contenuto di un file, puoi semplicemente reindirizzare l'input da quel file.
Marc van Leeuwen,

1
@MarcvanLeeuwen - Tenderei ad essere d'accordo, ma volevo che fosse più facile per chiunque possa imbattersi in questo attraverso ricerche future per capire chiaramente come viene passato il pubkey pssh.
slm

1
@MarcvanLeeuwen: Non è più inutile se lo si fa in questo modo: cat ~/.ssh/*.pub | .... Tuttavia, potrebbe essere o meno ciò che si desidera in questa situazione.
lcd047,

7

Utilizzando Alternativa xargs, sshpasse ssh-copy-id:

Supponendo che le tue credenziali vivano in credentials.txt in formato user:password@server:

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

Potresti fare:

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

Nota: ricordati di rimuovere credentials.txt dopo l'uso!


2
E se è lo stesso nome utente e password per tutti i server, puoi semplicemente codificarlo direttamente e leggere solo un elenco di indirizzi IP :-)
Falco,

6

ClusterSSH ti dà una finestra su ogni macchina e con una finestra comune per controllare tutte le finestre.

Se stiamo parlando di 10 macchine funzionerà. Se stiamo parlando di 100 macchine, ci saranno molte finestre.

La bellezza di ClusterSSH è che se una macchina non è al 100% simile alle altre, puoi semplicemente fare clic sulla finestra e inviare i tasti solo a quella macchina prima di tornare a inviare tasti a tutti i computer.


6

L'uso di Ansible è abbastanza semplice. Sostituisci semplicemente <USER>con il nome di accesso reale

$ 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)'"        


-1

Hai due opzioni qui:

  • È possibile creare un file con tutti gli indirizzi IP dei server, quindi procedere come segue

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

Supponendo che servers.txtsia il file con IP / nomi host.

  • Puoi mettere tutti i tuoi IP / nomi host in un ciclo ed eseguire ssh-copy-idcome di seguito:

    for i in hostname1 hostname2
      do ssh-copy-id -i .ssh/id_rsa.pub $i
    done
    

Il che va completamente contro i requisiti dei PO: "Né voglio digitare più volte la mia password usando ssh-copy-idin un ciclo for".
OldTimer

Non penso che ci sia un altro modo, a meno che OP non sia disposto a copiare fisicamente su tutti i server.
Tolga Ozses,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.