Wählen Sie die Identität von ssh-agent anhand des Dateinamens

9

Problem: Ich habe 20-30 ssh-agentIdentitäten. Die meisten Server verweigern die Authentifizierung mit Too many failed authentications, da ich bei SSH normalerweise nicht versuchen kann, mich mit 20 verschiedenen Schlüsseln anzumelden.

Im Moment spezifiziere ich die Identitätsdatei für jeden Host manuell unter Verwendung der IdentityFileund der IdentitiesOnlyDirektive, so dass SSH nur eine Schlüsseldatei ausprobiert, was funktioniert.

Leider funktioniert dies nicht mehr, sobald die Originalschlüssel nicht mehr verfügbar sind. ssh-add -lzeigt mir die richtigen Pfade für jede Schlüsseldatei und sie stimmen mit den Pfaden in überein .ssh/config, aber es funktioniert nicht. Anscheinend wählt SSH den Einzug nach der Signatur des öffentlichen Schlüssels und nicht nach dem Dateinamen aus, was bedeutet, dass die Originaldateien verfügbar sein müssen, damit SSH den öffentlichen Schlüssel extrahieren kann.

Hierbei gibt es zwei Probleme:

  • Es funktioniert nicht mehr, sobald ich das Flash-Laufwerk mit den Tasten ausstecke
  • Dadurch wird die Agentenweiterleitung unbrauchbar, da die Schlüsseldateien auf dem Remote-Host nicht verfügbar sind

Natürlich könnte ich die öffentlichen Schlüssel aus meinen Identitätsdateien extrahieren und auf meinem Computer und auf jedem Remotecomputer speichern, bei dem ich mich normalerweise anmelde. Dies scheint jedoch keine wünschenswerte Lösung zu sein.

Was ich brauche, ist die Möglichkeit, eine Identität von ssh-agent anhand des Dateinamens auszuwählen, damit ich den richtigen Schlüssel einfach mit .ssh/configoder durch Übergabe auswählen kann -i /path/to/original/key, selbst auf einem Remote-Host, auf den ich SSH-fähig bin. Es wäre sogar noch besser, wenn ich die Schlüssel "mit einem Spitznamen" versehen könnte, damit ich nicht einmal den vollständigen Pfad angeben muss.

Leoluk
quelle
1
Warum brauchen Sie viele SSH-Identitäten? Wenn Sie vermeiden möchten, dass ein kompromittierter privater Schlüssel Zugriff auf alle Ihre Konten gewährt, warum speichern Sie dann alle auf einem einzigen Flash-Laufwerk? Es ist nicht das erste Mal, dass ich von Problemen im Zusammenhang mit der Verwaltung mehrerer SSH-Identitäten höre, aber ich hatte nie die Gelegenheit zu fragen, warum sie benötigt werden.
Dmitri Chubarov
Ich habe nie gesagt, dass sich alle auf einem Flash-Laufwerk befinden.
Leoluk
3
@DmitriChubarov Eine mögliche Anwendung für mehrere SSH-Identitäten ist eine authorized_keysDatei, die je nach verwendetem Schlüssel unterschiedliche Befehle ausführt, ohne jemals einen direkten Shell-Zugriff zuzulassen.
Tobias Kienzler

Antworten:

8

Ich denke, ich muss meine eigene Frage beantworten, da es anscheinend keine Möglichkeit gibt, eine Identität anhand des Dateinamens anzufordern.

Ich habe ein schnelles und schmutziges Python-Skript geschrieben, das .ssh/fingerprintsfür jeden Schlüssel, den der Agent enthält, eine öffentliche Schlüsseldatei erstellt . Ich kann dann diese Datei, die keinen geheimen Schlüssel enthält, mit angeben IdentityFileund SSH wählt die richtige Identität vom SSH-Agenten aus. Funktioniert einwandfrei und ermöglicht es mir, den Agenten für so viele private Schlüssel zu verwenden, wie ich möchte.

#!/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
quelle
Gute Arbeit, ich werde es bald versuchen
Tobias Kienzler
3

Lauf

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

auf dem Remotecomputer, um automatisch alle öffentlichen Schlüsseldateien zu generieren (vorausgesetzt, die öffentlichen Schlüssel in Ihrem .ssh/configsind benannt privateKeyFileName.pubund es sind keine inkonsistenten Pfade beteiligt). Rufen Sie chown $USER .ssh/*für Ihren sudoFall.

Tobias Kienzler
quelle
1

Nehmen Sie die akzeptierte Lösung auf und nehmen Sie an, dass Sie nur die Identität wiederverwenden möchten, die für den Zugriff auf den ursprünglichen Server verwendet wurde.

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

ist ausreichend.

cagney
quelle
das funktioniert bei mir nicht Wenn die Identitätsdatei nur einen öffentlichen Schlüssel hat, funktioniert dies, jedoch nicht, wenn mehrere vorhanden sind.
Ygrek