- Copy actual .gitconfig instead of placeholder - Create encrypted SSH key backup script with GPG - Add SSH-based remote setup script - Include restore instructions and security notes 🤖 Generated with Claude Code (https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
182 lines
4.8 KiB
Bash
Executable File
182 lines
4.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Backup and encrypt SSH keys
|
|
|
|
set -euo pipefail
|
|
|
|
SSH_DIR="$HOME/.ssh"
|
|
BACKUP_DIR="$HOME/dotfiles/backups/ssh"
|
|
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
|
|
# Colors
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
RED='\033[0;31m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
echo -e "${BLUE}SSH Keys Backup & Encryption${NC}"
|
|
echo "==============================="
|
|
|
|
# Check if SSH directory exists
|
|
if [ ! -d "$SSH_DIR" ]; then
|
|
echo -e "${RED}❌ SSH directory not found: $SSH_DIR${NC}"
|
|
exit 1
|
|
fi
|
|
|
|
# Check if GPG is available
|
|
if ! command -v gpg >/dev/null 2>&1; then
|
|
echo -e "${RED}❌ GPG not found. Please install GPG first.${NC}"
|
|
echo "Install with: brew install gnupg"
|
|
exit 1
|
|
fi
|
|
|
|
# Create backup directory
|
|
mkdir -p "$BACKUP_DIR"
|
|
|
|
echo -e "${YELLOW}🔍 Scanning SSH directory...${NC}"
|
|
|
|
# Find private keys (files without .pub extension and not config/known_hosts)
|
|
PRIVATE_KEYS=()
|
|
while IFS= read -r -d '' file; do
|
|
filename=$(basename "$file")
|
|
# Skip public keys, config files, and known_hosts
|
|
if [[ ! "$filename" =~ \.(pub|ppk)$ ]] && \
|
|
[[ "$filename" != "config" ]] && \
|
|
[[ "$filename" != "known_hosts" ]] && \
|
|
[[ "$filename" != "authorized_keys" ]]; then
|
|
PRIVATE_KEYS+=("$file")
|
|
fi
|
|
done < <(find "$SSH_DIR" -type f -print0)
|
|
|
|
if [ ${#PRIVATE_KEYS[@]} -eq 0 ]; then
|
|
echo -e "${YELLOW}⚠️ No private keys found to backup${NC}"
|
|
exit 0
|
|
fi
|
|
|
|
echo -e "${GREEN}Found ${#PRIVATE_KEYS[@]} private key(s):${NC}"
|
|
for key in "${PRIVATE_KEYS[@]}"; do
|
|
echo " • $(basename "$key")"
|
|
done
|
|
echo ""
|
|
|
|
# Ask for confirmation
|
|
read -p "Proceed with backup and encryption? (y/N) " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
echo "Backup cancelled."
|
|
exit 0
|
|
fi
|
|
|
|
# Create tarball of SSH directory
|
|
TEMP_TAR="/tmp/ssh_backup_${TIMESTAMP}.tar"
|
|
echo -e "${YELLOW}📦 Creating backup archive...${NC}"
|
|
|
|
# Create tar with only the files we want
|
|
tar -cf "$TEMP_TAR" -C "$HOME" .ssh/config 2>/dev/null || true
|
|
|
|
# Add private keys to tar
|
|
for key in "${PRIVATE_KEYS[@]}"; do
|
|
relative_path=$(echo "$key" | sed "s|$HOME/||")
|
|
tar -rf "$TEMP_TAR" -C "$HOME" "$relative_path" 2>/dev/null || true
|
|
echo " ✓ Added: $(basename "$key")"
|
|
done
|
|
|
|
# Add public keys corresponding to private keys
|
|
for key in "${PRIVATE_KEYS[@]}"; do
|
|
pub_key="${key}.pub"
|
|
if [ -f "$pub_key" ]; then
|
|
relative_path=$(echo "$pub_key" | sed "s|$HOME/||")
|
|
tar -rf "$TEMP_TAR" -C "$HOME" "$relative_path" 2>/dev/null || true
|
|
echo " ✓ Added: $(basename "$pub_key")"
|
|
fi
|
|
done
|
|
|
|
# Compress the tar
|
|
gzip "$TEMP_TAR"
|
|
TEMP_TAR="${TEMP_TAR}.gz"
|
|
|
|
# Encrypt with GPG
|
|
ENCRYPTED_FILE="$BACKUP_DIR/ssh_keys_${TIMESTAMP}.tar.gz.gpg"
|
|
|
|
echo -e "${YELLOW}🔐 Encrypting backup...${NC}"
|
|
echo "You will be prompted for a passphrase to encrypt the backup."
|
|
|
|
if gpg --symmetric --cipher-algo AES256 --compress-algo 1 --s2k-mode 3 \
|
|
--s2k-digest-algo SHA512 --s2k-count 65536 \
|
|
--output "$ENCRYPTED_FILE" "$TEMP_TAR"; then
|
|
|
|
# Clean up temporary file
|
|
rm "$TEMP_TAR"
|
|
|
|
echo -e "${GREEN}✅ SSH keys backup completed!${NC}"
|
|
echo ""
|
|
echo "Backup details:"
|
|
echo " 📁 Location: $ENCRYPTED_FILE"
|
|
echo " 📏 Size: $(du -h "$ENCRYPTED_FILE" | cut -f1)"
|
|
echo " 🔑 Encryption: AES256"
|
|
echo ""
|
|
|
|
# Create restore instructions
|
|
cat > "$BACKUP_DIR/RESTORE_INSTRUCTIONS.md" << EOF
|
|
# SSH Keys Restore Instructions
|
|
|
|
## Decrypting and Restoring SSH Keys
|
|
|
|
To restore from backup: \`ssh_keys_${TIMESTAMP}.tar.gz.gpg\`
|
|
|
|
### Step 1: Decrypt the backup
|
|
\`\`\`bash
|
|
gpg --decrypt ssh_keys_${TIMESTAMP}.tar.gz.gpg > ssh_keys_${TIMESTAMP}.tar.gz
|
|
\`\`\`
|
|
|
|
### Step 2: Extract the archive
|
|
\`\`\`bash
|
|
tar -xzf ssh_keys_${TIMESTAMP}.tar.gz -C ~/
|
|
\`\`\`
|
|
|
|
### Step 3: Set correct permissions
|
|
\`\`\`bash
|
|
chmod 700 ~/.ssh
|
|
chmod 600 ~/.ssh/config
|
|
chmod 600 ~/.ssh/*_key ~/.ssh/id_*
|
|
chmod 644 ~/.ssh/*.pub
|
|
\`\`\`
|
|
|
|
### Step 4: Add keys to SSH agent (if needed)
|
|
\`\`\`bash
|
|
ssh-add ~/.ssh/your_key_name
|
|
\`\`\`
|
|
|
|
## Security Notes
|
|
|
|
- Keep this encrypted backup in a secure location
|
|
- The backup contains your private keys - treat it as highly sensitive
|
|
- Consider storing a copy in a different location (cloud storage, external drive)
|
|
- Test the restore process periodically
|
|
|
|
## Backup Contents
|
|
|
|
This backup includes:
|
|
- SSH configuration file
|
|
- Private keys found in ~/.ssh/
|
|
- Corresponding public keys
|
|
- Proper directory structure
|
|
|
|
Created: $(date)
|
|
System: $(sw_vers -productVersion)
|
|
EOF
|
|
|
|
echo -e "${YELLOW}📋 Restore instructions created: $BACKUP_DIR/RESTORE_INSTRUCTIONS.md${NC}"
|
|
|
|
# Clean up old backups (keep last 5)
|
|
cd "$BACKUP_DIR"
|
|
ls -t ssh_keys_*.tar.gz.gpg 2>/dev/null | tail -n +6 | xargs -r rm
|
|
|
|
echo -e "${GREEN}🎉 Backup process complete!${NC}"
|
|
|
|
else
|
|
# Clean up on failure
|
|
rm -f "$TEMP_TAR"
|
|
echo -e "${RED}❌ Encryption failed!${NC}"
|
|
exit 1
|
|
fi |