keybase / keybase-issues

A single repo for managing publicly recognized issues with the keybase client, installer, and website.
902 stars 37 forks source link

Integrate GPG authentication keys with OpenSSH #2230

Open bitglue opened 8 years ago

bitglue commented 8 years ago

It would be great if keybase could handle SSH keys, as requested in #710. The answer is already in there, but it's buried in all the noise of people arguing about how to sign and prove what and whatever. Truth is that keybase already does this: it just needs a little UI polish.

Here's a proof of concept. It requires openpgp2ssh from monkeysphere. Invoke it with someone's keybase username and it will output that person's SSH pubilc key.

#!/bin/bash

set -o nounset -o errexit

username=$1

cleanup() {
    [[ -e "$key" ]] && rm -f "$key"
}

get-fingerprint() {
    while read line; do
        IFS=':' read -ra fields <<< "$line"
        if [[ "${fields[0]}" == "fpr" ]]; then
            echo "${fields[9]}"
            return
        fi
    done
    return 1
}

auth-keys() {
    while read line; do
        IFS=':' read -ra fields <<< "$line"
        [[ "${fields[0]}" == "sub" ]] || continue # skip all but subkeys
        [[ "${fields[1]}" == "r" ]] && continue   # skip revoked keys
        [[ "${fields[11]}" == *a* ]] || continue  # skip all but auth keys
        echo "${fields[4]}"
    done
}

key=$(mktemp)
trap cleanup EXIT
curl -s "https://keybase.io/$username/key.asc" > "$key"

gpg2 --quiet --import "$key"
fingerprint="$(gpg2 --with-colons "$key" | get-fingerprint)"

gpg2 --with-colons --list-keys "$fingerprint" | auth-keys | while read subkey; do
    gpg2 --dearmor <"$key" | openpgp2ssh "$subkey"
done

And boom:

$ ./get-ssh-key.sh indigo
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCJ/asD6o9k1CjNssGzLC45ekkHBw0lFDVnbavN4/Q2MwaVktQAY2QJW/usdF1/c7L8ASy5BcwILsekSJHHg0P9nZf4vsCnAyyURbPxVqEllSUofl1u5pqDEOwgpPSbh+zRkwKmHUnOp9zb8ecZTl/gnpNAFTYm2nxF9LH3/3ScEM/Q8wmrV43EnBP8TazNhNuqNip6Sbp7GkAFNxCZz7XYI6xNh/Bzv1JAzKqC5aRzUJeWaPGBG7CiYlwgHvg2QoePKv+99geenMJmfS2jdL6iyRdYOpiBlOTTUOxK1W3FsiKz0JQn7W0Od3shHLB/fJoszUKV2Avoh8zUKbOaL0B9

Having something like this which isn't a shell script hack in the keybase client would be super great and useful for me. And of course the additional validation that keybase can provide is about 1000x better than typical SSH key validation, which usually consists of someone emailing a sysadmin a key.


On the other end, people need to actually use the corresponding private key as their SSH identity. Most people only know how to run ssh-keygen and they think that's the only way to do SSH authentication, but it's not.

Personally I use gpg-agent as an SSH agent. My private key is on a smartcard so this is pretty much the only option for me. It's pretty great, though admittedly it was a pain to set up.

An easier option is to pipe gpg2 --export-secret-subkeys into openpgp2ssh to get one's GPG private key in a format suitable for ~/.ssh/id_rsa. This should work for nearly everyone without the fuss of setting up gpg-agent.

I suspect, though I've not tried, that it's possible to attach an existing SSH keypair as a subkey of a GPG key.


So in closing, some pretty great SSH <-> keybase integrations are already possible, just difficult due to the arcane incantations required to perform them. Most of the work is just converting between different key formats. A couple of additions to the keybase client would make it orders of magnitude easier.

bitglue commented 8 years ago

Just as a quick note, it is easy to convert a key to the ssh format with gpg2

Even better. But it looks like it's quite recent, more specifically gpg 2.1. Quite a few distros don't have it yet.

jalustig commented 8 years ago

This would be super cool, especially if there were an easy way to have keybase installed on your server to import the desired user's SSH key to enable login. That way the entire SSH system could be verified: that the user who you are allowing to log in is the person you want, and that the server you are connecting to (via DNS verification of Keybase identity) is owned by a keybase id.

zokier commented 7 years ago

@BrandonIngalls That looks great. Is there some easy way to use --export-ssh-key without importing the key first to keyring? I made small scriptlet to achieve that for now, but its hardly ideal:

#!/bin/bash
TMPDIR=$(mktemp -d)
export GNUPGHOME=$TMPDIR/gpg
mkdir -p $GNUPGHOME
cd $TMPDIR
wget -q https://keybase.io/$1/key.asc
gpg --no-permission-warning --batch --quiet --import key.asc
KEYID=$(gpg --no-permission-warning --batch --quiet --list-keys --with-colons|grep ^pub|awk -F: '{print $5}')
gpg --no-permission-warning --batch --quiet --export-ssh-key $KEYID
rm -rf $TMPDIR
drzraf commented 7 years ago

Any hint about how to import an existing ssh-key pair as a gpg [A] subkey would be great (https://unix.stackexchange.com/questions/372879/)