Pilih identitas dari ssh-agent berdasarkan nama file

9

Masalah: Saya memiliki sekitar 20-30 ssh-agentidentitas. Sebagian besar server menolak otentikasi Too many failed authentications, karena SSH biasanya tidak mengizinkan saya mencoba 20 kunci berbeda untuk masuk.

Saat ini, saya menetapkan file identitas untuk setiap host secara manual, menggunakan IdentityFiledan IdentitiesOnlydirektif, sehingga SSH hanya akan mencoba satu file kunci, yang berfungsi.

Sayangnya, ini berhenti berfungsi segera setelah kunci asli tidak tersedia lagi. ssh-add -lmemperlihatkan saya jalur yang benar untuk setiap file kunci, dan mereka cocok dengan jalur di .ssh/config, tetapi tidak berhasil. Rupanya, SSH memilih indentitas dengan tanda tangan kunci publik dan bukan dengan nama file, yang berarti bahwa file asli harus tersedia sehingga SSH dapat mengekstrak kunci publik.

Ada dua masalah dengan ini:

  • itu berhenti bekerja segera setelah saya mencabut flash drive memegang kunci
  • itu membuat agen meneruskan tidak berguna karena file kunci tidak tersedia pada host jarak jauh

Tentu saja, saya bisa mengekstrak kunci publik dari file identitas saya dan menyimpannya di komputer saya, dan di setiap komputer jarak jauh yang biasa saya masuki. Ini tidak terlihat seperti solusi yang diinginkan.

Yang saya butuhkan adalah kemungkinan untuk memilih identitas dari ssh-agent berdasarkan nama file, sehingga saya dapat dengan mudah memilih kunci yang tepat menggunakan .ssh/configatau dengan melewati -i /path/to/original/key, bahkan pada host jarak jauh yang saya masuki SSH. Akan lebih baik lagi jika saya bisa "memberi julukan" kunci sehingga saya bahkan tidak perlu menentukan path lengkap.

leoluk
sumber
1
Mengapa Anda memerlukan banyak identitas ssh? Jika itu untuk menghindari satu kunci pribadi yang dikompromikan memberikan akses ke semua akun Anda, lalu mengapa Anda menyimpan semuanya pada satu flash drive? Ini bukan pertama kalinya saya mendengar masalah yang berkaitan dengan mengelola beberapa identitas ssh tetapi tidak pernah memiliki kesempatan untuk bertanya mengapa mereka diperlukan.
Dmitri Chubarov
Tidak pernah dikatakan semuanya ada dalam satu flash drive.
leoluk
3
@DmitriChubarov Salah satu aplikasi yang mungkin untuk beberapa identitas ssh adalah authorized_keysfile yang, tergantung pada kunci yang digunakan, menjalankan perintah yang berbeda, tanpa pernah mengizinkan akses shell langsung.
Tobias Kienzler

Jawaban:

8

Kira saya harus menjawab pertanyaan saya sendiri, karena sepertinya tidak ada cara untuk meminta identitas dengan nama file.

Saya menulis skrip Python cepat dan kotor yang membuat file kunci publik .ssh/fingerprintsuntuk setiap kunci yang dimiliki agen. Saya kemudian dapat menentukan file ini, yang tidak mengandung kunci rahasia, menggunakan IdentityFiledan SSH akan memilih identitas yang tepat dari agen SSH. Bekerja dengan sangat baik, dan memungkinkan saya menggunakan agen untuk sebanyak kunci pribadi yang saya inginkan.

#!/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
sumber
Kerja
3

Lari

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

pada mesin jarak jauh untuk secara otomatis menghasilkan semua file kunci publik (dengan asumsi kunci publik di Anda .ssh/configdinamai privateKeyFileName.pubdan tidak ada jalur tidak konsisten yang terlibat). Panggil kasus chown $USER .ssh/*Anda sudo.

Tobias Kienzler
sumber
1

Mengambil dari solusi yang diterima, dan dengan asumsi Anda hanya ingin menggunakan kembali identitas yang digunakan untuk mendapatkan akses ke server awal, maka sesuatu seperti:

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

sudah cukup.

cagney
sumber
ini tidak bekerja untuk saya. Ketika file identitas hanya memiliki satu kunci publik - itu berfungsi, tetapi tidak ketika banyak.
ygrek