Skip to content

Instantly share code, notes, and snippets.

@grenade
Last active May 2, 2024 23:15
Show Gist options
  • Save grenade/6318301 to your computer and use it in GitHub Desktop.
Save grenade/6318301 to your computer and use it in GitHub Desktop.
generate ed25519 ssh and gpg/pgp keys and set file permissions for ssh keys and config
#!/bin/bash
# generate new personal ed25519 ssh key
ssh-keygen -o -a 100 -t ed25519 -f ~/.ssh/id_ed25519 -C "rob thijssen <rthijssen@gmail.com>"
# generate new host cert authority (host_ca) ed25519 ssh key
# used for signing host keys and creating host certs
ssh-keygen -t ed25519 -f manta_host_ca -C manta.network
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_ed25519
# set local file permissions
chmod 700 ~/.ssh
chmod 644 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts
chmod 644 ~/.ssh/config
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub
# add key to git/github
git config --global core.sshCommand "ssh -i ~/.ssh/id_ed25519 -F /dev/null"
# sudo dnf config-manager --add-repo https://cli.github.com/packages/rpm/gh-cli.repo
# sudo dnf install gh
gh ssh-key add ~/.ssh/id_ed25519.pub
#!/bin/bash
# usage
# $ curl -sL https://gist.github.com/grenade/6318301/raw/02-backup-gpg-key.sh?$(uuidgen) | bash
backup_dir=${HOME}/key-backup
# backup old gpg key
key_name="Rob Thijssen (https://grenade.github.io) <rthijssen@gmail.com>"
key_fingerprint=$(if [[ $(gpg --list-keys ${key_name}) =~ ([A-F0-9]{40}) ]]; then echo ${BASH_REMATCH[1]}; fi)
if [ -n "${key_fingerprint}" ]; then
timestamp=$(date -u --iso-8601)
mkdir -p ${backup_dir}/${timestamp}/${key_fingerprint}
gpg --export --armor ${key_fingerprint} > ${backup_dir}/${timestamp}/${key_fingerprint}/public.asc
gpg --export-secret-keys --armor ${key_fingerprint} > ${backup_dir}/${timestamp}/${key_fingerprint}/private.asc
gpg --export-secret-subkeys --armor ${key_fingerprint} > ${backup_dir}/${timestamp}/${key_fingerprint}/subkeys.private.asc
gpg --export-ownertrust > ${backup_dir}/${timestamp}/${key_fingerprint}/ownertrust.txt
tar -C ~/ -zcvf ${backup_dir}/${timestamp}/${key_fingerprint}/.gnupg.tar.gz .gnupg
fi
#!/bin/bash
# references:
# - https://blog.josefsson.org/tag/ed25519/
# - https://www.gnupg.org/documentation/manuals/gnupg/OpenPGP-Key-Management.html
# use a new and unique key name.
# it will be necessary to have both old and new keys while transitioning.
# eg: for password-store re-encryption.
old_key_name="Rob Thijssen (https://grenade.github.io) <rthijssen@gmail.com>"
new_key_name="rob thijssen <rthijssen@gmail.com>"
# generate ed25519 master key with no expiration
gpg --quick-generate-key ${new_key_name} ed25519 sign 0
old_key_fingerprint=$(if [[ $(gpg --list-keys ${old_key_name}) =~ ([A-F0-9]{40}) ]]; then echo ${BASH_REMATCH[1]}; fi)
new_key_fingerprint=$(if [[ $(gpg --list-keys ${new_key_name}) =~ ([A-F0-9]{40}) ]]; then echo ${BASH_REMATCH[1]}; fi)
if [ -n "${new_key_fingerprint}" ]; then
# generate elyptic curve encryption sub-key with no expiration
gpg --quick-add-key ${new_key_fingerprint} cv25519 encr 0
# generate ed25519 authentication sub-key with no expiration
gpg --quick-add-key ${new_key_fingerprint} ed25519 auth 0
# generate ed25519 signing sub-key with no expiration
gpg --quick-add-key ${new_key_fingerprint} ed25519 sign 0
# sign the new key with the old key
gpg --default-key ${old_key_fingerprint} --sign-key ${new_key_fingerprint}
# optionally sign the old key with the new key
# gpg --default-key ${new_key_fingerprint} --sign-key ${old_key_fingerprint}
# wip. don't use this.
# touch transition-statement.md
# gpg --digest-algo SHA512 --default-key ${new_key_fingerprint} --clearsign transition-statement.md
# tell git about signing key
# https://docs.github.com/en/github/authenticating-to-github/telling-git-about-your-signing-key
new_signing_key_id=$(if [[ $(gpg --list-secret-keys --keyid-format LONG ${new_key_fingerprint}) =~ ed25519/([A-F0-9]{16})[[:space:]]202[1-9]-[01][0-9]-[0-3][0-9][[:space:]]\[S\] ]]; then echo ${BASH_REMATCH[1]}; fi)
git config --global user.signingkey ${new_signing_key_id}
fi

update ~/.gitconfig

[user]
  ...
  signingkey = <signing key from `gpg --list-secret-keys --keyid-format LONG` goes here)
  ...

update password-store (re-encrypt everything)

cd ~/.password-store
pass init $new_key_fingerprint $old_key_fingerprint
ssh-keygen -t rsa -b 4096 -N '' -C "rthijssen@gmail.com" -f ~/.ssh/id_rsa
ssh-keygen -t rsa -b 4096 -N '' -C "rthijssen@gmail.com" -f ~/.ssh/github_rsa
ssh-keygen -t rsa -b 4096 -N '' -C "rthijssen@gmail.com" -f ~/.ssh/mozilla_rsa
eval "$(ssh-agent -s)"
ssh-add ~/.ssh/id_rsa
ssh-add ~/.ssh/github_rsa
ssh-add ~/.ssh/mozilla_rsa
chmod 700 ~/.ssh
chmod 644 ~/.ssh/authorized_keys
chmod 644 ~/.ssh/known_hosts
chmod 644 ~/.ssh/config
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub
chmod 600 ~/.ssh/github_rsa
chmod 644 ~/.ssh/github_rsa.pub
chmod 600 ~/.ssh/mozilla_rsa
chmod 644 ~/.ssh/mozilla_rsa.pub
@KlausEverWalkingDev
Copy link

Thanks for those simple but important commands. It saved me from craziness :)

@cassie-nahar
Copy link

@ajorpheus

chmod 644 ~/.ssh/config seems to be incorrect according to http://linuxcommand.org/lc3_man_pages/ssh1.html which says:

Because of the potential for abuse,
this file must have strict
permissions: read/write for the
user, and not accessible by others.

That should be chmod 600 ~/.ssh/config instead

Beware that the man pages will vary from one version to another. For example, the man page on Ubuntu Bionic says:

 ~/.ssh/config
        This is the per-user configuration file.  The file format and configuration options
        are described in ssh_config(5).  Because of the potential for abuse, this file must
        have strict permissions: read/write for the user, and not writable by others.  It may
        be group-writable provided that the group in question contains only the user.

Which would mean either chmod 644 ~/.ssh/config or chmod 664 ~/.ssh/config if the file group contains only your user.

Overall, safer is better and you should lock the files down as much as possible for your environment.

@tornikesharia
Copy link

Works like a charm. Thanks dude!

@duynguyen-icw
Copy link

duynguyen-icw commented Mar 25, 2021

You saved my day, thanks a lot! xD

@fabiofrasson
Copy link

Thank you very much for sharing this information :D

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment