Eu estava tentando resolver esse problema enquanto gerava os keypairs e os armazenava em um banco de dados com o Python. Abaixo estão alguns dos passos que acabei usando, começando ssh-agent
e interagindo com ele. É em Python, mas presumivelmente você poderia traduzi-lo para qualquer outra coisa. Outra característica é que nenhum desses usa shell=True
, então eles são mais seguros contra ataques de injeção.
import subprocess
import os
sockfile = '/some/place.sock'
agent = subprocess.Popen(['ssh-agent',
'-D', # foreground mode
'-a', sockfile, # bind address (socket file)
])
subprocess.check_call(['ssh-add',
'-D', # delete all identities from the agent
],
env={'SSH_AUTH_SOCK': sockfile},
)
Isso gera um ssh-agent
apenas para o nosso programa e limpa (acredito que esteja carregando minhas chaves de usuário nele, não tenho certeza.) A variável de ambiente SSH_AUTH_SOCK
normalmente definida por ssh-agent
(mas que fizemos manualmente), estamos alimentando outros programas.
Em seguida, usamos ssh-add
para alimentá-lo com a chave privada (aqui ele é armazenado em dr.private_key
como uma string, mas eu preciso serializá-lo, então eu o codifico como ASCII).
adder = subprocess.Popen(['ssh-add',
'-', # read key from stdin
],
env={'SSH_AUTH_SOCK': sockfile},
stdin=subprocess.PIPE,
)
adder.communicate(dr.private_key.encode('ascii'))
retval = adder.wait()
assert retval == 0 # added successfully
Agora, sempre que eu uso algum aplicativo que usa SSH, por exemplo Git, eu indico para usar o mesmo socket de agente SSH:
gitp = subprocess.Popen(
['git', '-C', os.path.abspath('../some-repo') ,'fetch'],
env={'SSH_AUTH_SOCK': sockfile},
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
)
print(gitp.communicate()[0].decode('ascii'))
e funciona muito bem. O único "arquivo temporário" é o soquete usado por ssh-agent
, mas é criado de modo que apenas o proprietário tenha permissões para ele e é removido quando você termina o agente.