213

I would like to make an automated script that calls ssh-keygen and creates some pub/private keypairs that I will use later on. In principle everything works fine with....
ssh-keygen -b 2048 -t rsa -f /tmp/sshkey -q
...except that it asks me for the passphrase that would encrypt the keys. This make -at present- the automation difficult.

I could provide a passphrase via the command line argument -N thepassphrase, so to keep the prompt from appearing. Still I do not even desire to have the keys -additionally secured by encryption- and want the keypairs to be plaintext.

What is a (the best) solution to this problem?

The -q option which supposedly means "quiet/silent" does still not avoid the passphrase interaction. Also I have not found something like this
ssh-keygen ... -q --no-passphrase

Please do not start preaching about or lecture me to the pro and cons of the "missing passphrase", I am aware of that. In the interactive form (not as a script) the user can simply hit [ENTER] twice and the key will be saved as plaintext. This is what I want to achieve in a script like this:

#!/bin/bash

command1
command2
var=$(command3)

# this should not stop the script and ask for password
ssh-keygen -b 2048 -t rsa -f /tmp/sshkey -q

8 Answers 8

273

This will prevent the passphrase prompt from appearing and set the key-pair to be stored in plaintext (which of course carries all the disadvantages and risks of that):

ssh-keygen -b 2048 -t rsa -f /tmp/sshkey -q -N ""

Using Windows 10 built in SSH

PowerShell:

ssh-keygen -b 2048 -t rsa -f C:/temp/sshkey -q -N '""'

CMD:

ssh-keygen -b 2048 -t rsa -f C:/temp/sshkey -q -N ""
8
  • 8
    This works. In case /tmp/sshkey already exists one gets an overwrite prompt, though. This can be prevented via redirecting/closing stdin - e.g. via adding 0>&-. Commented Feb 4, 2018 at 19:05
  • 6
    So bad practice to generate a clear pair of keys in /tmp ;)
    – tisc0
    Commented Feb 24, 2020 at 16:03
  • 3
    To make it not ask questions it's enough to specify the destination (-f ~/.ssh/id_rsa), and specify a passphrase (-N '').
    – x-yuri
    Commented Apr 1, 2021 at 23:06
  • 2
    Powershell should be ssh-keygen -t rsa -b 4096 -f "C:/temp/sshkey" -q -N '""' (single quotes around a set of double quotes). While 2 sets of double quotes works in this specific case, it can cause issues when paired with additional arguments (such as empty comment/-C e.g. ssh-keygen -t rsa -b 4096 -f "C:/temp/sshkey" -q -N '""' -C '""' ). Commented Jul 9, 2021 at 2:43
  • 1
    This is a variation I came up with, in my case I needed to overwrite any previous ssh keys so mine looks like this HOSTNAME=$(hostname) ; yes | ssh-keygen -t rsa -C "$HOSTNAME" -f "$HOME/.ssh/id_rsa" -P "" && cat ~/.ssh/id_rsa.pub
    – ruevaughn
    Commented Jan 10, 2022 at 7:28
61

The simplest way I found to do what you want is this (example using default filename)

    < /dev/zero ssh-keygen -q -N ""

If the ~/.ssh/id_rsa file already exists, the command will exit without modifying anything.

If not, you get a brand new key, in that filename.

Either way, you haven't overwritten anything, and you know at the end you have a key.

9
  • 1
    confirmed: on lubuntu 14.04.2
    – user77115
    Commented Mar 15, 2015 at 11:40
  • 1
    On (admittedly antique) SLES 11 the above command fail to produce a key. yes "" | ssh-keygen -N "" >&- 2>&- works just fine however and does not output anything (whether or not a keyfile already exists), and does not overwrite a previously existing keyfile.
    – zrajm
    Commented May 16, 2016 at 14:41
  • 8
    Why do you cat /dev/zero? Commented Feb 4, 2018 at 18:59
  • 1
    @maxschlepzig That's how it answers "no" to the "do you want to overwrite?" prompt when the file already exists Commented Jun 12, 2020 at 20:31
  • 2
    @JoeHolloway I see - the cat is superfluous then, i.e. < /dev/zero ssh-keygen -q -N '' works the same. Commented Jun 12, 2020 at 20:51
27

This worked for me:

ssh-keygen -t rsa -f /home/oracle/.ssh/id_rsa -q -P ""

The -P is the passphrase option, and "" is the empty passphrase.

5
  • 2
    key_save_private: No such file or directory Commented Jul 21, 2016 at 10:48
  • 10
    The -P <passphrase> option is to provide the (old) passphrase. linux.die.net/man/1/ssh-keygen
    – Gian Tech
    Commented Feb 21, 2017 at 23:04
  • works, but if the key already exist it ask for overwrite
    – elbarna
    Commented Apr 7, 2020 at 0:23
  • ssh-keygen -P "" worked for me.
    – domih
    Commented Apr 22, 2021 at 13:38
  • @GianfrancoP. Do you suggest using -N <new_passphrase> instead? Commented Jul 21, 2022 at 19:19
7

You can use expect to send the "enter" for you

cat test.sh
#!/bin/bash
set -x
XYZ=$(expect -c "
spawn ssh-keygen -b 2048 -t rsa -f /tmp/sshkey -q
expect \"Enter passphrase (empty for no passphrase):\"
send \"\r\"
expect \"Enter same passphrase again:\"
send \"\r\"
")

But be aware, that if the file /tmp/sshkey already exists it will fail because the output of the command will be different.

1
  • 1
    thank you for the contribution. the expect seems even a more versatile for problems in the same kind.... well those where scripting and user-interaction would conflict. I will be aware of the potential conflicht that /tmp/sshkey already exists and check for it prior to using your command. Commented Mar 27, 2013 at 14:26
3

For another user, tested on Ubuntu 18.04:

sudo -u username bash -c "ssh-keygen -f ~username/.ssh/id_rsa -N ''"
2
  • What is the relevance of doing it for another user? How does ssh-keygen depend on the user running it? I'm just trying to understand this better. Thanks.
    – pgr
    Commented Nov 2, 2020 at 16:17
  • 2
    Good point. One benefit is the rights are set correct by ssh-keygen. I have updated the answer to put the file straight in the right place. Now the command does everything in one go: no need to move files or change rights. Commented Nov 2, 2020 at 23:31
2

I did a simple echo before ssh-keygen. So su - <user> -c "echo |ssh-keygen -t rsa"

This was tested on Redhat 6

1
  • I don't think this is the best answer around, but I think there isn't any reason to downvote either, guys.
    – cubuspl42
    Commented Nov 1, 2016 at 15:05
2

ssh key generation function which can be put into .bashrc or .bash_aliases

# Make an ssh key if not exists, and copy ssh key to clipboard
# needs xclip to copy to system clipboard
ssh-key-now () {
    cat /dev/zero | ssh-keygen -t ed25519 -C "made with ssh-key-now" -q -N ""
    xclip -sel clip < ~/.ssh/id_ed25519.pub
    echo "ssh-key copied to clipboard"
}

Saves time when you've reinstalled OS and lost your ssh keys and have to set up gitlab/github again

0

The following works:

sudo -u user ssh-keygen -t rsa -N '' <<<''

It is intended to create the directory ~user/.ssh/, so that the file ~user/.ssh/authorized_keys can be created and updated to hold a public key for incoming ssh access.

A key pair is also generated but not needed for this purpose.

For example, one can prepare a boot-time init (kernel) parameter to preseed a live system for ssh access as follows:

ID=$(cat ~/.ssh/id_rsa.pub)
pr1="sudo -u user ssh-keygen -t rsa -N '' <<<''; echo '$ID' | sudo -u user tee -a ~user/.ssh/authorized_keys"

Include "$pr1" in the appropriate kernel parameter as a command which gets run automatically, as in ocs_prerun1="$pr1" for Clonezilla. Also verify that ssh service is enabled, as in ocs_daemonon="ssh".

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .