如何在没有提示的情况下执行 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-keygen
man 页面:
-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 >/dev/null
可能类似于echo y|ssh-keygen -q -t rsa -N '' > NUL
很好的答案,尽管正确的重定向顺序是:>/dev/null 2>&1
2>&1 >/dev/null
导致 stdout 到 /dev/null 和 steder 到 stdout,这不是预期的【参考方案3】:
接受的答案仍然指定自定义文件名。这对我有用:
ssh-keygen -t rsa -b 4096 -N '' <<<$'\n'
-t rsa
指定要创建的密钥类型 (RSA)。
-b 4096
指定要创建的密钥的位数(4096 位)。
-N ''
提供密码(在本例中为空)。
<<<
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
(安静)选项或>/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的主要内容,如果未能解决你的问题,请参考以下文章
如何在没有确认提示的情况下执行 Set-GPPermissions 命令
如何回答 Python 的 ssh-keygen 密码提示?