Bagaimana membuat ssh-agent secara otomatis menambahkan kunci sesuai permintaan?

51

Saya ingin menjalankan ssh-agent (dengan opsi seumur hidup maksimum), tetapi tidak menambahkan kunci apa pun saat startup, tetapi menambahkannya sesuai permintaan.

Seperti pertama kali saya masuk ke beberapa server, ia harus meminta frasa sandi, lain kali (kecuali jika saya menunggu lebih dari satu jam) itu harus terhubung dengan bersih:

ssh server1
Enter passphrase for key '/home/vi/.ssh/id_dsa':
server1> ...

ssh server2
server2> # no passphrase this time

# wait for lifetime

ssh server2
Enter passphrase for key '/home/vi/.ssh/id_dsa':

Saya tidak ingin mengingat secara manual tentang menjalankan 'ssh-add' setiap kali. (misalnya memasukkan frasa sandi hanya untuk ssh dan "Oh, tidak ingat, perlu mengetik ulang").

Bagaimana mengkonfigurasi ssh untuk secara otomatis menambahkan kunci ke ssh-agent jika pengguna memberikan frasa sandi?

Vi.
sumber

Jawaban:

58

ssh mendukung menambahkan kunci ke agen pada penggunaan pertama (sejak versi 7.2). Anda dapat mengaktifkan fitur itu dengan memasukkan yang berikut ini ke ~/.ssh/config:

AddKeysToAgent yes

Ini juga berfungsi saat menggunakan alat turunan, seperti git.

Dari changelog 7.2 :

  • ssh (1): Tambahkan opsi klien AddKeysToAgent yang dapat diatur ke 'ya', 'tidak', 'tanyakan', atau 'konfirmasi', dan default ke 'tidak'. Saat diaktifkan, kunci pribadi yang digunakan selama otentikasi akan ditambahkan ke ssh-agent jika sedang berjalan (dengan konfirmasi diaktifkan jika diatur ke 'konfirmasi').
spheenik
sumber
Ini membutuhkan ssh-agent untuk berjalan. Lihat stackoverflow.com/a/24347344/4573065 + komentarnya untuk cara yang baik untuk memulainya (hanya sekali).
ST-DDT
18

Anda dapat menipu dan menaruh sesuatu seperti alias ssh='ssh-add -l || ssh-add && ssh'di .bashrc/ .profile. Ini berjalan pertama ssh-add -l, yang dapat mengembalikan 0 (ada kunci pada agen), 1 (tidak ada kunci) atau 2 (tidak ada agen yang berjalan); jika mengembalikan 0, sshakan berjalan; jika 1, ssh-addakan berjalan dan kemudian ssh; jika 2, ssh-addakan gagal dan sshtidak akan dijalankan. Ganti &&dengan ;jika Anda ingin sshmenjalankan bahkan ketika tidak ada agen yang berjalan.

Jessidhia
sumber
3
Itu akan meminta frasa sandi ke kunci bahkan ketika perintah ssh lebih lanjut tidak menggunakannya.
Vi.
@ Vi. true, tetapi jarang adalah perintah yang tidak menggunakannya (kecuali Anda terhubung ke server yang menggunakan keyboard-interaktif). Kuncinya akan ada di agen kapan pun Anda membutuhkannya. Juga, alias untungnya (atau sayangnya) tidak mengubah penggunaan backend dari ssh (seperti dengan git atau rsync).
Jessidhia
2
(berpikir tentang menulis tambalan auto-panggilan-ssh-tambahkan untuk klien ssh)
Vi.
Berdasarkan jawaban ini Anda dapat membuat alias untuk spesifik host: alias ssh-hostname='(ssh-add -l | grep hostname > /dev/null) || ssh-add ~/.ssh/id_rsa_hostname && ssh -p 12345 username@hostname'. Anda bahkan bisa meletakkannya dalam satu lingkaran untuk semua kunci ssh Anda dan menghasilkan alias. Retasan kotor, tetapi berhasil.
dset0x
5

Sampai auto-call-ssh-add didukung oleh ssh, saya menambahkan ini di saya .bashrc, berdasarkan proposal Kovensky:

ssh-add -l >/dev/null || alias ssh='ssh-add -l >/dev/null || ssh-add && unalias ssh; ssh'

Alias ​​dibuat hanya jika identitas tidak ditambahkan, dan alias menghancurkan dirinya sendiri setelah dijalankan.

Dengan cara ini perintah ssh biasa digunakan setelah identitas ditambahkan.

Marc MAURICE
sumber
Tidak akan berfungsi dalam kasus saya karena ssh-add juga memiliki batas waktu yang dikonfigurasi, tetapi idenya cukup baik.
Vi.
@ Vi. Bagaimana batas waktu akan memengaruhi ini? Tampaknya bekerja dengan baik untuk saya.
lanrat
1
@lanrat, Ini memeriksa apakah kunci ada di ssh-agent dan mengkonfigurasi alias tergantung pada keberadaan. Tetapi karena batas waktu ( ssh-add -t ...) kunci yang ditambahkan ke ssh-agent mungkin hilang dengan tiba-tiba, tetapi dan alias akan tetap ada karena kuncinya masih dalam memori.
Vi.
1

Saya menggunakan fungsi shell berikut:

ssh() {
    local possible_keys=($(/usr/bin/env ssh -G $@ | grep '^identityfile' \
                           | cut -d " " -f 2- | sed -e "s|^~|$HOME|"))
    for k in $possible_keys; do
        if [[ -f $k ]]; then
            local fingerprint=$(ssh-keygen -lf $k)
            ssh-add -l | grep -q "$fingerprint" || ssh-add $k
        fi
    done
    /usr/bin/env ssh $@
    return $?
}

Pertama-tama ia menyelesaikan konfigurasi untuk host yang saya coba sambungkan, kemudian menambahkan kunci yang mungkin untuk host tersebut ke ssh-agent jika belum ditambahkan dan akhirnya terhubung ke host. Saya yakin itu bisa diperbaiki, jadi saya terbuka untuk umpan balik.

mbrgm
sumber