Escolha a identidade do ssh-agent pelo nome do arquivo

9

Problema: tenho entre 20 ssh-agente 30 identidades. A maioria dos servidores recusa a autenticação Too many failed authentications, pois o SSH geralmente não permite que eu tente 20 chaves diferentes para fazer login.

No momento, estou especificando o arquivo de identidade para cada host manualmente, usando IdentityFilea IdentitiesOnlydiretiva e, para que o SSH tente apenas um arquivo-chave, que funcione.

Infelizmente, isso para de funcionar assim que as chaves originais não estão mais disponíveis. ssh-add -lmostra os caminhos corretos para cada arquivo-chave e eles correspondem aos caminhos .ssh/config, mas não funciona. Aparentemente, o SSH seleciona a identidade pela assinatura da chave pública e não pelo nome do arquivo, o que significa que os arquivos originais precisam estar disponíveis para que o SSH possa extrair a chave pública.

Existem dois problemas com isso:

  • ele pára de funcionar assim que eu desconecto a unidade flash segurando as teclas
  • torna inútil o encaminhamento do agente, pois os arquivos principais não estão disponíveis no host remoto

Obviamente, eu poderia extrair as chaves públicas dos meus arquivos de identidade e armazená-las no meu computador e em todos os computadores remotos nos quais normalmente faço login. Porém, isso não parece uma solução desejável.

O que eu preciso é da possibilidade de selecionar uma identidade do ssh-agent pelo nome do arquivo, para que eu possa selecionar facilmente a chave correta usando .ssh/configou passando -i /path/to/original/key, mesmo em um host remoto no qual eu SSH. Seria ainda melhor se eu pudesse "apelidar" as chaves para não precisar especificar o caminho completo.

leoluk
fonte
1
Por que você precisa de muitas identidades ssh? Se é para evitar que uma chave privada comprometida dê acesso a todas as suas contas, por que você as mantém em uma única unidade flash? Não é a primeira vez que ouço problemas relacionados ao gerenciamento de múltiplas identidades ssh, mas nunca tive a chance de perguntar por que eles são necessários.
Dmitri Chubarov
Nunca disse que todos eles estão em uma unidade flash.
leoluk
3
@DmitriChubarov Um aplicativo possível para várias identidades ssh é um authorized_keysarquivo que, dependendo da chave usada, executa comandos diferentes, sem nunca permitir o acesso direto ao shell.
21412 Tobias Kienzler

Respostas:

8

Acho que vou ter que responder minha própria pergunta, pois parece não haver maneira de solicitar uma identidade pelo nome do arquivo.

Escrevi scripts Python rápidos e sujos que criam um arquivo de chave pública .ssh/fingerprintspara todas as chaves que o agente possui. Posso então especificar esse arquivo, que não contém chave secreta, usando IdentityFilee o SSH selecionará a identidade correta do agente SSH. Funciona perfeitamente e permite que eu use o agente para quantas chaves privadas eu desejar.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""Dumps all public keys held by ssh-agent and stores them in ~/.ssh/fingerprints/, so that
they can be identified using the IdentityFile directive.

"""

import sys, os
import stat
import re
import envoy

RE_MATCH_FILENAME = re.compile(r'([^\\/:*?"<>|\r\n]+)\.\w{2,}$', re.IGNORECASE)

if os.getuid() == 0:
    USERNAME = os.environ['SUDO_USER']
else:
    USERNAME = os.environ['USER']

def error(message):
    print "Error:", message
    sys.exit(1)

def main():
    keylist = envoy.run('ssh-add -L').std_out.strip('\n').split('\n')

    if len(keylist) < 1:
        error("SSH-Agent holds no indentities")

    for key in keylist:
        crypto, ckey, name = key.split(' ')
        filename = os.path.join(os.environ['HOME'], '.ssh/fingerprints',
                  RE_MATCH_FILENAME.search(name).group(1)+'.pub')

        with open(filename, 'w') as f:
            print "Writing %s ..." % filename
            f.write(key)

        envoy.run('chmod 600 %s' % filename)
        envoy.run('chown %s %s' % (USERNAME, filename))


if __name__ == '__main__':
    main()
leoluk
fonte
Bom trabalho, vou tentar isso em breve #
Tobias Kienzler 17/10/12
3

Corre

ssh-add -L | gawk ' { print $2 > $3 ".pub" } '

na máquina remota para gerar automaticamente todos os arquivos de chave pública (assumindo que as chaves públicas em seu .ssh/confignome sejam nomeadas privateKeyFileName.pube que nenhum caminho inconsitente esteja envolvido). Ligue chown $USER .ssh/*para o seu sudocaso.

Tobias Kienzler
fonte
1

Pegando a solução aceita e supondo que você deseja apenas reutilizar a identidade usada para obter acesso ao servidor inicial, algo como:

Host github.com
    IdentitiesOnly yes
    IdentityFile ~/.ssh/authorized_keys

é suficiente.

cagney
fonte
isso não funciona para mim. Quando o arquivo de identidade possui apenas uma chave pública - ele funciona, mas não quando múltiplos.
Ygrek