166

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

217

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 ""
7
  • 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>&-. Feb 4, 2018 at 19:05
  • 4
    So bad practice to generate a clear pair of keys in /tmp ;)
    – tisc0
    Feb 24, 2020 at 16:03
  • To make it not ask questions it's enough to specify the destination (-f ~/.ssh/id_rsa), and specify a passphrase (-N '').
    – x-yuri
    Apr 1, 2021 at 23:06
  • 1
    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 '""' ). 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
    Jan 10 at 7:28
54

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
  • confirmed: on lubuntu 14.04.2
    – user77115
    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
    May 16, 2016 at 14:41
  • 8
    Why do you cat /dev/zero? 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 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. Jun 12, 2020 at 20:51
18

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.

4
  • 2
    key_save_private: No such file or directory Jul 21, 2016 at 10:48
  • 7
    The -P <passphrase> option is to provide the (old) passphrase. linux.die.net/man/1/ssh-keygen Feb 21, 2017 at 23:04
  • works, but if the key already exist it ask for overwrite
    – elbarna
    Apr 7, 2020 at 0:23
  • ssh-keygen -P "" worked for me.
    – domih
    Apr 22, 2021 at 13:38
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. Mar 27, 2013 at 14:26
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
    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

2

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
    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. Nov 2, 2020 at 23:31
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".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.