【问题标题】:How to execute ssh-keygen without prompt如何在没有提示的情况下执行 ssh-keygen
【发布时间】: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'。

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

【问题讨论】:

    标签: linux bash shell ssh


    【解决方案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】:

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

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

        ssh-keygen -t rsa -N ''

      2. 覆盖密钥文件

      使用-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 名称而只想覆盖它,我们需要自动回答这两个问题:

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

      2. 覆盖(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 文件已经存在。

            【讨论】:

              猜你喜欢
              • 2011-07-13
              • 2012-03-06
              • 2018-07-01
              • 2017-11-07
              • 2021-08-14
              • 2020-05-14
              • 1970-01-01
              • 2016-09-11
              相关资源
              最近更新 更多