Jak sprawić, aby ssh-agent automatycznie dodawał klucz na żądanie?

51

Chcę uruchomić ssh-agent (z opcją maksymalnego czasu życia), ale nie dodawać żadnych kluczy przy uruchamianiu, ale zamiast tego dodawać je na żądanie.

Podobnie jak przy pierwszym logowaniu do jakiegoś serwera, powinien poprosić o hasło, następnym razem (chyba że zaczekam ponad godzinę) powinien połączyć się czysto:

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

Nie chcę ręcznie pamiętać o uruchamianiu „ssh-add” za każdym razem. (np. wprowadzono hasło tylko dla ssh i „Och, nie pamiętam, trzeba ponownie wpisać”).

Jak skonfigurować ssh, aby automatycznie dodawał klucz do ssh-agent, jeśli użytkownik podał hasło?

Vi.
źródło

Odpowiedzi:

58

ssh obsługuje dodanie klucza do agenta przy pierwszym użyciu (od wersji 7.2). Możesz włączyć tę funkcję, umieszczając następujące elementy w ~/.ssh/config:

AddKeysToAgent yes

Działa to również podczas korzystania z narzędzi pochodnych, takich jak git.

Z dziennika zmian 7.2 :

  • ssh (1): Dodaj opcję klienta AddKeysToAgent, która może być ustawiona na „tak”, „nie”, „pytaj” lub „potwierdź” i domyślnie ma wartość „nie”. Po włączeniu klucz prywatny używany podczas uwierzytelniania zostanie dodany do ssh-agent, jeśli jest uruchomiony (z włączonym potwierdzeniem, jeśli jest ustawione na „potwierdź”).
spheenik
źródło
Wymaga to uruchomienia agenta ssh. Zapoznaj się z stackoverflow.com/a/24347344/4573065 + jego komentarzami, aby znaleźć dobry sposób na uruchomienie (tylko raz).
ST-DDT,
18

Możesz oszukiwać i umieszczać coś alias ssh='ssh-add -l || ssh-add && ssh'na swoim .bashrc/ .profile. To pierwsze uruchomienie ssh-add -l, które może zwrócić 0 (agent ma klucze), 1 (brak kluczy) lub 2 (agent nie działa); jeśli zwróci 0, sshuruchomi się; jeśli 1, ssh-adduruchomi się, a następnie ssh; jeśli 2, ssh-addzawiedzie i sshnie zostanie uruchomiony. Wymień &&się ;, jeśli chcesz sshuruchomić nawet wtedy, gdy nie ma bieg agentem.

Jessidhia
źródło
3
Zażąda hasła do klucza, nawet jeśli dalsze polecenie ssh go nie używa.
Vi.
@Vi. prawda, ale rzadkie są polecenia, które ich nie używają (chyba że łączysz się z serwerem, który używa klawiatury interaktywnej). Klucz będzie jednak w agencie, gdy będziesz go potrzebować później. Ponadto, alias na szczęście (lub niestety) nie zmienia użycia backendu przez ssh (na przykład z git lub rsync).
Jessidhia,
2
(zastanawiając się nad napisaniem łatki auto-call-ssh-add dla klienta ssh)
Vi.
Na podstawie tej odpowiedzi można utworzyć aliasy dla konkretnego zastępów alias ssh-hostname='(ssh-add -l | grep hostname > /dev/null) || ssh-add ~/.ssh/id_rsa_hostname && ssh -p 12345 username@hostname'. Możesz nawet umieścić to w pętli dla wszystkich swoich kluczy ssh i generować aliasy. Brudny hack, ale działa.
dset0x 19.04.13
5

Dopóki ssh nie obsługuje automatycznego wywołania-ssh-add, dodałem to w mojej .bashrc, na podstawie propozycji Kovensky'ego:

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

Alias ​​jest tworzony tylko wtedy, gdy tożsamość nie zostanie dodana, a alias sam się zniszczy po uruchomieniu.

W ten sposób zwykłe polecenie ssh jest używane po dodaniu tożsamości.

Marc MAURICE
źródło
Nie będzie działać w moim przypadku, ponieważ ssh-add ma również skonfigurowany limit czasu, ale pomysł jest wystarczająco dobry.
Vi.
@Vi. Jak wpłynie to na limit czasu? Wydaje mi się, że działa świetnie.
lanrat
1
@lanrat, Sprawdza, czy klucz jest obecny w ssh-agent i konfiguruje alias w zależności od obecności. Ale z powodu timeout ( ssh-add -t ...) klucz dodany do ssh-agent może nagle zniknąć, ale alias pozostanie, ponieważ klucz jest nadal w pamięci.
Vi.
1

Korzystam z następującej funkcji powłoki:

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

Najpierw rozwiązuje konfigurację hosta, z którym próbuję się połączyć, a następnie dodaje możliwe klucze dla tego hosta do agenta ssh, jeśli nie zostały jeszcze dodane, a na końcu łączy się z hostem. Jestem pewien, że można to poprawić, dlatego jestem otwarty na opinie.

mbrgm
źródło