Bagaimana saya bisa menyebarkan kunci pub SSH saya ke daftar server tanpa harus mengetik kata sandi saya berulang kali?

26

Saya baru-baru ini diberikan akses nama pengguna / kata sandi ke daftar server dan ingin menyebarkan kunci publik SSH saya ke server ini, sehingga saya dapat masuk dengan lebih mudah.

Sehingga jelas:

  • Tidak ada kunci publik yang sudah ada di server jauh yang dapat saya manfaatkan untuk mengotomatiskan ini
  • Ini merupakan pertama kalinya saya masuk ke server ini, dan saya ingin tidak harus terus-menerus mengetikkan kredensial saya untuk mengaksesnya
  • Saya juga tidak ingin mengetik kata sandi saya berulang kali menggunakan ssh-copy-iddalam for for loop.
slm
sumber
1
Itu nama pengguna dan kata sandi yang sama untuk semua server?
roaima
@roaima - yup! Detail itu mengejutkan saya juga, tapi begitulah pengaturan pusat data ini dan itulah yang mereka lakukan.
slm
@ ott-- - periksa Q. Saya secara eksplisit menyatakan bahwa saya tidak ingin melakukan perulangan ssh-copy-id, memompa kata sandi saya berulang kali.
slm
Lihat juga skrip untuk mengotomatisasi scp dalam jaringan
Gilles 'SO-stop being evil'
2
Ini adalah kasus penggunaan yang sempurna untuk manajemen konfigurasi. Lihatlah boneka, koki, atau garam.
Pengamen

Jawaban:

31

Daripada mengetikkan kata sandi Anda beberapa kali, Anda dapat menggunakan psshdan -Aberalih untuk meminta kata sandi sekali, dan kemudian memasukkan kata sandi ke semua server dalam daftar.

CATATAN: Menggunakan metode ini tidak memungkinkan Anda untuk menggunakan ssh-copy-id, jadi Anda harus menggulung metode Anda sendiri untuk menambahkan file kunci pub SSH Anda ke file akun jarak jauh Anda ~/.ssh/authorized_keys.

Contoh

Berikut ini contoh yang berfungsi:

$ 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

Skrip di atas umumnya terstruktur seperti:

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

psshDetail tingkat tinggi

  • cat <pubkey> menghasilkan file kunci publik pssh
  • psshmenggunakan -Iperalihan untuk menelan data melalui STDIN
  • -l <remote user> adalah akun server jarak jauh (kami mengasumsikan Anda memiliki nama pengguna yang sama di seluruh server dalam file IP)
  • -Amemberitahu psshuntuk meminta kata sandi Anda dan kemudian menggunakannya kembali untuk semua server yang terhubung
  • -imemberitahu psshuntuk mengirim output ke STDOUT daripada menyimpannya dalam file (perilaku default-nya)
  • '...cmds to add pubkey...'- ini adalah bagian tersulit dari apa yang terjadi, jadi saya akan memecah ini dengan sendirinya (lihat di bawah)

Perintah dijalankan di server jarak jauh

Ini adalah perintah yang psshakan dijalankan di setiap server:

'                                         \
  umask 077;                              \
  mkdir -p ~/.ssh;                        \
  afile=~/.ssh/authorized_keys;           \
  cat - >> $afile;                        \
  sort -u $afile -o $afile                \
'
Dalam urutan:
  • atur umask pengguna jarak jauh ke 077, ini agar direktori atau file apa pun yang akan kita buat, akan memiliki izinnya diatur seperti:

    $ 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
    
  • buat direktori ~/.sshdan abaikan peringatan kami jika sudah ada di sana

  • setel variabel $afile,, dengan path ke file Authorized_keys
  • cat - >> $afile - ambil input dari STDIN dan tambahkan ke file otor_keys
  • sort -u $afile -o $afile - secara unik mengurutkan file otor_keys dan menyimpannya

CATATAN: Bit terakhir itu adalah untuk menangani case di mana Anda menjalankan beberapa kali di atas terhadap server yang sama. Ini akan menghilangkan pubkey Anda dari ditambahkan beberapa kali.

Perhatikan kutu tunggal!

Juga berikan perhatian khusus pada fakta bahwa semua perintah ini bersarang di dalam tanda kutip tunggal. Itu penting, karena kami tidak ingin $afiledievaluasi sampai setelah dijalankan di server jauh.

'               \
   ..cmds...    \
'

Saya telah memperluas di atas sehingga lebih mudah untuk membaca di sini, tetapi saya biasanya menjalankan semuanya pada satu baris seperti ini:

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

Materi bonus

Dengan menggunakan psshAnda dapat melupakan harus membuat file dan menyediakan konten dinamis menggunakan -h <(...some command...)atau Anda dapat membuat daftar IP menggunakan psshswitch lain -H "ip1 ip2 ip3",.

Sebagai contoh:

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

Di atas dapat digunakan untuk mengekstrak daftar IP dari ~/.ssh/configfile saya . Tentu saja Anda juga dapat menggunakan printfuntuk menghasilkan konten dinamis:

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

Sebagai contoh:

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

Anda juga dapat menggunakan sequntuk menghasilkan urutan angka yang diformat juga!

Referensi & alat serupa untuk pssh

Jika Anda tidak ingin menggunakan psshseperti yang saya lakukan di atas, ada beberapa opsi lain yang tersedia.

slm
sumber
2
Tiga tambahan kecil: (1) psshadalah skrip Python, dan dapat diinstal dengan pip install pssh. (2) Anda juga dapat menghasilkan sshkunci pada semua server secara bersamaan dengan menjalankan ssh-keygenmelalui pssh. (3) Setelah membuat kunci, Anda dapat mendistribusikan kunci "all-to-all" dengan menyalin semua kunci publik dalam satu loop ke mesin lokal, merakitnya secara bersama authorized_keys, dan menyalinnya ke setiap mesin. ssh_agentSaya ssh_adddapat membantu dengan kata sandi.
lcd047
@ lcd047 - terima kasih, saya akan memasukkan mereka ke dalam A hari ini nanti!
slm
1
Saya pikir skrip ini memenuhi syarat untuk penggunaan tak berguna catpenghargaan (lama): untuk memulai saluran pipa dengan isi file, Anda bisa mengarahkan ulang input dari file itu.
Marc van Leeuwen
1
@MarcvanLeeuwen - Saya akan cenderung setuju, tapi saya ingin lebih mudah bagi siapa saja yang menemukan ini melalui pencarian di masa depan untuk memahami dengan jelas bagaimana pubkey tersebut diteruskan pssh.
slm
1
@MarcvanLeeuwen: Ini tidak lagi berguna jika Anda melakukannya seperti ini: cat ~/.ssh/*.pub | .... Mungkin atau tidak mungkin apa yang Anda inginkan dalam situasi ini.
lcd047
7

Alternatif menggunakan xargs, sshpassdan ssh-copy-id:

Dengan asumsi kredensial Anda tinggal di credentials.txt dalam 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

Anda bisa melakukannya:

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

Catatan: Ingatlah untuk menghapus credentials.txt setelah penggunaan!

FloHimself
sumber
2
Dan jika itu nama pengguna dan kata sandi yang sama untuk semua server, Anda bisa langsung membuat hardcode secara langsung dan hanya membaca daftar IP-Adresses :-)
Falco
6

ClusterSSH memberi Anda jendela di setiap mesin dan dengan jendela umum untuk mengontrol semua jendela.

Jika kita berbicara 10 mesin, ini akan berhasil. Jika kita berbicara 100 mesin, akan ada banyak jendela.

Keindahan ClusterSSH adalah bahwa jika satu mesin tidak 100% seperti yang lain, Anda cukup mengklik jendela, dan mengirim penekanan tombol hanya ke mesin itu sebelum Anda kembali mengirim penekanan tombol ke semua mesin.

Ole Tange
sumber
6

Menggunakan Ansible cukup sederhana. Cukup ganti <USER>dengan nama login asli

$ 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
sumber
-1

Anda memiliki dua opsi di sini:

  • Anda dapat membuat file dengan semua alamat IP server, lalu lakukan hal berikut

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

Dengan asumsi servers.txtadalah file dengan IP / nama host.

  • Anda dapat meletakkan semua IP / nama host dalam satu lingkaran, dan jalankan ssh-copy-idseperti di bawah ini:

    for i in hostname1 hostname2
      do ssh-copy-id -i .ssh/id_rsa.pub $i
    done
    
Tolga Ozses
sumber
Yang sepenuhnya bertentangan dengan persyaratan OP: "Saya juga tidak ingin mengetikkan kata sandi saya berulang-ulang ssh-copy-iddalam for for."
OldTimer
Saya tidak berpikir ada cara lain, kecuali OP mau secara fisik menyalin ke semua server.
Tolga Ozses