-
-
Save kraftb/9918106 to your computer and use it in GitHub Desktop.
| #!/bin/bash | |
| BITS=2048 | |
| # In one line: | |
| # rm -f temp.key && ssh-keygen -t rsa -b 2048 -f temp.key -N "" -q && ssh-keygen -e -f temp.key -m PKCS8 | tr "\n" " " && echo && cat temp.key | tr "\n" " " && echo | |
| # In multiple lines: | |
| rm -f temp.key | |
| ssh-keygen -t rsa -b $BITS -f temp.key -N "" -q | |
| echo | |
| ssh-keygen -e -f temp.key -m PKCS8 | tr "\n" " " | |
| echo | |
| echo | |
| cat temp.key | tr "\n" " " | |
| echo | |
| echo | |
@allisonkarlitskaya Thanks for your contribution. Note that much of the trickery here, that is, all solution other than using openssl or your first Python solution, will fail if you work on a read-only filesystem.
Here's a practical example of this for encrypting the ssh key with sops and age in a taskfile:
version: "3"
gen-key:
desc: Generate encrypted ssh key
silent: true
status:
- test -f ssh.sops.key
cmds:
- mkfifo key key.pub
- defer: rm key key.pub
- cat key | sops -e /dev/stdin > ssh.sops.key &
- 'printf "Your public key:\n$(cat key.pub)\n" &'
- yes | ssh-keygen -t ed25519 -f key > /dev/nullI was working on a script to generate an SSH key pair and store it directly in my vault. I came across this gist and found @mprasil approach very helpful as a starting point.
That said, I ended up implementing it a bit differently. Since I needed to read both the private and public keys after generation, I decided to run the key generation process itself in the background (instead of backgrounding the file reads). Also the contents are read into a variable which you can use elsewhere in the script. Also does the cleanup on exit.
Here's my version of the code - hope it helps someone else!
local COMMENT="Your comment"
local TEMP_DIR=$(mktemp -d)
trap "rm -rf ${TEMP_DIR}" EXIT
local KEY_FILE="${TEMP_DIR}/key"
mkfifo "${KEY_FILE}" "${KEY_FILE}.pub"
(ssh-keygen -t ed25519 -N '' -q -f "${KEY_FILE}" -C "${COMMENT}" <<< y > /dev/null)&
sleep 0.1
PRI_KEY=$(< "${KEY_FILE}")
PUB_KEY=$(< "${KEY_FILE}.pub")
Here is how you can output just the public key and append this output to a remote host's authorized_keys file, with a single command line
(mkfifo key key.pub && ((cat key > /dev/null ; cat key.pub ; rm key key.pub )&) && (echo y | ssh-keygen -N '' -q -f key > /dev/null)) | ssh -o "StrictHostKeyChecking no" username@remotehost.lan "cat >> ~/.ssh/authorized_keys"
At which point I realized I actually need that private key for auto login and it needed to my in my local host's ~/.ssh/id_rsa
Also you need that id_rsa to only be readable by the owner or else it will be ignored by ssh
This one line command will let your create private keys and push them to any remote host
(mkfifo key key.pub && ((cat key > ~/.ssh/id_rsa ; chmod go-rwx ~/.ssh/id_rsa ; cat key.pub ; rm key key.pub )&) && (echo y | ssh-keygen -N '' -q -f key > /dev/null)) | ssh -o "StrictHostKeyChecking no" username@remotehost.lan "cat >> ~/.ssh/authorized_keys"But now I realize, the entire reason why I needed to output the public key to console is gone, I was trying to have useless keyfiles scattered about but I need those files....
So the command becomes
This will create keys and push them to a remote host in a single command !
(mkfifo key key.pub && ((cat key > ~/.ssh/id_rsa ; chmod go-rwx ~/.ssh/id_rsa ; cat key.pub | tee ~/.ssh/id_rsa.pub ; rm key key.pub )&) && (echo y | ssh-keygen -N '' -q -f key > /dev/null)) | ssh -o "UserKnownHostsFile=/dev/null" -o "StrictHostKeyChecking=no" -o "PubkeyAuthentication=no" username@remotehost.lan "cat >> ~/.ssh/authorized_keys"At which point, I realize I could just ask ssh-keygen to output key files in the right place ..
And there's a command called ssh-copy-id for doing exactly what I'm doing
So, here's another, final, version of that
This one liner will create public/private key pair in the .ssh default folder only if you don't already have them and push them to your remote host
([ -f ~/.ssh/id_rsa.pub ] || ssh-keygen -N '' -q -f ~/.ssh/id_rsa) ;ssh-copy-id username@hostname.lan