通过文件名从ssh-agent选择身份


9

问题:我有20-30个ssh-agent身份。大多数服务器都拒绝使用进行身份验证Too many failed authentications,因为SSH通常不允许我尝试20种不同的密钥来登录。

目前,我正在使用IdentityFileIdentitiesOnly指令为每个主机手动指定身份文件,以便SSH仅尝试一个有效的密钥文件。

不幸的是,一旦不再有原始密钥,此操作就会停止。ssh-add -l向我显示了每个密钥文件的正确路径,并且它们与中的路径匹配.ssh/config,但是它不起作用。显然,SSH通过公钥签名而不是文件名来选择身份,这意味着原始文件必须可用,以便SSH可以提取公钥。

这有两个问题:

  • 我拔下持有钥匙的闪存驱动器时,它立即停止工作
  • 由于密钥文件在远程主机上不可用,它使代理转发无用

当然,我可以从身份文件中提取公钥,并将其存储在我的计算机以及通常登录的每台远程计算机上。但是,这似乎不是理想的解决方案。

我需要的是通过文件名从ssh-agent选择身份的可能性,这样,即使在我SSH输入的远程主机上,我也可以使用.ssh/config或通过轻松选择正确的密钥-i /path/to/original/key。如果我可以“昵称”这些键,甚至不必指定完整路径,那就更好了。


1
为什么需要许多ssh身份?如果要避免一个受损的私钥访问您的所有帐户,那么为什么要将所有帐户都保存在一个闪存驱动器上?这不是我第一次听到有关管理多个ssh身份的问题,但从未有机会问为什么需要它们。
德米特里·丘巴罗夫

从来没有说过它们都在一个闪存驱动器上。
leoluk 2012年

3
@DmitriChubarov一个可能用于多个ssh身份的应用程序是一个authorized_keys文件,该文件根据所使用的密钥执行不同的命令,而从未允许直接访问shell。
Tobias Kienzler 2012年

Answers:


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()


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

足够了。


这对我不起作用。当身份文件只有一个公钥时,它将起作用,但当多个公钥不起作用时。
ygrek
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.