Como ser solicitado a senha da chave SSH uma vez e somente quando necessário?

15

(Li muitas das perguntas neste site que parecem relacionadas e acredito que essa é uma pergunta genuinamente nova.)

Eu tenho muitas chaves em muitos servidores e todas elas estão protegidas com senhas.

Gosto de digitar senhas tanto quanto gosto de digitar senhas - é uma perda real de produtividade.

  • Os comandos ssh-agent + ssh-add podem ser usados ​​em um shell de login para significar que você só precisa digitar sua senha uma vez no login

  • as chaves podem ser usadas para manter um agente ssh ativo após o logout, por exemplo, você pode tê-lo para inserir a senha apenas uma vez na inicialização ou pode mantê-lo vivo por mais ou menos uma hora.

O problema que tenho é que essas duas soluções geralmente são iniciadas em um logon do shell (por exemplo .zshrc) dependem de que eu digite minha senha quando eu efetuar login, mesmo que não precise desbloqueá-la. (Não estou feliz com as chaves mantendo um agente vivo por tempo indeterminado.)

O que eu gostaria é que uma senha seja solicitada (para um agente) somente quando necessário .

Para que eu possa entrar no servidor A, fazer algumas coisas, então ssh no servidor B e , nesse momento, ser solicitada a senha. Faça algumas coisas no servidor B, efetue logout. De volta a A, faça mais algumas coisas, ssh para B novamente e não preciso da minha senha (ela é mantida por um agente).

Percebo que isso é possível em áreas de trabalho gráficas como o Gnome - você recebe um pop-up solicitando a senha para desbloquear sua chave privada assim que você tenta ssh. Então é isso que eu estou procurando, mas em um console.

artfulrobot
fonte
Por que não gerar chaves ssh sem senhas? Se você vai passar por todo esse problema, afinal?
devnull
1
Se alguém invadir e houver chaves sem senha (ou um agente ssh ativo), também poderá ter acesso a muitos outros servidores. Também chaves sem senha podem ser roubadas e usadas em outros lugares.
Artfulrobot
Tanto quanto eu sei, não há como fazer o que você quer sem sacrificar algum nível de segurança, o que parece que você não quer fazer. Houve uma resposta detalhada de Thomas Nyman aqui que aborda muitas possibilidades, se você ainda não leu: unix.stackexchange.com/a/90869/82289 . Eu entendo isso na minha empresa usando um servidor intermediário que gerencia as sessões ssh com o Tmux.
precisa saber é o seguinte
@DevNull parece estranho que você possa fazer isso com uma área de trabalho, mas não com um terminal, não? Certamente, ele só precisa que o agente pule para o tty se nenhuma chave foi adicionada? Deve ser assim que os gui funcionam?
Artfulrobot
Você pode ter um olhar sobre a minha resposta aqui: unix.stackexchange.com/a/184160/89706 (ligação da Pergunta: unix.stackexchange.com/questions/90853/... )
Johnny Wong

Respostas:

15

Não adicione nada a nenhum dos seus scripts de inicialização do shell, isso é uma invasão desnecessária.

Em vez disso, adicione

AddKeysToAgent yes

para o seu .ssh / config

Assim, o ssh-add é executado automaticamente na primeira vez que você ssh em outra caixa. Você só precisa digitar novamente sua chave quando ela expirar do ssh-agent ou após a reinicialização.

Toby
fonte
Eu gostaria que as pessoas comentassem ao votar. Se não está certo, é importante, sabemos por que não está certo. Obrigado por postar, ainda não tive tempo de tentar sua sugestão.
Artfulrobot
Também me perguntei, talvez por causa das minhas postagens cruzadas?
Toby
Isso funciona para mim. No entanto, é uma adição muito recente ao openssh (7.2). Caso ajude alguém, o openssh 7.3 está disponível no Debian Sid.
Artfulrobot 3/16
@artfulrobot: Estranho, pois eu tive esse mesmo comportamento (auto-ssh-add na primeira chamada do ssh) trabalhando por anos, até que finalmente parou há algum tempo. Procurando a causa, encontrei AddKeysToAgent e presumi que a razão pela qual ele parou foi que, por acidente, devo ter limpado meu .ssh / config e AddKeysToAgent junto com ele. Agora eu me pergunto por que estava funcionando muito antes do OpenSSH 7.2 ser lançado? Eu não estou imaginando isso :-)
Toby
@ Toby isto é exatamente o que eu preciso. Infelizmente, o ssh-agent não parece iniciar automaticamente no kubuntu, então é a próxima coisa que preciso resolver.
Ogaday
7

O Zsh possui um preexecgancho que executa uma função antes que um comando digitado na linha de comando seja executado. Aqui está um gancho que procura sshna sua linha de comando e, se encontrado, verifica a existência de um agente ssh. Se isso não for encontrado, ele executa o chaveiro.

Dessa forma, o chaveiro é executado apenas antes dos comandos ssh e, somente se necessário.

Coloque isso no seu ~/.zshrc:

function check_ssh {
  [[ $3 =~ '\bssh\b' ]] || return
  [[ -n "$SSH_AGENT_PID" && -e "/proc/$SSH_AGENT_PID" ]] \
    && ssh-add -l >/dev/null && return
  eval `keychain --eval id_dsa --timeout 60`
}    
autoload -U add-zsh-hook
add-zsh-hook preexec check_ssh

O que acontece aqui é que sempre que um comando é digitado, check_sshé chamado antes que o comando seja executado.

A primeira linha da função verifica o comando expandido para sshusar um regex Zsh. sshdeve ter limites de palavras em \bambos os lados. Se isso não for encontrado, a função retornará.

A próxima linha verifica se há um processo do agente SSH na variável de ambiente e se esse processo ainda existe na tabela de processos e se pelo menos uma chave foi adicionada ao agente. Se tudo estiver correto, o agente ssh está configurado e não precisamos fazer nada; portanto, ele retorna.

Finalmente começamos o chaveiro, com o agente sendo mantido vivo por uma hora.

Ainda deixa o problema sobre coisas ssh incorporadas, como gitou rsyncouscp como que não vai acionar a função (você pode adicioná-los à regex).

artfulrobot
fonte
Mesmo sem zsh, pode-se criar um script curto com o mesmo efeito e colocá-lo PATHdiante do sshcliente real . Pode até funcionar com rsyncet al, se eles lerem em PATHvez de executar /usr/bin/sshdiretamente.
ilkkachu
2

Para o zsh, escrevi um conjunto de utilitários e wrappers para fazer mais ou menos o que você deseja: https://www.vinc17.net/unix/index.en.html#zsh-ssh-utils

Na verdade, isso faz ainda mais, porque o ssh-agentserá compartilhado por todas as sessões de login (desktop ou via SSH, e o GNU Screen também é suportado se você iniciar os shells de login a partir dele, por exemplo, shell -zshno ~/.screenrcarquivo), e só será fechado após o a última sessão termina.

Nota: Eu uso apenas uma senha para todas as minhas chaves. Não tenho certeza do comportamento de diferentes senhas; pode haver algumas mudanças.

vinc17
fonte
Uau, isso é bastante código. Bom trabalho e obrigado por compartilhar. Acho que preciso de algo mais simples - o SSH é uma ferramenta essencial para mim.
Artfulrobot