如何将存储在 shell 环境变量中的密钥传递给 ssh?

如何将存储在 shell 环境变量中的密钥传递给 ssh?

大概尝试多次ssh访问,但在第一次读取后就被销毁了:fdfd

# ssh -i <(echo $KEY) [email protected]
Warning: Identity file /dev/fd/11 not accessible: Bad file descriptor.
[email protected]: Permission denied (publickey).

有没有其他方法而不写入/删除临时文件?

答案1

export MYKEY=`cat key.pem`
ssh-add - <<< "$MYKEY"
ssh [email protected]

答案2

太长了;博士不,但是请看XY 问题

$ strace -f ssh -i <(cat ~/.ssh/id_rsa) user@server echo test
...
close(63)
...
newfstatat(AT_FDCWD, "/dev/fd/63", 0x7ffc4f1d0c60, 0) = -1 ENOENT (No such file or directory)
write(2, "Warning: Identity file /dev/fd/6"..., 77Warning: Identity file /dev/fd/63 not accessible: No such file or directory.) = 77

因此由于某种原因一开始ssh就关闭了fd。也许它会关闭除标准描述符之外的所有描述符。

无论如何,你的假设都是错误的:

大概 ssh 尝试多次访问 fd,但 fd 在第一次读取后就被销毁了

在尝试处理 fd 之前只有一个系统调用statclose(63)。是的,在那之后它就被摧毁了。

答案3

这是一个解决方案,它使用ssh-agent,不需要它运行。

ssh-agent bash -c "ssh-add <(echo '$MY_SSH_KEY') && ssh ..."

因此,代理不会被“守护进程”,而只会在您的 SSH 会话处于活动状态时才存在。

答案4

作为替代方案,如果将密钥写入暂时的kill -9您可以接受保证被清理的安全文件(无 a )。我使用这个 Bash 辅助函数来包装ssh, scp, 并sftp允许我将密钥作为第一个参数传递:

with-ssh-key() (
    # Bash wrapper for OpenSSH CLI tools (ssh, scp, sftp, or any that accept
    # the `-i /path/to/keyfile` option) that allows for passing an SSH private
    # key as the first parameter rather than via a persistent identity file.
    # This is something that is not possible with ssh tools by default.
    #
    # This command is useful when storing the key in an environment variable
    # that is set in some secure way, such as set via secrets mastered in the
    # AWS Parameter Store, or as the result another command in a subshell.
    #
    # The "OPENSSH PRIVATE KEY" lines at the beginning and end of the passed
    # key string will be added if they are not on already present.
    #
    # Usage: with-ssh-key {ssh | scp | sftp} KEY ADDITIONAL_ARGS...
    #
    # Examples:
    #   key="b3blbnnzaC1rZXktdjEAAAAABG5vbmUAAAA[etc...]"
    #   with-ssh-key "$key" ssh myserver echo Hello-from-myserver
    #   with-ssh-key "$key" scp myserver:file.txt ./
    #   echo get file.txt | with-ssh-key "$key" sftp myserver
    #
    # A note regarding zsh: this wrapper is not necessary in zsh because zsh
    # has the extremely convenient `=(cmd)` syntax which will create a real
    # on-disk tempfile and clean it up immediately after the calling command
    # exits. Thus you can easily do something like this in zsh to accomplish
    # the same effect as this wrapper:
    #
    #   ssh -i =(echo "$key") ...
    #
    # Or, if you need to add the header/footer lines:
    # 
    #   ssh -i =(echo "-----BEGIN OPENSSH PRIVATE KEY-----\n$(echo "$key")\n-----END OPENSSH PRIVATE KEY-----")
    set -euo pipefail
    key="$1"; shift
    cmd="$1"; shift
    tempkeyfile=$(mktemp)
    chmod 600 "$tempkeyfile" # ensure file is locked down
    trap "rm \"$tempkeyfile\"" 0 2 3 15 # ensure tempfile cleanup in event of various signals
    [[ $key =~ "BEGIN OPENSSH PRIVATE KEY" ]] || echo "-----BEGIN OPENSSH PRIVATE KEY-----" >> $tempkeyfile
    echo "$key" >> $tempkeyfile
    [[ $key =~ "END OPENSSH PRIVATE KEY" ]] || echo "-----END OPENSSH PRIVATE KEY-----" >> $tempkeyfile
    $cmd -i "$tempkeyfile" "$@"
)

相关内容