Add SSH key backup script and fix git config
- 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>
This commit is contained in:
co-authored by
Claude
parent
0838f1cf8c
commit
8bddc004a7
+14
@@ -0,0 +1,14 @@
|
||||
# This is Git's per-user configuration file.
|
||||
[user]
|
||||
name = David F Glidden
|
||||
email = d@davidglidden.eu
|
||||
# Please adapt and uncomment the following lines:
|
||||
# name = David GLIDDEN
|
||||
# email = davidglidden@Macintosh.home
|
||||
[filter "lfs"]
|
||||
clean = git-lfs clean -- %f
|
||||
smudge = git-lfs smudge -- %f
|
||||
process = git-lfs filter-process
|
||||
required = true
|
||||
[url "git@github.com:"]
|
||||
insteadOf = https://github.com/
|
||||
Executable
+182
@@ -0,0 +1,182 @@
|
||||
#!/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
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/env bash
|
||||
# Setup GitHub and Gitea remotes using SSH
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
RED='\033[0;31m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}Setting up Git remotes with SSH${NC}"
|
||||
echo "=================================="
|
||||
|
||||
cd ~/dotfiles
|
||||
|
||||
# Get GitHub username
|
||||
echo -e "${YELLOW}What's your GitHub username?${NC}"
|
||||
read -p "GitHub username: " GITHUB_USER
|
||||
|
||||
# Get Gitea details (optional)
|
||||
echo ""
|
||||
echo -e "${YELLOW}Gitea setup (optional - press Enter to skip):${NC}"
|
||||
read -p "Gitea server URL (e.g., git.yourdomain.com): " GITEA_SERVER
|
||||
if [ -n "$GITEA_SERVER" ]; then
|
||||
read -p "Gitea username: " GITEA_USER
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Setting up remotes...${NC}"
|
||||
|
||||
# Add GitHub remote
|
||||
if ! git remote get-url github >/dev/null 2>&1; then
|
||||
git remote add github git@github.com:${GITHUB_USER}/dotfiles.git
|
||||
echo -e "${GREEN}✓ Added GitHub remote${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}GitHub remote already exists${NC}"
|
||||
fi
|
||||
|
||||
# Add Gitea remote if provided
|
||||
if [ -n "$GITEA_SERVER" ] && [ -n "$GITEA_USER" ]; then
|
||||
if ! git remote get-url gitea >/dev/null 2>&1; then
|
||||
git remote add gitea git@${GITEA_SERVER}:${GITEA_USER}/dotfiles.git
|
||||
echo -e "${GREEN}✓ Added Gitea remote${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}Gitea remote already exists${NC}"
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Manual steps required:${NC}"
|
||||
echo ""
|
||||
echo "1. 📋 Create repositories manually:"
|
||||
echo " • GitHub: https://github.com/new"
|
||||
echo " - Repository name: dotfiles"
|
||||
echo " - Description: 🖖 Complete macOS dotfiles system - 'Engage!'"
|
||||
echo " - Public repository"
|
||||
echo " - Don't initialize with README, .gitignore, or license"
|
||||
|
||||
if [ -n "$GITEA_SERVER" ]; then
|
||||
echo " • Gitea: https://${GITEA_SERVER}/repo/create"
|
||||
echo " - Repository name: dotfiles"
|
||||
echo " - Description: 🖖 Complete macOS dotfiles system - 'Engage!'"
|
||||
echo " - Public repository"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "2. 🔑 Test SSH access:"
|
||||
echo " ssh -T git@github.com"
|
||||
if [ -n "$GITEA_SERVER" ]; then
|
||||
echo " ssh -T git@${GITEA_SERVER}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "3. 🚀 Push to remotes:"
|
||||
echo " git push -u github master"
|
||||
if [ -n "$GITEA_SERVER" ]; then
|
||||
echo " git push -u gitea master"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Remote setup complete!${NC}"
|
||||
echo ""
|
||||
echo "Your repositories will be available at:"
|
||||
echo "• GitHub: https://github.com/${GITHUB_USER}/dotfiles"
|
||||
if [ -n "$GITEA_SERVER" ]; then
|
||||
echo "• Gitea: https://${GITEA_SERVER}/${GITEA_USER}/dotfiles"
|
||||
fi
|
||||
echo ""
|
||||
echo -e "${BLUE}Clone command for new machines:${NC}"
|
||||
echo "git clone git@github.com:${GITHUB_USER}/dotfiles.git ~/dotfiles && ~/dotfiles/engage"
|
||||
Executable
+61
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
# Setup GitHub and Gitea remotes for dotfiles repository
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# Colors
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
echo -e "${BLUE}Setting up Git remotes for dotfiles repository${NC}"
|
||||
echo "=============================================="
|
||||
|
||||
cd ~/dotfiles
|
||||
|
||||
# Check if we have gh CLI
|
||||
if ! command -v gh >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW}GitHub CLI (gh) not found. Please install it first: brew install gh${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if logged into GitHub
|
||||
if ! gh auth status >/dev/null 2>&1; then
|
||||
echo -e "${YELLOW}Please login to GitHub first: gh auth login${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}Creating GitHub repository...${NC}"
|
||||
|
||||
# Create GitHub repository
|
||||
gh repo create dotfiles --public --description "🖖 Complete macOS dotfiles system - From zero to fully configured in minutes. 'Engage!'" --homepage ""
|
||||
|
||||
# Add GitHub remote
|
||||
git remote add github https://github.com/$(gh api user --jq .login)/dotfiles.git
|
||||
|
||||
echo -e "${GREEN}✓ GitHub repository created${NC}"
|
||||
|
||||
# Push to GitHub
|
||||
echo -e "${YELLOW}Pushing to GitHub...${NC}"
|
||||
git push -u github master
|
||||
|
||||
echo -e "${GREEN}✓ Pushed to GitHub${NC}"
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Gitea Setup${NC}"
|
||||
echo "For Gitea, you'll need to:"
|
||||
echo "1. Create repository manually on your Gitea instance"
|
||||
echo "2. Add the remote:"
|
||||
echo " git remote add gitea https://your-gitea-instance.com/username/dotfiles.git"
|
||||
echo "3. Push to Gitea:"
|
||||
echo " git push -u gitea master"
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}Setup complete! 🎉${NC}"
|
||||
echo ""
|
||||
echo "Repository URLs:"
|
||||
echo "• GitHub: https://github.com/$(gh api user --jq .login)/dotfiles"
|
||||
echo "• Clone command: git clone https://github.com/$(gh api user --jq .login)/dotfiles.git ~/dotfiles && ~/dotfiles/engage"
|
||||
echo ""
|
||||
echo -e "${BLUE}Your 'engage' command is ready for the world! 🖖${NC}"
|
||||
Reference in New Issue
Block a user