Wie wird ssh-agent veranlasst, den Schlüssel bei Bedarf automatisch hinzuzufügen?

50

Ich möchte ssh-agent ausführen (mit der Option "Maximale Lebensdauer"), aber beim Start keine Schlüssel hinzufügen, sondern sie bei Bedarf hinzufügen.

Wenn ich mich zum ersten Mal bei einem Server anmelde, sollte er beim nächsten Mal nach der Passphrase fragen (es sei denn, ich habe länger als eine Stunde gewartet), und die Verbindung sollte sauber hergestellt werden:

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

Ich möchte nicht jedes Mal manuell daran denken, 'ssh-add' auszuführen. (zB eingegebene Passphrase für nur für ssh und "Oh, es hat sich nicht erinnert, muss neu eingegeben werden").

Wie konfiguriere ich ssh so, dass der Schlüssel automatisch zu ssh-agent hinzugefügt wird, wenn der Benutzer die Passphrase angegeben hat?

Vi.
quelle

Antworten:

56

ssh unterstützt das Hinzufügen eines Schlüssels zum Agenten bei der ersten Verwendung (seit Version 7.2). Sie können diese Funktion aktivieren, indem Sie Folgendes eingeben ~/.ssh/config:

AddKeysToAgent yes

Dies funktioniert auch, wenn abgeleitete Tools wie git verwendet werden.

Aus dem 7.2 Changelog :

  • ssh (1): Fügen Sie eine AddKeysToAgent-Clientoption hinzu, die auf "Ja", "Nein", "Fragen" oder "Bestätigen" und standardmäßig auf "Nein" gesetzt werden kann. Wenn diese Option aktiviert ist, wird ein privater Schlüssel, der während der Authentifizierung verwendet wird, zu ssh-agent hinzugefügt, wenn dieser ausgeführt wird (mit aktivierter Bestätigung, wenn 'confirm' festgelegt ist).
Spheenik
quelle
Dazu muss ein ssh-agent ausgeführt werden. Siehe stackoverflow.com/a/24347344/4573065 + seine Kommentare für einen guten Weg , um es zu starten (nur einmal).
ST-DDT
18

Sie könnten schummeln und etwas alias ssh='ssh-add -l || ssh-add && ssh'auf Ihr .bashrc/ setzen .profile. Dieser erste Lauf ssh-add -lkann 0 (es sind Schlüssel auf dem Agenten vorhanden), 1 (keine Schlüssel) oder 2 (kein Agent läuft) zurückgeben. Wenn es 0 zurückgibt, sshwird ausgeführt. Wenn 1, ssh-addwird ausgeführt und dann ssh; Wenn 2, ssh-addwird fehlschlagen und sshnicht ausgeführt. Ersetzen Sie das &&durch, ;wenn Sie sshausführen möchten , auch wenn kein Agent ausgeführt wird.

Kovensky
quelle
3
Es fordert eine Passphrase für den Schlüssel an, auch wenn ein weiterer ssh-Befehl diese nicht verwendet.
Vi.
@Vi. true, aber selten sind die Befehle, die sie nicht verwenden (es sei denn, Sie stellen eine Verbindung zu einem Server her, der keyboard-interactive verwendet). Der Schlüssel befindet sich jedoch immer dann im Agenten, wenn Sie ihn später benötigen. Außerdem ändert der Alias ​​glücklicherweise (oder leider) nicht die Backend-Verwendung von ssh (wie bei git oder rsync).
Kovensky
2
(Denken Sie daran, einen Auto-Call-SSH-Add-Patch für den SSH-Client zu schreiben.)
Vi.
Auf der Grundlage dieser Antwort können Sie ein Aliase für eine bestimmte Hosts erstellen: alias ssh-hostname='(ssh-add -l | grep hostname > /dev/null) || ssh-add ~/.ssh/id_rsa_hostname && ssh -p 12345 username@hostname'. Sie können dies sogar in eine Schleife für alle Ihre ssh-Schlüssel einfügen und Aliase generieren. Ein dreckiger Hack, aber es funktioniert.
dset0x
5

Bis auto-call-ssh-add von ssh unterstützt wird, habe ich dies in meinem .bashrc, auf Kovensky basierenden Vorschlag hinzugefügt:

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

Der Alias ​​wird nur erstellt, wenn die Identität nicht hinzugefügt wird und der Alias ​​sich selbst zerstört, sobald er ausgeführt wird.

Auf diese Weise wird der reguläre Befehl ssh verwendet, nachdem die Identität hinzugefügt wurde.

Marc MAURICE
quelle
Funktioniert in meinem Fall nicht, da ssh-add ebenfalls ein Timeout konfiguriert hat, aber die Idee ist gut genug.
Vi.
@Vi. Wie würde sich ein Timeout darauf auswirken? Es scheint großartig für mich zu funktionieren.
Lanrat
1
@lanrat, Prüft, ob der Schlüssel im ssh-agent vorhanden ist und konfiguriert den Alias ​​abhängig von der Anwesenheit. Aufgrund von timeout ( ssh-add -t ...) verschwindet der zu ssh-agent hinzugefügte Schlüssel möglicherweise abrupt, und der Alias ​​bleibt bestehen, da sich der Schlüssel noch im Speicher befindet.
Vi.
0

Ich benutze die folgende Shell-Funktion:

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 $?
}

Zunächst wird die Konfiguration für den Host, zu dem ich eine Verbindung herstellen möchte, aufgelöst. Anschließend werden dem ssh-agent mögliche Schlüssel für diesen Host hinzugefügt, sofern diese noch nicht hinzugefügt wurden, und schließlich wird eine Verbindung zum Host hergestellt. Ich bin sicher, dass es verbessert werden kann, also bin ich offen für Feedback.

mbrgm
quelle