AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / server / 问题 / 401737
Accepted
leoluk
leoluk
Asked: 2012-06-25 02:06:55 +0800 CST2012-06-25 02:06:55 +0800 CST 2012-06-25 02:06:55 +0800 CST

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

  • 772

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

目前,我正在使用IdentityFile和IdentitiesOnly指令手动为每台主机指定身份文件,这样 SSH 将只尝试一个密钥文件,这是可行的。

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

这有两个问题:

  • 一旦我拔下拿着钥匙的闪存驱动器,它就会停止工作
  • 它使代理转发无用,因为密钥文件在远程主机上不可用

当然,我可以从我的身份文件中提取公钥并将它们存储在我的计算机上,以及我经常登录的每台远程计算机上。不过,这看起来不像是理想的解决方案。

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

ssh ssh-agent ssh-keys
  • 4 4 个回答
  • 4838 Views

4 个回答

  • Voted
  1. Best Answer
    leoluk
    2012-06-25T05:19:21+08:002012-06-25T05:19:21+08:00

    猜猜我必须回答我自己的问题,因为似乎没有任何方法可以通过文件名请求身份。

    .ssh/fingerprints我写了一个快速而简单的 Python 脚本,它为代理持有的每个密钥创建一个公钥文件。然后我可以使用 SSH 指定这个不包含密钥的文件,IdentityFileSSH 将从 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()
    
    • 9
  2. Tobias Kienzler
    2012-10-20T02:18:40+08:002012-10-20T02:18:40+08:00

    跑

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

    在远程机器上自动生成所有公钥文件(假设您的公钥.ssh/config已命名privateKeyFileName.pub并且不涉及不一致的路径)。打电话chown $USER .ssh/*给你的sudo情况。

    • 4
  3. cagney
    2017-01-10T08:28:00+08:002017-01-10T08:28:00+08:00

    从接受的解决方案中挑选,并假设您只想重用用于访问初始服务器的身份,然后是这样的:

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

    足够了。

    • 2
  4. Terrance Kennedy
    2022-01-05T19:17:00+08:002022-01-05T19:17:00+08:00

    一种选择是为 SSH 创建一个小的包装脚本,它可以从 SSH 代理转发正确的公钥。这是一个有效的概念验证:

    #!/usr/bin/env bash
    
    # SSH with specific identity that has been previously added to the ssh-agent.
    # Public key file need not exist.
    # Usage: First argument is the ssh key fingerprint of the identity you want to
    #     use. All further arguments will be forwarded to ssh directly.
    #     
    # Ex: ssh-with-key SHA256:VrzNKaV7VcU7jT7hLZJMxxAo6whPc+VVXKaH0exqXiM user@host
    
    set -euo pipefail
    
    fingerprint="$1"
    shift
    
    # List ssh-agent fingerprints and public keys, get public key that corresponds
    # to the line number of the fingerprint.
    pub_key="$(awk 'line == null && "'"$fingerprint"'" {line=FNR; nextfile}; line == FNR' <(ssh-add -l) <(ssh-add -L))"
    
    # Save public key to temporary file.
    # NB: Can't use process substitution here. Bash passes substituted argument as
    # a /dev/fd file, and ssh closes all /dev/fd files other than stdin, stdout,
    # and stderr before processing CLI options.
    pub_key_file=$(mktemp)
    echo $pub_key > $pub_key_file
    
    cleanup() {
        rm -f $pub_key_file
    }
    trap cleanup EXIT
    
    ssh -o IdentitiesOnly=yes -i $pub_key_file "$@"
    

    您可以创建一个单独的配置文件,将 SSH 密钥指纹与一个或多个主机名或昵称相关联,以便于使用。

    这种技术的优势在于,除了将公钥添加到 SSH 代理之外,您无需预先或定期处理公钥。公钥文件根据需要写入,并在会话结束后立即删除。

    • 0

相关问题

  • 如何最好地设置 ssh 隧道以访问远程网络 (Linux)

  • SSH 和重定向

  • 通过 SSH 会话使用 NET USER 命令拒绝访问

  • SSH 服务器零日漏洞利用 - 保护自己的建议

  • ubuntu apt-get upgrade - 如何在 shell 中单击确定?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    新安装后 postgres 的默认超级用户用户名/密码是什么?

    • 5 个回答
  • Marko Smith

    SFTP 使用什么端口?

    • 6 个回答
  • Marko Smith

    命令行列出 Windows Active Directory 组中的用户?

    • 9 个回答
  • Marko Smith

    什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同?

    • 3 个回答
  • Marko Smith

    如何确定bash变量是否为空?

    • 15 个回答
  • Martin Hope
    Tom Feiner 如何按大小对 du -h 输出进行排序 2009-02-26 05:42:42 +0800 CST
  • Martin Hope
    Noah Goodrich 什么是 Pem 文件,它与其他 OpenSSL 生成的密钥文件格式有何不同? 2009-05-19 18:24:42 +0800 CST
  • Martin Hope
    Brent 如何确定bash变量是否为空? 2009-05-13 09:54:48 +0800 CST
  • Martin Hope
    cletus 您如何找到在 Windows 中打开文件的进程? 2009-05-01 16:47:16 +0800 CST

热门标签

linux nginx windows networking ubuntu domain-name-system amazon-web-services active-directory apache-2.4 ssh

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve