docs(yubikey): add post-rebuild YubiKey setup guide
Step-by-step guide covering GPG key generation, subkey creation, moving keys to YubiKey, SSH key deployment, and git signing setup.
This commit is contained in:
+269
@@ -0,0 +1,269 @@
|
||||
# Post-Rebuild YubiKey Setup Guide
|
||||
|
||||
## Step 0: Rebuild & Reboot
|
||||
|
||||
```bash
|
||||
nixos-rebuild switch
|
||||
# Then reboot to ensure gpg-agent replaces gnome-keyring as SSH agent
|
||||
reboot
|
||||
```
|
||||
|
||||
After reboot, verify the new environment:
|
||||
|
||||
```bash
|
||||
gpg --version # Should show GnuPG 2.4+
|
||||
ykman info # Should show your YubiKey model/serial
|
||||
gpg --card-status # Should show the YubiKey smartcard
|
||||
echo $SSH_AUTH_SOCK # Should point to gpg-agent socket, NOT gcr
|
||||
```
|
||||
|
||||
> If `gpg --card-status` hangs or errors, restart pcscd:
|
||||
> `sudo systemctl restart pcscd`
|
||||
|
||||
---
|
||||
|
||||
## Step 1: Generate GPG Master Key
|
||||
|
||||
```bash
|
||||
gpg --expert --full-generate-key
|
||||
```
|
||||
|
||||
At the prompts:
|
||||
|
||||
1. Select **(9) ECC and ECC**
|
||||
2. Curve: **Curve 25519**
|
||||
3. Expiration: **1y**
|
||||
4. Real name: **0xWheatyz**
|
||||
5. Email: **wyatt@leeworks.dev**
|
||||
6. Set a strong passphrase
|
||||
|
||||
Note the key ID printed (e.g. `0x1234ABCD5678EFGH`).
|
||||
|
||||
---
|
||||
|
||||
## Step 2: Add Subkeys
|
||||
|
||||
```bash
|
||||
gpg --expert --edit-key <KEY-ID>
|
||||
```
|
||||
|
||||
Add 3 subkeys at the `gpg>` prompt:
|
||||
|
||||
**Signing subkey:**
|
||||
|
||||
```
|
||||
gpg> addkey
|
||||
→ (10) ECC (sign only)
|
||||
→ Curve 25519
|
||||
→ 1y expiry
|
||||
```
|
||||
|
||||
**Encryption subkey** (may already exist — check with `list`):
|
||||
|
||||
```
|
||||
gpg> addkey
|
||||
→ (12) ECC (encrypt only)
|
||||
→ Curve 25519
|
||||
→ 1y expiry
|
||||
```
|
||||
|
||||
**Authentication subkey:**
|
||||
|
||||
```
|
||||
gpg> addkey
|
||||
→ (11) ECC (set your own capabilities)
|
||||
→ Toggle: disable Sign, enable Authenticate
|
||||
→ Curve 25519
|
||||
→ 1y expiry
|
||||
```
|
||||
|
||||
```
|
||||
gpg> save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 3: Back Up Master Key (CRITICAL)
|
||||
|
||||
> Once keys are moved to the YubiKey, they cannot be extracted. Back up now.
|
||||
|
||||
```bash
|
||||
mkdir -p /tmp/gpg-backup
|
||||
gpg --armor --export-secret-keys <KEY-ID> > /tmp/gpg-backup/master-secret.asc
|
||||
gpg --armor --export-secret-subkeys <KEY-ID> > /tmp/gpg-backup/subkeys-secret.asc
|
||||
gpg --armor --export <KEY-ID> > /tmp/gpg-backup/public.asc
|
||||
gpg --export-ownertrust > /tmp/gpg-backup/ownertrust.txt
|
||||
```
|
||||
|
||||
Copy `/tmp/gpg-backup/` to an encrypted USB drive or other secure offline storage. Then remove the temp copy:
|
||||
|
||||
```bash
|
||||
rm -rf /tmp/gpg-backup
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 4: Move Subkeys to YubiKey
|
||||
|
||||
```bash
|
||||
gpg --edit-key <KEY-ID>
|
||||
```
|
||||
|
||||
Move each subkey to its corresponding card slot:
|
||||
|
||||
```
|
||||
gpg> key 1
|
||||
gpg> keytocard
|
||||
→ (1) Signature key
|
||||
gpg> key 1
|
||||
|
||||
gpg> key 2
|
||||
gpg> keytocard
|
||||
→ (2) Encryption key
|
||||
gpg> key 2
|
||||
|
||||
gpg> key 3
|
||||
gpg> keytocard
|
||||
→ (3) Authentication key
|
||||
|
||||
gpg> save
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 5: Set Trust & Verify
|
||||
|
||||
```bash
|
||||
gpg --edit-key <KEY-ID>
|
||||
```
|
||||
|
||||
```
|
||||
gpg> trust
|
||||
→ (5) I trust ultimately
|
||||
gpg> quit
|
||||
```
|
||||
|
||||
Verify the card:
|
||||
|
||||
```bash
|
||||
gpg --card-status # Should show all 3 subkeys
|
||||
gpg --list-secret-keys # Subkeys should show "ssb>" (stub pointing to card)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 6: Back Up & Remove Old SSH Keys
|
||||
|
||||
```bash
|
||||
mkdir -p ~/.ssh/old
|
||||
mv ~/.ssh/id_ed25519 ~/.ssh/old/
|
||||
mv ~/.ssh/id_ed25519.pub ~/.ssh/old/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 7: Get Your New SSH Public Key
|
||||
|
||||
```bash
|
||||
gpg --export-ssh-key <KEY-ID>
|
||||
```
|
||||
|
||||
This outputs the SSH public key derived from your GPG auth subkey. Save it:
|
||||
|
||||
```bash
|
||||
gpg --export-ssh-key <KEY-ID> > ~/.ssh/yubikey.pub
|
||||
```
|
||||
|
||||
Verify gpg-agent serves it:
|
||||
|
||||
```bash
|
||||
ssh-add -L # Should show the same key
|
||||
```
|
||||
|
||||
Deploy this key to your remote servers:
|
||||
|
||||
- **vps** (45.79.198.105) — add to `~/.ssh/authorized_keys` for user `wyatt`
|
||||
- **home** (10.0.0.20) — add to `~/.ssh/authorized_keys` for user `l-wyatt`
|
||||
- **git** (10.0.1.10) — add via your Gitea/Forgejo web UI
|
||||
- **GitHub** — Settings → SSH and GPG Keys → New SSH Key
|
||||
|
||||
> **Tip:** Use the old key (still in `~/.ssh/old/`) to SSH in and deploy the new one:
|
||||
> ```bash
|
||||
> ssh -i ~/.ssh/old/id_ed25519 vps "echo '$(gpg --export-ssh-key <KEY-ID>)' >> ~/.ssh/authorized_keys"
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## Step 8: Update home.nix with Your Signing Key
|
||||
|
||||
Get your key ID:
|
||||
|
||||
```bash
|
||||
gpg --list-secret-keys --keyid-format 0xlong
|
||||
```
|
||||
|
||||
Then edit `home.nix` and replace the `key = null;` line:
|
||||
|
||||
```nix
|
||||
signing = {
|
||||
key = "<YOUR-0xLONG-KEY-ID>"; # e.g. "0x1234ABCD5678EFGH"
|
||||
signByDefault = true;
|
||||
};
|
||||
```
|
||||
|
||||
Rebuild again:
|
||||
|
||||
```bash
|
||||
nixos-rebuild switch
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 9: Verify Everything
|
||||
|
||||
```bash
|
||||
# Smartcard
|
||||
gpg --card-status
|
||||
|
||||
# SSH via YubiKey
|
||||
ssh-add -L
|
||||
ssh vps echo "YubiKey SSH works!"
|
||||
|
||||
# Git signing
|
||||
cd /tmp && git init test-sign && cd test-sign
|
||||
git commit --allow-empty -m "test signing"
|
||||
git log --show-signature -1
|
||||
# Should show "Good signature from 0xWheatyz <wyatt@leeworks.dev>"
|
||||
rm -rf /tmp/test-sign
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 10 (Optional): Change YubiKey PINs
|
||||
|
||||
The default PINs are `123456` (user) and `12345678` (admin). Change them:
|
||||
|
||||
```
|
||||
gpg --card-edit
|
||||
gpg/card> admin
|
||||
gpg/card> passwd
|
||||
→ (1) Change PIN
|
||||
→ (3) Change Admin PIN
|
||||
gpg/card> quit
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Step 11 (Optional): Upload GPG Public Key to GitHub
|
||||
|
||||
```bash
|
||||
gpg --armor --export <KEY-ID>
|
||||
```
|
||||
|
||||
Paste the output into **GitHub → Settings → SSH and GPG Keys → New GPG Key**. This makes your signed commits show "Verified" on GitHub.
|
||||
|
||||
---
|
||||
|
||||
## Note
|
||||
|
||||
The config changes to `configuration.nix` and `home.nix` are already saved. After you rebuild, reboot, and follow the steps above, you'll need to come back to update `home.nix` one more time with your actual GPG key ID (Step 8) and do a final rebuild.
|
||||
Reference in New Issue
Block a user