Wybierz tożsamość z ssh-agent według nazwy pliku

9

Problem: Mam około 20-30 ssh-agenttożsamości. Większość serwerów odmawia uwierzytelnienia Too many failed authentications, ponieważ SSH zwykle nie pozwala mi wypróbować 20 różnych kluczy, aby się zalogować.

W tej chwili jestem ręcznie określając plik tożsamości dla każdego hosta, przy użyciu IdentityFile, a IdentitiesOnlydyrektywy, tak że SSH będzie próbował jeden plik klucza, który działa tylko.

Niestety przestaje to działać, gdy oryginalne klucze nie będą już dostępne. ssh-add -lpokazuje mi poprawne ścieżki dla każdego pliku klucza i pasują do ścieżek w .ssh/config, ale to nie działa. Najwyraźniej SSH wybiera wcięcie według podpisu klucza publicznego, a nie według nazwy pliku, co oznacza, że ​​oryginalne pliki muszą być dostępne, aby SSH mógł wyodrębnić klucz publiczny.

Są z tym dwa problemy:

  • przestaje działać, gdy tylko odłączę dysk flash przytrzymujący klawisze
  • sprawia, że ​​przekazywanie agentów jest bezużyteczne, ponieważ pliki kluczy nie są dostępne na zdalnym hoście

Oczywiście mogę wyodrębnić klucze publiczne z moich plików tożsamości i zapisać je na moim komputerze oraz na każdym komputerze zdalnym, na którym zwykle się loguję. Nie wydaje się to jednak pożądanym rozwiązaniem.

Potrzebuję możliwości wybrania tożsamości z ssh-agent według nazwy pliku, dzięki czemu mogę łatwo wybrać odpowiedni klucz za pomocą .ssh/configlub przekazując -i /path/to/original/key, nawet na zdalnym hoście, do którego SSH wybrałem. Byłoby jeszcze lepiej, gdybym mógł „nadać pseudonim” kluczom, aby nawet nie musiałem określać pełnej ścieżki.

leoluk
źródło
1
Dlaczego potrzebujesz wielu tożsamości ssh? Jeśli ma to na celu uniknięcie jednego skompromitowanego klucza prywatnego zapewniającego dostęp do wszystkich kont, to dlaczego przechowujesz je wszystkie na jednym dysku flash? Nie pierwszy raz słyszę o problemach związanych z zarządzaniem wieloma tożsamościami ssh, ale nigdy nie miałem okazji zapytać, dlaczego są potrzebne.
Dmitrij Chubarow
Nigdy nie mówiłem, że wszystkie są na jednym dysku flash.
leoluk
3
@DmitriChubarov Jedną z możliwych aplikacji dla wielu tożsamości ssh jest authorized_keysplik, który w zależności od użytego klucza wykonuje różne polecenia, nigdy nie zezwalając na bezpośredni dostęp do powłoki.
Tobias Kienzler

Odpowiedzi:

8

Chyba będę musiał odpowiedzieć na własne pytanie, ponieważ wydaje się, że nie ma sposobu, aby poprosić o tożsamość według nazwy pliku.

Napisałem szybkie i brudne skrypty Pythona, które tworzą plik klucza publicznego .ssh/fingerprintsdla każdego klucza, który posiada agent. Następnie mogę określić ten plik, który nie zawiera tajnego klucza, IdentityFilea SSH wybierze odpowiednią tożsamość od agenta SSH. Działa idealnie dobrze i pozwala mi korzystać z agenta dla dowolnej liczby kluczy prywatnych, jakie chcę.

#!/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
źródło
Dobra robota, wypróbuję to wkrótce
Tobias Kienzler,
3

Biegać

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

na zdalnym komputerze, aby automatycznie wygenerować wszystkie pliki kluczy publicznych (zakładając, że klucze publiczne w twoim .ssh/configsą nazwane privateKeyFileName.pubi nie są zaangażowane niespójne ścieżki). Zadzwoń chown $USER .ssh/*po swoją sudoskrzynkę.

Tobias Kienzler
źródło
1

Pobieranie z zaakceptowanego rozwiązania i zakładanie, że chcesz ponownie użyć tożsamości użytej do uzyskania dostępu do początkowego serwera, a następnie coś w stylu:

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

jest wystarczający.

Cagney
źródło
to nie działa dla mnie. Gdy plik tożsamości ma tylko jeden klucz publiczny - działa, ale nie w przypadku wielu.
ygrek