web-dev-qa-db-ja.com

ファイル名でssh-agentからIDを選択します

問題:20〜30個のssh-agentIDがあります。 SSHでは通常20種類のキーを試してログインできないため、ほとんどのサーバーはToo many failed authenticationsによる認証を拒否します。

現時点では、IdentityFileおよびIdentitiesOnlyディレクティブを使用して、すべてのホストのIDファイルを手動で指定しているため、SSHは1つのキーファイルのみを試行します。

残念ながら、元のキーが使用できなくなるとすぐに機能しなくなります。 ssh-add -lは、すべてのキーファイルの正しいパスを表示し、それらは.ssh/configのパスと一致しますが、機能しません。どうやら、SSHはファイル名ではなく公開鍵署名によってIDを選択します。つまり、SSHが公開鍵を抽出できるように、元のファイルが使用可能である必要があります。

これには2つの問題があります。

  • キーを保持しているフラッシュドライブを抜くとすぐに動作を停止します
  • キーファイルがリモートホストで利用できないため、エージェント転送が役に立たなくなります。

もちろん、IDファイルから公開鍵を抽出して、自分のコンピューターと、通常ログインするすべてのリモートコンピューターに保存することもできます。ただし、これは望ましい解決策のようには見えません。

必要なのは、ファイル名でssh-agentからIDを選択できることです。これにより、リモートのホストI SSHでも、.ssh/configを使用するか、-i /path/to/original/keyを渡すことで適切なキーを簡単に選択できます。 dに。フルパスを指定する必要がないように、キーに「ニックネーム」を付けることができればさらに良いでしょう。

9
leoluk

ファイル名でIDを要求する方法がないように思われるので、自分の質問に答える必要があると思います。

エージェントが保持するすべてのキーについて、.ssh/fingerprintsに公開キーファイルを作成する、手っ取り早いPythonスクリプトを作成しました。次に、秘密キーを含まないこのファイルを指定できます。 、IdentityFileを使用すると、SSHはSSHエージェントから正しいIDを選択します。完全に正常に機能し、必要な数の秘密鍵にエージェントを使用できます。

#!/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()
8
leoluk

実行

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

リモートマシン上で、すべての公開鍵ファイルを自動的に生成します(.ssh/configの公開鍵の名前はprivateKeyFileName.pubであり、矛盾するパスが含まれていないと仮定します)。 Sudoの場合は、chown $USER .ssh/*に電話してください。

3
Tobias Kienzler

受け入れられたソリューションから取得し、最初のサーバーへのアクセスを取得するために使用されたIDを再利用したい場合は、次のようになります。

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

十分です。

1
cagney