Думаю, мне придется ответить на свой вопрос, поскольку, похоже, нет никакого способа запросить идентификацию по имени файла.
Я написал быстрые и грязные сценарии Python, которые создают файл открытого ключа в .ssh / fingerprints
для каждого ключа, который держит агент. Затем я могу указать этот файл, который не содержит секретного ключа, используя IdentityFile
, и SSH выберет правильную идентификацию от агента SSH. Работает отлично и позволяет мне использовать агент для любого количества закрытых ключей.
#!/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()
Запустите
ssh-add -L | gawk ' { print $2 > $3 ".pub" } '
на удаленном компьютере, чтобы автоматически сгенерировать все файлы открытых ключей (при условии, что открытые ключи находятся в вашем .ssh / config
] имеют имя privateKeyFileName.pub
, и никакие несогласованные пути не задействованы). Для обращения к sudo
вызовите chown $ USER .ssh / *
.
Исходя из принятого решения и предполагая, что вы просто хотите повторно использовать идентификатор, используемый для получения доступа к начальному серверу, тогда достаточно чего-то вроде:
Host github.com
IdentitiesOnly yes
IdentityFile ~/.ssh/authorized_keys
.
Одним из вариантов является создание небольшого сценария-оболочки для SSH, который может пересылать правильный открытый ключ из агента SSH. Вот рабочее доказательство концепции:
#!/usr/bin/env bash
# SSH with specific identity that has been previously added to the ssh-agent.
# Public key file need not exist.
# Usage: First argument is the ssh key fingerprint of the identity you want to
# use. All further arguments will be forwarded to ssh directly.
#
# Ex: ssh-with-key SHA256:VrzNKaV7VcU7jT7hLZJMxxAo6whPc+VVXKaH0exqXiM user@host
set -euo pipefail
fingerprint="$1"
shift
# List ssh-agent fingerprints and public keys, get public key that corresponds
# to the line number of the fingerprint.
pub_key="$(awk 'line == null && "'"$fingerprint"'" {line=FNR; nextfile}; line == FNR' <(ssh-add -l) <(ssh-add -L))"
# Save public key to temporary file.
# NB: Can't use process substitution here. Bash passes substituted argument as
# a /dev/fd file, and ssh closes all /dev/fd files other than stdin, stdout,
# and stderr before processing CLI options.
pub_key_file=$(mktemp)
echo $pub_key > $pub_key_file
cleanup() {
rm -f $pub_key_file
}
trap cleanup EXIT
ssh -o IdentitiesOnly=yes -i $pub_key_file "$@"
Вы можете создать отдельный конфигурационный файл, чтобы связать отпечатки ключа SSH с одним или несколькими именами хостов или псевдонимами для удобства использования.
Преимущество этого метода заключается в том, что вам не нужно выполнять предварительную или периодическую обработку открытых ключей, кроме добавления их в агент SSH. Файлы открытых ключей записываются по мере необходимости и удаляются, как только сеанс заканчивается.