Выберите личность в ssh-agent по имени файла

9

Проблема: у меня есть 20-30 ssh-agentличностей. Большинство серверов отказывают в аутентификации Too many failed authentications, поскольку SSH обычно не позволяет мне попробовать 20 различных ключей для входа в систему.

В данный момент я указываю файл идентификации для каждого хоста вручную, используя директиву IdentityFileand IdentitiesOnly, чтобы SSH попробовал только один файл ключа, который работает.

К сожалению, это перестает работать, как только оригинальные ключи больше не доступны. ssh-add -lпоказывает мне правильные пути для каждого ключевого файла, и они совпадают с путями .ssh/config, но это не работает. Очевидно, SSH выбирает идентификационные данные по подписи открытого ключа, а не по имени файла, что означает, что исходные файлы должны быть доступны, чтобы SSH мог извлечь открытый ключ.

Есть две проблемы с этим:

  • он перестает работать, как только я отключаю флешку с ключами
  • это делает пересылку агента бесполезной, поскольку файлы ключей недоступны на удаленном хосте

Конечно, я мог бы извлечь открытые ключи из моих файлов идентификации и сохранить их на своем компьютере и на каждом удаленном компьютере, на котором я обычно захожу. Это не похоже на желаемое решение, хотя.

Что мне нужно, так это возможность выбрать идентификатор из ssh-agent по имени файла, чтобы я мог легко выбрать правильный ключ, используя .ssh/configили передавая -i /path/to/original/key, даже на удаленном хосте, в который я входил по SSH. Было бы еще лучше, если бы я мог «прозвать» ключи, чтобы мне даже не пришлось указывать полный путь.

leoluk
источник
1
Зачем вам много SSH-личностей? Если вы не хотите, чтобы один скомпрометированный закрытый ключ давал доступ ко всем вашим учетным записям, то почему вы храните их все на одной флешке? Это не первый раз, когда я слышу о проблемах, связанных с управлением несколькими идентификаторами SSH, но у меня никогда не было возможности спросить, зачем они нужны.
Дмитрий Чубаров
Никогда не говорил, что все они на одной флешке.
leoluk
3
@DmitriChubarov Одним из возможных приложений для нескольких идентификаторов SSH является authorized_keysфайл, который, в зависимости от используемого ключа, выполняет различные команды, даже не разрешая прямой доступ к оболочке.
Тобиас Кинцлер

Ответы:

8

Думаю, мне придется ответить на мой собственный вопрос, поскольку, похоже, нет способа запросить личность по имени файла.

Я написал быстрые скрипты 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()
leoluk
источник
Хорошая работа, я попробую это скоро
Тобиас Кинцлер
3

Запустить

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

на удаленной машине, чтобы автоматически сгенерировать все файлы открытых ключей (при условии, что открытые ключи в вашем .ssh/configназваны, privateKeyFileName.pubи пути к ним отсутствуют). Позвоните chown $USER .ssh/*по вашему sudoделу.

Тобиас Кинцлер
источник
1

Выбирая из принятого решения и предполагая, что вы просто хотите повторно использовать идентификатор, используемый для получения доступа к исходному серверу, тогда что-то вроде:

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

достаточно.

Кэгни
источник
это не работает для меня. Когда идентификационный файл имеет только один открытый ключ - он работает, но не когда несколько.
Игрек