#!/bin/bash set -euo pipefail # ============================================================================== # GPG + YubiKey SSH Authentication Setup # ============================================================================== # Configures GPG agent for YubiKey-based SSH authentication # Run AFTER install-apt-tools.sh has installed yubikey-manager, pcscd, scdaemon # ============================================================================== readonly GREEN='\033[0;32m' readonly YELLOW='\033[1;33m' readonly BLUE='\033[0;34m' readonly RED='\033[0;31m' readonly NC='\033[0m' log() { echo -e "${GREEN}[INFO]${NC} $*"; } warn() { echo -e "${YELLOW}[WARN]${NC} $*"; } error() { echo -e "${RED}[ERROR]${NC} $*"; } section() { echo -e "${BLUE}=== $* ===${NC}"; } section "GPG + YubiKey SSH Setup" echo "" # Check dependencies log "Checking dependencies..." MISSING=() command -v gpg >/dev/null 2>&1 || MISSING+=("gnupg") command -v ykman >/dev/null 2>&1 || MISSING+=("yubikey-manager") systemctl list-unit-files | grep -q pcscd || MISSING+=("pcscd") if [ ${#MISSING[@]} -gt 0 ]; then error "Missing dependencies: ${MISSING[*]}" echo "Run: sudo apt install ${MISSING[*]}" exit 1 fi log "All dependencies found" echo "" section "Configuring GPG Agent" # Create ~/.gnupg if it doesn't exist mkdir -p ~/.gnupg chmod 700 ~/.gnupg # Configure gpg-agent.conf GPG_AGENT_CONF=~/.gnupg/gpg-agent.conf if ! grep -q "enable-ssh-support" "$GPG_AGENT_CONF" 2>/dev/null; then log "Adding enable-ssh-support to gpg-agent.conf" echo "enable-ssh-support" >> "$GPG_AGENT_CONF" else log "enable-ssh-support already configured" fi echo "" section "Shell Configuration" echo "" # Detect shell SHELL_RC="" if [ -n "${ZSH_VERSION:-}" ] || [ -f ~/.zshrc ]; then SHELL_RC=~/.zshrc elif [ -f ~/.bashrc ]; then SHELL_RC=~/.bashrc fi SSH_AUTH_LINE='export SSH_AUTH_SOCK="$(gpgconf --list-dirs agent-ssh-socket)"' echo "Add this to your shell config ($SHELL_RC or ~/.exports):" echo "" echo " $SSH_AUTH_LINE" echo "" if [ -n "$SHELL_RC" ]; then read -p "Add to $SHELL_RC automatically? [y/N] " -n 1 -r echo if [[ $REPLY =~ ^[Yy]$ ]]; then if ! grep -q "gpgconf --list-dirs agent-ssh-socket" "$SHELL_RC" 2>/dev/null; then echo "" >> "$SHELL_RC" echo "# GPG agent for SSH (YubiKey support)" >> "$SHELL_RC" echo "$SSH_AUTH_LINE" >> "$SHELL_RC" log "Added to $SHELL_RC" else log "Already configured in $SHELL_RC" fi fi fi echo "" section "Restart GPG Agent" log "Killing gpg-agent to apply changes..." gpgconf --kill gpg-agent echo "" section "Testing Setup" # Start pcscd if not running if ! systemctl is-active --quiet pcscd; then log "Starting pcscd..." sudo systemctl start pcscd fi echo "" log "Checking for YubiKey..." if ykman list 2>/dev/null | grep -q "YubiKey"; then log "YubiKey detected!" ykman list echo "" log "Checking GPG card status..." if gpg --card-status >/dev/null 2>&1; then log "GPG sees the YubiKey!" echo "" gpg --card-status | head -15 else warn "GPG can't see the card. Try: sudo systemctl restart pcscd" fi else warn "No YubiKey detected. Plug one in and run: gpg --card-status" fi echo "" section "Next Steps" echo "" cat << 'NEXT' 1. If you haven't moved GPG keys to YubiKey yet: gpg --edit-key > key 1 # select auth subkey > keytocard # move to YubiKey (ONE-WAY!) > save 2. Export your SSH public key from the YubiKey: gpg --export-ssh-key > ~/.ssh/yubikey.pub 3. Add to remote servers: ssh-copy-id -f -i ~/.ssh/yubikey.pub user@server 4. Configure SSH to use YubiKey (add to ~/.ssh/config): Host server-yubikey User youruser HostName server.example.com IdentityAgent /run/user/1000/gnupg/S.gpg-agent.ssh 5. Test SSH: ssh server-yubikey NEXT echo "" section "Setup Complete!" log "Reload your shell or run: source $SHELL_RC" echo ""