Как заставить ssh-agent автоматически добавлять ключ по требованию?

51

Я хочу запустить ssh-agent (с параметром максимального срока службы), но не добавлять ключи при запуске, а вместо этого добавлять их по требованию.

Как и при первом входе в систему на каком-либо сервере, он должен запросить парольную фразу, в следующий раз (если я не ждал более часа) он должен подключиться корректно:

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

Я не хочу вручную помнить о запуске ssh-add каждый раз. (например, введенная фраза только для ssh и «О, он не запомнил, нужно перепечатать»).

Как настроить ssh для автоматического добавления ключа в ssh-agent, если пользователь предоставил ключевую фразу?

Vi.
источник

Ответы:

58

ssh поддерживает добавление ключа к агенту при первом использовании (начиная с версии 7.2). Вы можете включить эту функцию, поместив следующее в ~/.ssh/config:

AddKeysToAgent yes

Это также работает при использовании производных инструментов, таких как git.

Из журнала изменений 7.2 :

  • ssh (1): добавить клиентскую опцию AddKeysToAgent, для которой можно установить «да», «нет», «спросить» или «подтвердить», а по умолчанию - «нет». Когда включено, закрытый ключ, который используется во время аутентификации, будет добавлен в ssh-agent, если он работает (с подтверждением, включенным, если установлено «подтверждение»).
spheenik
источник
Это требует запуска ssh-agent. Обратитесь к stackoverflow.com/a/24347344/4573065 + его комментарии для хорошего способа его запуска (только один раз).
ST-DDT
18

Вы могли бы обмануть и поставить что-то вроде alias ssh='ssh-add -l || ssh-add && ssh'вашего .bashrc/ .profile. Это первый запуск ssh-add -l, который может возвращать 0 (есть ключи на агенте), 1 (нет ключей) или 2 (агент не запущен); если он вернет 0, sshбудет работать; если 1, ssh-addбудет работать, а затем ssh; если 2, ssh-addпотерпит неудачу и sshне будет запущен. Заменить &&с , ;если вы хотите sshработать , даже когда нет агента работает.

Jessidhia
источник
3
Он будет запрашивать пароль для ключа, даже если дальнейшая команда ssh не использует его.
Ви.
@Vi. правда, но редко встречаются команды, которые их не используют (если только вы не подключаетесь к серверу, использующему интерактивную клавиатуру). Ключ будет в агенте всякий раз, когда он вам понадобится впоследствии. Кроме того, псевдоним, к счастью (или к сожалению), не меняет использование ssh в бэкэнде (например, с помощью git или rsync).
Джессидия
2
(думает о написании патча auto-call-ssh-add для клиента ssh)
Vi.
На основании этого ответа вы можете создать псевдонимы для конкретных хостов: alias ssh-hostname='(ssh-add -l | grep hostname > /dev/null) || ssh-add ~/.ssh/id_rsa_hostname && ssh -p 12345 username@hostname'. Вы можете даже поместить это в цикл для всех ваших ключей ssh ​​и генерировать псевдонимы. Грязный хак, но это работает.
dset0x
5

До тех пор пока ssh не поддерживает auto-call-ssh-add, я добавил это в свой .bashrc, основываясь на предложении Ковенского:

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

Псевдоним создается только в том случае, если идентификатор не добавляется, а псевдоним уничтожается сам после запуска.

Таким образом, обычная команда ssh используется после добавления идентификатора.

Марк Морис
источник
Не будет работать в моем случае, потому что ssh-add также настроили время ожидания, но идея достаточно хороша.
Ви.
@Vi. Как тайм-аут повлияет на это? Кажется, это отлично работает для меня.
Ланрат
1
@lanrat, проверяет наличие ключа в ssh-agent и настраивает псевдоним в зависимости от наличия. Но из-за timeout ( ssh-add -t ...) ключ, добавленный в ssh-agent, может внезапно исчезнуть, но псевдоним останется, так как ключ все еще находится в памяти.
Ви.
1

Я использую следующую функцию оболочки:

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

Сначала он разрешает конфигурацию хоста, к которому я пытаюсь подключиться, затем добавляет возможные ключи для этого хоста в ssh-agent, если они еще не добавлены, и, наконец, подключается к хосту. Я уверен, что это может быть улучшено, поэтому я открыт для обратной связи.

mbrgm
источник