如何从文件中生成ssh-add读密码?

Sat*_*ish 21 ssh ssh-agent

我正在尝试添加密钥ssh-agent并希望ssh-add从文件中读取密码.怎么可能?

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

enr*_*cis 30

根据您的发行版和ssh-add版本,您可以使用-pssh-add选项以这种方式从stdin读取密码:

cat passfile | ssh-add -p keyfile
Run Code Online (Sandbox Code Playgroud)

如果这不起作用,您可以使用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
Run Code Online (Sandbox Code Playgroud)

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

  • ssh-add中没有-[Pp]选项-ssh-add错误:非法选项-P (2认同)
  • 我正在起诉CentOS 5 (2认同)

小智 13

在我的 Ubuntu 系统上,所有答案都不起作用:

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

对我来说有效的是:

password_source | SSH_ASKPASS=/bin/cat setsid -w ssh-add keyfile
Run Code Online (Sandbox Code Playgroud)

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

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


ken*_*orb 9

以下是不支持的系统的一些解决方法-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"
Run Code Online (Sandbox Code Playgroud)

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

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

  • 正确,但是 `ps.sh` 是一个安全风险,而 rm 是一种相当弱的隐藏方式,你至少应该执行 `shred -u`,但即使是 shred 在现代文件系统(如 ext4 等)上效率也很低。有关 btrfs 的更多信息。因此,在共享内存“/dev/shm”或“/run/user/&lt;uid&gt;”中创建文件,并在使用后将其粉碎。另一种选择是将“ps.sh”放在加密的文件系统上。 (3认同)

Ray*_*non 5

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

$ SSH_ASKPASS=/path/to/ssh_give_pass.sh ssh-add $KEYFILE <<< "$KEYPASS"
Run Code Online (Sandbox Code Playgroud)

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
Run Code Online (Sandbox Code Playgroud)

如果您在$ KEYPASSFILE中拥有秘密,请首先使用以下命令将其读入变量

KEYPASS=`cat $KEYPASSFILE`
Run Code Online (Sandbox Code Playgroud)

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

  • 这是迄今为止最优雅的 - 无需在任何地方保存密码。微小的缩短,替换 read SECRET ;echo $SECRET with cat 另外,因为这是在脚本中使用的,所以脚本本身可以使用 SSH_ASKPASS=$0 作为 askpass 的两倍,然后检查 $1 以查看是否被正常调用或作为 askpass (2认同)
  • 如果未设置 DISPLAY,ssh-add 将不会考虑 SSH_ASKPASS 变量。因此,如果上述解决方案不起作用,请先检查此解决方案。 (2认同)
  • @petkov.np `DISPLAY=:0 SSH_ASKPASS=/path/to/ssh_give_pass.sh ssh-add $KEYFILE &lt;&lt;&lt; "$KEYPASS"` (2认同)