Como fazer com que o ssh-agent adicione automaticamente a chave sob demanda?

51

Quero executar o ssh-agent (com a opção de duração máxima), mas não adicionar nenhuma chave na inicialização, mas adicioná-las sob demanda.

Como na primeira vez em que inicio sessão em algum servidor, ele deve solicitar uma senha, na próxima vez (a menos que espere mais de uma hora), ele deve se conectar corretamente:

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

Não quero me lembrar manualmente de executar o 'ssh-add' toda vez. (por exemplo, senha inserida apenas para ssh e "Ah, não se lembra, é preciso redigitar").

Como configurar o ssh para adicionar automaticamente a chave ao ssh-agent se o usuário forneceu a senha?

Vi.
fonte

Respostas:

58

O ssh suporta a adição de uma chave ao agente no primeiro uso (desde a versão 7.2). Você pode ativar esse recurso colocando o seguinte em ~/.ssh/config:

AddKeysToAgent yes

Isso também funciona ao usar ferramentas derivadas, como o git.

No log de alterações 7.2 :

  • ssh (1): adicione uma opção de cliente AddKeysToAgent que pode ser definida como 'yes', 'no', 'ask' ou 'confirm' e o padrão é 'no'. Quando ativada, uma chave privada usada durante a autenticação será adicionada ao ssh-agent se estiver em execução (com a confirmação ativada se configurada como 'confirm').
spheenik
fonte
Isso requer que um ssh-agent esteja em execução. Consulte stackoverflow.com/a/24347344/4573065 + seus comentários para uma boa maneira de iniciá-lo (apenas uma vez).
ST-DDT
18

Você pode trapacear e colocar algo como alias ssh='ssh-add -l || ssh-add && ssh'no seu .bashrc/ .profile. Isso é executado primeiro ssh-add -l, o que pode retornar 0 (existem chaves no agente), 1 (sem chaves) ou 2 (nenhum agente em execução); se retornar 0, sshserá executado; se 1, ssh-addserá executado e depois ssh; se 2, ssh-addfalhará e sshnão será executado. Substitua &&por ;se desejar sshexecutar mesmo quando não houver nenhum agente em execução.

Jessidhia
fonte
3
Ele solicitará a senha da chave mesmo quando o comando ssh adicional não a usar.
Vi.
@Vi. verdadeiro, mas raro são os comandos que não os usam (a menos que você esteja se conectando a um servidor que usa teclado interativo). A chave estará no agente sempre que você precisar delas posteriormente. Além disso, felizmente (ou infelizmente) o alias não altera os usos de back-end do ssh (como com git ou rsync).
Jessidhia
2
(pensando em escrever o patch auto-call-ssh-add para o cliente ssh)
Vi.
Com base nessa resposta que você pode criar um alias para um específicas anfitriões: alias ssh-hostname='(ssh-add -l | grep hostname > /dev/null) || ssh-add ~/.ssh/id_rsa_hostname && ssh -p 12345 username@hostname'. Você pode colocar isso em loop para todas as suas chaves ssh e gerar aliases. Um truque sujo, mas funciona.
precisa
5

Até que o auto-call-ssh-add seja suportado pelo ssh, eu adicionei isso no meu .bashrc, com base na proposta de Kovensky:

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

O alias é criado apenas se a identidade não for adicionada e o alias se destrói uma vez executado.

Dessa forma, o comando ssh regular é usado após a adição da identidade.

Marc MAURICE
fonte
Não vai funcionar no meu caso por causa do ssh-add também tem tempo limite configurado, mas a ideia é boa o suficiente.
Vi.
@Vi. Como um tempo limite afetaria isso? Parece funcionar muito bem para mim.
lanrat
1
@lanrat, verifica se a chave está presente no ssh-agent e configura o alias, dependendo da presença. Porém, devido ao timeout ( ssh-add -t ...), a chave adicionada ao ssh-agent pode desaparecer abruptamente, mas o alias permanecerá, pois a chave ainda está na memória.
Vi.
1

Estou usando a seguinte função shell:

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

Primeiro, ele resolve a configuração do host ao qual estou tentando me conectar e, em seguida, adiciona as chaves possíveis para esse host ao ssh-agent se elas ainda não foram adicionadas e, finalmente, se conectam ao host. Tenho certeza de que pode ser melhorado, por isso estou aberto a feedback.

mbrgm
fonte