如何在没有提示的情况下执行 ssh-keygen

Posted

技术标签:

【中文标题】如何在没有提示的情况下执行 ssh-keygen【英文标题】:How to execute ssh-keygen without prompt 【发布时间】:2017-08-31 07:17:01 【问题描述】:

我想在 Centos7 上使用 shell 脚本自动生成一对 ssh 密钥,我已经尝试过

yes "y" | ssh-keygen -t rsa
echo "\n\n\n" | ssh-keygen...
echo | ssh-keygen..

所有这些命令都不起作用,只需输入一个“输入”,shell 脚本就会在“输入密码(无密码时为空)”处停止, 我只是想知道如何在shell中连续模拟多个'enter'。

如果有人能提供帮助,非常感谢!

【问题讨论】:

【参考方案1】:

没有一个答案完全符合预期。想要的行为:使用默认设置运行 ssh-keygen(就像我们只是向 Enter 发送垃圾邮件)而不提示输入。

要运行的命令是:

yes '' | ssh-keygen -N '' > /dev/null

如果要打印输出,请忽略 >/dev/null。

解释:yes y spams 'y',ssh-keygen 会按照字面意思生成 $PWD/y 和 $PWD/y.pub 中的密钥。 yes '' 发送空行(回车),这是我们想要的。如果 .ssh 目录不存在,则使用 -f ~/.ssh/id_rsa 指定文件会失败。如果 rsa 是默认类型,则不需要 -t rsa 选项(无论如何我们都会发送垃圾邮件)。密码不是从标准输入(我们正在输入垃圾邮件)中读取的,而是直接从键盘读取的,因此没有任何东西可以拦截它。因此,您需要为空密码指定 -N ''。

【讨论】:

【参考方案2】:

我们需要自动完成两个步骤

    输入密码。使用-N 标志(此示例为空字符串):

    ssh-keygen -t rsa -N ''

    覆盖密钥文件

使用-f 输入路径(在本例中为id_rsa)加上一个here-string 来回答yes以下问题:

ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa <<<y >/dev/null 2>&1

或者,在类似 bash 的 shell 下,如果您肯定要覆盖前一个,只需使用 here-string输入命令 有所有需要的输入

ssh-keygen -q -t rsa -N '' <<< $'\ny' >/dev/null 2>&1

来自ssh-keygenman 页面:

  -N new_passphrase provides the new passphrase.
  -q                silence ssh-keygen.
  -f filename       specifies the filename of the key file.

分步说明

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/klashxx/.ssh/id_rsa):

1) 为避免输入密钥,请使用-f

$ ssh-keygen -t rsa -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
/home/klashxx/.ssh/id_rsa already exists.
Overwrite (y/n)?

注意:如果您不关心 RSA 文件名并且肯定想覆盖之前的文件名,请查看以下第四点的说明。

2) 现在我们需要对覆盖问题自动回答“y”(让我们使用here-string 来完成该工作) :

$ ssh-keygen -t rsa -f ~/.ssh/id_rsa <<< y
Generating public/private rsa key pair.
/home/klashxx/.ssh/id_rsa already exists.
Overwrite (y/n)? Enter passphrase (empty for no passphrase):

3) 最后,我们将使用-N 标志来输入无效通行证:

$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa <<< y
Generating public/private rsa key pair.
/home/klashxx/.ssh/id_rsa already exists.
Overwrite (y/n)? Your identification has been saved in /home/klashxx/.ssh/id_rsa.
Your public key has been saved in /home/klashxx/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:Xo0t6caMB/8TSsigxfY28JIfqYjyqxRZrFrPncx5yiU klashxx@server
The key's randomart image is:
+---[RSA 2048]----+
|                 |
|  .              |
|   o .           |
|  +   *    =     |
| +.  + BSo= o    |
|...o.+o+XO...    |
|.. .o.E==+B. .   |
|o . ...=.o...    |
|.+o.  o     ..   |
+----[SHA256]-----+

4) 多余的球,清理输出,只检查返回码:

$ ssh-keygen -q -t rsa -N '' -f ~/.ssh/id_rsa <<<y >/dev/null 2>&1
$ echo $?
0

覆盖先前 RSA 文件的替代路径(不需要 -f 标志)

注意:只有bash 像shell。

如果您不关心 RSA 名称而只想覆盖它,我们需要自动回答这两个问题:

    输入要保存密钥的文件:/example/path/.ssh/id_rsa 已存在。

    覆盖(y/n)?

如果我们手动执行此操作,对于第一个问题,我们只需按 enter,对于第二个问题,输入 y 并按 enter

我们可以使用下面的here-string来模拟这些动作:

$'\ny'

来自bash 手册页:

$'string' 形式的单词被特殊处理。该词扩展为 “字符串”,用反斜杠转义字符替换为指定的 ANSI C 标准。

\n 换行

所以,如果我们使用od 来分析我们的字符串:

cat - <<< $'\ny' | od -c
0000000  \n   y  \n

我们看到我们得到了回答问题所需要的东西。

第 1 点和第 2 点可以概括为

ssh-keygen -q -t rsa  <<< $'\ny'

最终命令将是:

$ ssh-keygen -q -t rsa -N '' <<< $'\ny' >/dev/null 2>&1
$ echo $?
0

荣誉

@lukasz-dynowski、@redochka、@mellow-yellow、@yeti 以及本主题中的其他人。

【讨论】:

我知道这种方式,但我只是想用'ssh-keygen -t rsa'来实现。 那么没有-N标志有什么解决办法吗? 只想在此处添加,如果要覆盖 id_rsa,则需要将 -f 标志附加到此答案。对我来说,这是创建一个 y 和 y.pub rsa 密钥文件对。这段代码修复了它:yes y | ssh-keygen -q -t rsa -n '' -f ~/.ssh/id_rsa &gt;/dev/null 可能类似于echo y|ssh-keygen -q -t rsa -N '' &gt; NUL 很好的答案,尽管正确的重定向顺序是:&gt;/dev/null 2&gt;&amp;1 2&gt;&amp;1 &gt;/dev/null 导致 stdout 到 /dev/null 和 steder 到 stdout,这不是预期的【参考方案3】:

接受的答案仍然指定自定义文件名。这对我有用:

ssh-keygen -t rsa -b 4096 -N '' <<<$'\n'
-t rsa 指定要创建的密钥类型 (RSA)。 -b 4096 指定要创建的密钥的位数(4096 位)。 -N '' 提供密码(在本例中为空)。 &lt;&lt;&lt; shell 的一部分:"here string" 将一个字符串输入到 ssh-keygen 的标准输入中。 $'\n' 换行符(使用 $ 使单引号字符串解释特殊字符)。

上面给出的命令会创建一个 4096 位的 RSA 密钥,其密码为空。它要求:Enter file in which to save the key (.../.ssh/id_rsa):,因此将换行符 (\n) 输入标准输入,以自动接受默认文件名。如果一个键已经存在,它不会做任何事情。

但是,如果您确实希望在没有任何提示的情况下自动覆盖现有密钥,请使用 (这是对原始问题的真正答案,但它位于此处以防止意外覆盖对于不阅读就复制粘贴的人):

ssh-keygen -t rsa -b 4096 -N '' <<<$'\ny\n'

silence ssh-keygen stdout,添加-q(安静)选项或&gt;/dev/null

ssh-keygen -t rsa -b 4096 -N '' <<<$'\n' >/dev/null

【讨论】:

完美!这就像一个魅力【参考方案4】:

删除当前私钥以防止覆盖请求。

rm -f ~/.ssh/id_rsa && ssh-keygen -m PEM -t rsa -b 4096 -N '' -f ~/.ssh/id_rsa

【讨论】:

【参考方案5】:

在我的 Dockerfile(来自 node:8.13.0)中,以下内容运行良好:yes 'y' | /usr/bin/ssh-keygen

更完整的例子:

yes 'y' | /usr/bin/ssh-keygen -q -N '' -t rsa -f /etc/ssh/ssh_host_rsa_key && \
yes 'y' | /usr/bin/ssh-keygen -q -N '' -t dsa -f /etc/ssh/ssh_host_dsa_key

【讨论】:

【参考方案6】:

对我来说,在 ssh 命令中使用时,我必须同时使用@Lukasz 答案和@Juan 的组合

ssh -p$SSH_PORT -q joker@$INSTANCE_IP 'yes y | ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa'

【讨论】:

【参考方案7】:

如果您不想提示用户输入保存密钥的文件,您可以在命令中添加文件输出标志-f

ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

这种方式不会提示用户输入任何内容 - 除非 id_rsa 文件已经存在。

【讨论】:

以上是关于如何在没有提示的情况下执行 ssh-keygen的主要内容,如果未能解决你的问题,请参考以下文章

如何在没有密码提示的情况下执行 mysqldump?

如何在没有确认提示的情况下执行 Set-GPPermissions 命令

如何回答 Python 的 ssh-keygen 密码提示?

OBIEE 11 - 如何在没有提示的情况下在 excel 中导出多页仪表板

如何使用ssh-keygen生成key

如何在不询问密码提示的情况下自动执行rsync [关闭]