GitHub whoami via SSH
There is a very easy way to know know which Github user is associated with your SSH key.
Executing ssh -T [email protected]
, you will receive a greeting with your
username.
❭ ssh -T [email protected]
Hi menduz! Youve successfully authenticated, but GitHub does not provide shell access.
To extract the username we can run sed
over the response.
❭ ssh -T [email protected] 2>&1 | sed 's/^Hi //' | sed 's/\! .*//'
menduz
Importing GPG keys
I use my YubiKey to store both my GPG and SSH. But having the SSH working out of the box is way easier than GPG, the last requires the machine to know the public key before it can be used. And it can be either downloaded from a key server, plain .asc files, or like in my case: download it from my Github profile.
To do so, I leverage the https://github.com/{username}.gpg
function.
Since we now know the username associated with the SSH in the YubiKey (the previous step), we can get the GPG keys like this:
❭ # this step may require you to touch the YubiKey
❭ username=$(ssh -T [email protected] 2>&1 | sed 's/^Hi //' | sed 's/\! .*//')
❭ curl --silent "https://github.com/${username}.gpg" | gpg --import
Check it works running gpg --card-status
and search for the email in the
"General key info" section, it must match your GPG's. If it doesn't show up,
make sure you are importing the same keys present in the card.
❭ gpg --card-status | grep "General key info"
General key info..: pub ed25519/3ABC123401923E0A 2020-11-08 Agustin Mendez <[email protected]>
Setting up Git
Now that we already have our GPG and SSH working, we must configure Git to use the GPG and the mail.
To do so, the email address from the GPG will be used (which is a requirement for Github).
# Read email from the --card-status
CARD_MAIL=$(gpg --card-status | grep -Po --color=never "(?<=<).*(?=>)")
if [[ $? == 0 ]]; then
echo "> Using mail: ${CARD_MAIL}"
CARD_NAME=$(gpg --card-status | grep -Po --color=never "(?<=[0-9]{4}-[0-9]{2}-[0-9]{2} ).*(?= <${CARD_MAIL})")
if [[ $? != 0 ]]; then
echo "> ! Cannot find CARD_NAME."
echo "> FAILED!"
else
echo "> Using name: ${CARD_NAME}"
KEY_ID=$(gpg --keyid-format none --list-key "${CARD_MAIL}" | grep -Po "[A-F0-9]{40}")
if [[ $? == 0 ]]; then
echo "> Using key: ${KEY_ID}"
git config --global user.name "${CARD_NAME}"
git config --global user.email "${CARD_MAIL}"
git config --global commit.gpgsign true
git config --global user.signingkey "${KEY_ID}"
# git config --global url."ssh://[email protected]/".insteadOf "https://github.com/"
echo "> SUCCESS!"
else
echo "> ! Cannot find KEY_ID"
echo "> FAILED!"
fi
fi
else
echo "> ! No known yubikey was detected."
echo "> FAILED!"
fi
Leaking SSH keys
Did you know you are sending your identities every time you connect to an ssh server?
Be careful to not leak your keys to every place you want to connect to.
To do so, create an identity for each site you want to connect to and add the following
lines to your ~/.ssh/config
file:
IdentitiesOnly yes
Host github.com
IdentityFile ~/.ssh/id_rsa_yubikey.pub
To get the public key from your SSH in the YubiKey run:
ssh-add -L | grep "cardno" > ~/.ssh/id_rsa_yubikey.pub
That is part of my https://menduz.com/bootstrap.sh script, used every time I set up a new machine or when I think that my machine was somehow compromised.