【问题标题】:How to make ssh-add read passphrase from a file?如何使 ssh-add 从文件中读取密码?
【发布时间】:2022-03-18 23:48:06
【问题描述】:

我正在尝试向ssh-agent 添加一个密钥,并希望ssh-add 从我正在使用的密钥文件中读取密码。这怎么可能?

如何通过 shell 脚本自动执行此过程?

【问题讨论】:

标签: ssh ssh-agent


【解决方案1】:

根据您的发行版和 ssh-add 的版本,您可能能够或不使用 ssh-add 的 -p 选项以这种方式从标准输入读取密码:

cat passfile | ssh-add -p keyfile

如果这不起作用,您可以使用Expect,这是一个 Unix 工具,可以使交互式应用程序变为非交互式。你必须从你的包管理器安装它。

我已经为您编写了一个工具。只需将内容复制到一个名为 ssh-add-pass 的文件中并为其设置可执行权限 (chmod +x ssh-add-pass)。您也可以将其复制到 /usr/bin 或 /usr/local/bin 以便从 $PATH 搜索中访问。

#!/bin/bash

if [ $# -ne 2 ] ; then
  echo "Usage: ssh-add-pass keyfile passfile"
  exit 1
fi

eval $(ssh-agent)
pass=$(cat $2)

expect << EOF
  spawn ssh-add $1
  expect "Enter passphrase"
  send "$pass\r"
  expect eof
EOF

用法很简单:ssh-add-pass keyfile passfile

【讨论】:

  • ssh-add 中没有 -[Pp] 选项 - 错误 ssh-add: 非法选项 -- P
  • 它曾经存在于某些发行版中。您使用的是哪个发行版?我将给出答案,以便具有兼容发行版的人可能会发现它很有用。
  • 他们关闭了问题,但我仍然想提供帮助。试试我发布的新方式并告诉我!
  • 尝试将eval $(ssh-agent)更改为ssh-agent basheval `ssh-agent -s`
  • 我已经尝试过eval ssh-agent -s 并且它运行了所有命令,但是在该脚本返回原始 bash 之后它丢失了那个密钥。它都依赖于产生 bash 并使用相同的 bash 来运行 ssh-add
【解决方案2】:

类似于 kenorb 的答案,但不会将秘密保存在文件中:

$ SSH_ASKPASS=/path/to/ssh_give_pass.sh ssh-add $KEYFILE <<< "$KEYPASS"

ssh_give_pass.sh 在哪里:

#!/bin/bash
# Parameter $1 passed to the script is the prompt text
# READ Secret from STDIN and echo it
read SECRET
echo $SECRET

如果您在 $KEYPASSFILE 中有秘密,请先使用

将其读入变量
KEYPASS=`cat $KEYPASSFILE`

还要确保 ssh_give_pass.sh 不能被未经授权的用户编辑 - 很容易记录通过脚本传递的所有秘密。

【讨论】:

  • 非常好!我认为这可以进一步改进——因为提问者希望它作为脚本的一部分,你可以去:SSH_ASKPASS="$0",然后有
  • 这是迄今为止最优雅的 - 无需在任何地方保存密码。微小的缩短,替换 read SECRET ; echo $SECRET with cat 另外,由于这是在脚本中使用,脚本本身可以使用 SSH_ASKPASS=$0 作为 askpass,然后检查 $1 以查看是否被正常调用或作为 askpass
  • 如果 DISPLAY 未设置,ssh-add 将不遵守 SSH_ASKPASS 变量。因此,如果上述解决方案不起作用,请先检查这个。
  • @petkov.np DISPLAY=:0 SSH_ASKPASS=/path/to/ssh_give_pass.sh ssh-add $KEYFILE &lt;&lt;&lt; "$KEYPASS"
  • @petkov.np 如果我们使用 bash,它会是 ${DISPLAY:=0}
【解决方案3】:

以下是不支持-p的系统的一些解决方法:

$ PASS="my_passphrase"
$ install -vm700 <(echo "echo $PASS") "$PWD/ps.sh"
$ cat id_rsa | SSH_ASKPASS="$PWD/ps.sh" ssh-add - && rm -v "$PWD/ps.sh"

ps.sh 基本上是您打印密码的脚本。见:man ssh-add

为了使其更安全(不要将其保存在同一个文件中),请使用mktemp 生成一个随机私有文件,使其可执行 (chmod) 并确保它在执行后将密码短语打印到标准输出.

【讨论】:

  • 在这种特殊情况下伪造交互式输入的非常有创意的方法,ssh-add 允许您像这样在每次调用时换出SSH_ASKPASS 二进制文件。
  • 正确,但是ps.sh 是一种安全风险,并且 rm 是一种非常弱的隐藏方式,您至少应该使用shred -u,但即使是 shred 在现代 fs 上也效率低下,例如ext4 以及更多关于 btrfs 的内容。因此,在共享内存/dev/shm/run/user/&lt;uid&gt; 中创建您的文件,并在使用后将其切碎。另一种选择是将ps.sh 放在加密文件系统上。
  • 这个解决方案对我很有用,但前提是我将 DISPLAY=:0 设置为 ssh-add 的手册页建议(Ubuntu 16.04)
  • 在我的 Bionic 上,我必须按照手册页的建议从 /dev/null 重定向 ssh-add 的标准输入。
【解决方案4】:

在我的 Ubuntu 系统上,没有一个答案有效:

  • ssh-add 不支持 -p 选项。
  • ssh-add 忽略了 SSH_ASKPASS,坚持在控制终端上提示输入密码。
  • 我想避免安装额外的包,尤其是expect

对我来说有效的是:

password_source | SSH_ASKPASS=/bin/cat setsid -w ssh-add keyfile

password_source 并不是一个真正的程序:它只是代表将密码短语提供给ssh-add 的任何内容。就我而言,它是一个执行setsid 并将密码短语写入其标准输入的程序。如果您将密码保存在文件中,您有责任进行简单的修改:我不会让您伤害自己。

setsid 已安装,并分离控制终端,以便ssh-add 不会尝试使用它来提示输入密码。 -w 导致 setsid 等待 ssh-add 退出并使其返回代码可用。 /bin/cat 与 Ray Shannon 提供的脚本具有相同的效果,但使用标准工具而不是通过脚本复制其功能。

【讨论】:

  • 在相对干净的 Debian 上完美运行;在我的具体情况下,它是:来源 | setsid -w ssh-keygen -p -f 密钥文件
【解决方案5】:

有了这个最小的更改,@enrico.basis 的这个 bash 脚本对我有用

#!/bin/bash

if [ $# -ne 2 ] ; then
  echo "Usage: ssh-add-pass passfile keyfile"
  exit 1
fi

eval 'ssh-agent -s'
passwordToFileSSH=$1
pathFileSSH=$2

expect << EOF
  spawn ssh-add $pathFileSSH
  expect "Enter passphrase"
  send "$passwordToFileSSH\r"
  expect eof
EOF

【讨论】:

    猜你喜欢
    • 2017-01-13
    • 2018-02-20
    • 1970-01-01
    • 1970-01-01
    • 2016-09-28
    • 1970-01-01
    • 2016-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多