Files
rick-infra/docs/gitea-ssh-migration-guide.md
Joakim cf71fb3a8d Implement SSH passthrough mode and refactor Gitea domain configuration
Major Changes:
- Add dual SSH mode system (passthrough default, dedicated fallback)
- Refactor domain configuration to use direct specification pattern
- Fix critical fail2ban security gap in dedicated mode
- Separate HTTP and SSH domains for cleaner Git URLs
2025-12-17 21:51:24 +01:00

5.6 KiB
Raw Blame History

Gitea SSH Migration Guide

Guide for migrating between Gitea SSH modes and updating Git remote URLs.

SSH Modes Overview

Passthrough Mode (Default)

  • Port: 22 (standard SSH)
  • URL Format: git@git.jnss.me:user/repo.git
  • Security: System fail2ban protects all SSH traffic
  • Recommended: For production use

Dedicated Mode (Fallback)

  • Port: 2222 (Gitea SSH server)
  • URL Format: ssh://git@git.jnss.me:2222/user/repo.git
  • Security: Separate fail2ban jail for port 2222
  • Use Case: Debugging or when passthrough has issues

Migration: Dedicated → Passthrough (Default)

When you deploy the new code, Gitea will automatically switch to passthrough mode.

What Happens Automatically

  1. Gitea's SSH server stops listening on port 2222
  2. Port 2222 firewall rule removed
  3. System SSH configured for Git passthrough
  4. AuthorizedKeysCommand script deployed
  5. fail2ban switches to system sshd jail

What You Need to Do

Update your Git remote URLs in each repository:

# Check current remote URL
git remote -v

# Update to new format (no port number)
git remote set-url origin git@git.jnss.me:username/repo.git

# Verify new URL
git remote -v

# Test connection
git fetch

Bulk Update Script

If you have many repositories, use this script:

#!/bin/bash
# migrate-git-urls.sh - Update all Git remotes from dedicated to passthrough

# Find all git repositories in current directory and subdirectories
find . -type d -name '.git' | while read gitdir; do
    repo=$(dirname "$gitdir")
    echo "Processing: $repo"
    
    cd "$repo"
    
    # Get current origin URL
    current_url=$(git remote get-url origin 2>/dev/null)
    
    # Check if it's the old format (with :2222)
    if [[ $current_url == *":2222/"* ]]; then
        # Convert to new format
        new_url=$(echo "$current_url" | sed 's|ssh://git@git.jnss.me:2222/|git@git.jnss.me:|')
        
        echo "  Old: $current_url"
        echo "  New: $new_url"
        
        git remote set-url origin "$new_url"
        echo "  ✅ Updated"
    else
        echo "    Already using correct format or not Gitea"
    fi
    
    cd - > /dev/null
    echo ""
done

echo "Migration complete!"

Usage:

chmod +x migrate-git-urls.sh
./migrate-git-urls.sh

Migration: Passthrough → Dedicated

If you need to switch back to dedicated mode:

1. Update Configuration

Edit host_vars/arch-vps/main.yml:

gitea_ssh_mode: "dedicated"

2. Deploy

ansible-playbook -i inventory/hosts.yml rick-infra.yml --limit arch-vps

3. Update Git Remotes

# Update to dedicated format (with :2222 port)
git remote set-url origin ssh://git@git.jnss.me:2222/username/repo.git

# Test connection
ssh -T -p 2222 git@git.jnss.me
git fetch

URL Format Reference

Passthrough Mode (Port 22)

# Clone
git clone git@git.jnss.me:username/repo.git

# Add remote
git remote add origin git@git.jnss.me:username/repo.git

# SSH test
ssh -T git@git.jnss.me

Dedicated Mode (Port 2222)

# Clone
git clone ssh://git@git.jnss.me:2222/username/repo.git

# Add remote
git remote add origin ssh://git@git.jnss.me:2222/username/repo.git

# SSH test
ssh -T -p 2222 git@git.jnss.me

Troubleshooting

After Migration, Git Operations Fail

Symptom: git push fails with "Permission denied" or "Connection refused"

Solution:

  1. Check your remote URL format:

    git remote -v
    
  2. Update if needed:

    # For passthrough (no port)
    git remote set-url origin git@git.jnss.me:username/repo.git
    
    # For dedicated (with port)
    git remote set-url origin ssh://git@git.jnss.me:2222/username/repo.git
    
  3. Test SSH connection:

    # Passthrough
    ssh -T git@git.jnss.me
    
    # Dedicated
    ssh -T -p 2222 git@git.jnss.me
    

SSH Key Not Recognized After Migration

Symptom: "Permission denied (publickey)"

Cause: SSH keys are stored in Gitea's database, not affected by mode change.

Solution:

  1. Verify your SSH key is in Gitea:

    • Log into Gitea web interface
    • Go to Settings → SSH/GPG Keys
    • Check your key is listed
  2. Test key locally:

    ssh-add -l  # List loaded keys
    
  3. Try with explicit key:

    ssh -T -i ~/.ssh/id_ed25519 git@git.jnss.me
    

Port 2222 Still Open After Switching to Passthrough

Symptom: nc -zv git.jnss.me 2222 succeeds

Cause: Gitea service may still be running on port 2222

Solution:

# On the server
systemctl restart gitea
ss -tlnp | grep 2222  # Should show nothing

Verification Checklist

After migration, verify:

  • SSH connection works: ssh -T git@git.jnss.me (passthrough) or ssh -T -p 2222 git@git.jnss.me (dedicated)
  • Can clone repository with new URL format
  • Can push commits to repository
  • fail2ban is active: fail2ban-client status sshd (passthrough) or fail2ban-client status gitea-ssh (dedicated)
  • Firewall configured correctly: nft list ruleset | grep 2222 (should show nothing in passthrough)

Notes

  • Both modes are fully supported - choose what works best for your setup
  • No data loss - repositories, users, and SSH keys are unaffected by mode changes
  • Gradual migration - you can update remote URLs at your own pace (old URLs may still work for a short time)
  • Team coordination - if you're in a team, coordinate the migration so everyone updates their URLs

Rick-Infra Gitea SSH Migration Guide
Switch between passthrough and dedicated SSH modes safely.