如何使ssh从文件中添加读取密码短语?

如何使ssh从文件中添加读取密码短语?,ssh,ssh-agent,Ssh,Ssh Agent,我正在尝试将密钥添加到ssh-agent,并希望ssh-add从我正在使用的密钥文件中读取密码。这怎么可能 如何从shell脚本自动化此过程?根据您的发行版和ssh add的版本,您可以使用ssh add的-p选项,该选项以以下方式从stdin读取密码: cat passfile | ssh-add -p keyfile 如果这不起作用,您可以使用Unix工具使交互式应用程序非交互式。您必须从软件包管理器安装它 我在expect中为您编写了一个工具。只需将内容复制到名为ssh add pass

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


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

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

cat passfile | ssh-add -p keyfile
如果这不起作用,您可以使用Unix工具使交互式应用程序非交互式。您必须从软件包管理器安装它

我在expect中为您编写了一个工具。只需将内容复制到名为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
#/bin/bash
如果[$#-ne 2];然后
echo“用法:ssh添加passkeyfile passfile”
出口1
fi
eval$(ssh代理)
通过=$(类别$2)

expect对于不支持
-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"
$PASS=“我的密码”

$install-vm700与kenorb的答案类似,但不会将秘密保存在文件中:

$ SSH_ASKPASS=/path/to/ssh_give_pass.sh ssh-add $KEYFILE <<< "$KEYPASS"
如果在$KEYPASSFILE中有密码,请首先使用

KEYPASS=`cat $KEYPASSFILE`

还要确保ssh\u give\u pass.sh不可被未经授权的用户编辑-可以很容易地记录通过脚本传递的所有机密。

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

  • ssh add
    不支持
    -p
    选项
  • ssh add
    忽略ssh\u ASKPASS,坚持在控制终端上提示输入密码短语
  • 我想避免安装额外的软件包,尤其是
    expect
在我的案例中起作用的是:

password_source | SSH_ASKPASS=/bin/cat setsid -w ssh-add keyfile
密码源不是一个真正的程序:它只是表示将密码短语提供给
ssh add
的内容。在我的例子中,它是一个执行
setsid
并将密码短语写入其stdin的程序。如果你把你的密码短语保存在一个文件中,你就有责任进行简单的修改:我不会让你伤害自己


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

ssh add中没有-[Pp]选项-错误ssh add:非法选项-在某些发行版中使用PIt。您使用的是哪个发行版?我将给出答案,这样具有兼容发行版的用户可能会发现它很有用。他们结束了这个问题,但我仍然想提供帮助。试试我发布的新方式,让我知道!我还有一个问题与上面的脚本有关,如何在脚本中添加“ssh-agent-bash”命令。问题是它生成了一个新的shell,但失败了。请尝试更改
eval$(ssh代理)
使用
ssh-agent bash
或使用
eval`ssh-agent-s`
为什么不在同一位置以与存储密码相同的权限存储密钥副本?请参阅这一特殊情况下非常有创意的伪造交互输入的方法,
ssh-add
允许您交换掉
SSH\u ASKPASS
二进制的每次调用。正确,但是
ps.sh
是一种安全风险,rm是一种非常弱的隐藏方式,您至少应该执行
shred-u
,但即使是在ext4这样的现代fs和btrfs上,shred也是低效的。因此,在共享内存
/dev/shm
/run/user/
中创建您的文件,并在使用后将其撕碎。另一个选择是将
ps.sh
放在加密的文件系统上。这个解决方案对我来说非常有效,但只有当我在我的Bionic上设置了ssh add手册页(Ubuntu 16.04)所建议的
DISPLAY=:0
时,我才不得不按照手册页的建议从/dev/null重定向ssh add的stdin。非常好!我认为这可能会得到更大的改进-因为提问者希望将此作为脚本的一部分,您可以这样做:SSH_ASKPASS=“$0”,然后让这是迄今为止最优雅的-无需在任何地方保存密码。微小的缩短,代替阅读的秘密;同样,使用cat回显$SECRET,因为这是在脚本中使用的,所以脚本本身可以使用SSH_askpass=$0作为askpass加倍,然后检查$1以查看是正常调用还是未设置askpassif DISPLAY,SSH add将不考虑SSH_askpass变量。因此,如果上述解决方案不起作用,请首先检查此解决方案。@petkov.np
DISPLAY=:0ssh\u ASKPASS=/path/to/SSH\u give\u pass.sh SSH add$KEYFILE@petkov.np如果我们使用bash,它将是
${DISPLAY:=0}
password_source | SSH_ASKPASS=/bin/cat setsid -w ssh-add keyfile