Files

Gitea Git Service Role

Self-contained Gitea Git service for rick-infra following the established architectural patterns.

Features

  • Self-contained: Manages its own database and configuration
  • Native Arch installation: Uses pacman packages
  • PostgreSQL integration: Uses shared PostgreSQL infrastructure
  • Caddy integration: Deploys reverse proxy configuration
  • Dual SSH modes: Passthrough (default) or dedicated SSH server
  • Flexible domains: Separate HTTP and SSH domains
  • Security hardened: SystemD restrictions and secure defaults
  • Firewall management: Automatic nftables configuration per mode
  • fail2ban protection: Brute force protection for SSH authentication
  • Production ready: HTTPS, SSH access, LFS support

Architecture

  • Dependencies: PostgreSQL infrastructure role
  • Database: Self-managed gitea database and user
  • Network: HTTP on :3000 (localhost), SSH via system SSH (port 22) or dedicated (port 2222)
  • Web access: https://git.jnss.me (via Caddy reverse proxy)
  • SSH access: git@jnss.me:user/repo.git (passthrough mode, default)
  • Firewall: Managed per SSH mode (no extra ports in passthrough)
  • Security: fail2ban protects SSH authentication (system or dedicated jail)

Configuration

Key variables (defaults in defaults/main.yml):

# Service
gitea_service_enabled: true
gitea_http_port: 3000

# Domain Configuration
gitea_http_domain: "git.jnss.me"  # Web interface
gitea_ssh_domain: "jnss.me"       # SSH/Git operations

# SSH Mode
gitea_ssh_mode: "passthrough"  # or "dedicated"

# Database (self-managed)
gitea_db_name: "gitea"
gitea_db_user: "gitea" 
gitea_db_password: "{{ vault_gitea_db_password }}"

# Application
gitea_app_name: "Gitea: Git with a cup of tea"
gitea_disable_registration: false
gitea_enable_lfs: true

Domain Configuration

Gitea uses separate domains for HTTP and SSH access, providing flexibility and cleaner URLs:

HTTP Domain (gitea_http_domain)

  • Purpose: Web interface access
  • Default: git.jnss.me
  • Example: https://git.jnss.me
  • Used for: Browsing repos, managing settings, viewing commits

SSH Domain (gitea_ssh_domain)

  • Purpose: Git clone/push/pull operations
  • Default: jnss.me (root domain)
  • Example: git@jnss.me:user/repo.git
  • Used for: Git operations over SSH

Why Separate Domains?

  • Cleaner SSH URLs (no redundant "git" subdomain)
  • Flexibility to use completely different domains
  • Matches industry standards (GitHub, GitLab use root domain for SSH)
  • Professional appearance

Configuration Examples:

# Standard setup (recommended)
gitea_http_domain: "git.jnss.me"
gitea_ssh_domain: "jnss.me"
# Result: git@jnss.me:user/repo.git

# Same domain for both
gitea_http_domain: "git.jnss.me"
gitea_ssh_domain: "git.jnss.me"
# Result: git@git.jnss.me:user/repo.git

# Completely custom
gitea_http_domain: "code.jnss.me"
gitea_ssh_domain: "git.example.com"
# Result: git@git.example.com:user/repo.git

SSH Modes

System SSH handles Git operations via AuthorizedKeysCommand:

# Clone repository (standard Git URL, no port number)
git clone git@jnss.me:username/repository.git

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

# Test SSH connection
ssh -T git@jnss.me

Features:

  • Standard Git URLs (no :2222 port)
  • Single SSH daemon (smaller attack surface)
  • System fail2ban protects everything
  • Port 22 only (no extra firewall rules)
  • Matches GitHub/GitLab pattern

Dedicated Mode (Fallback)

Gitea runs its own SSH server on port 2222:

# Clone repository (with port number)
git clone ssh://git@jnss.me:2222/username/repository.git

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

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

Features:

  • Complete isolation from system SSH
  • Independent configuration
  • ⚠️ Requires port 2222 open in firewall
  • ⚠️ Non-standard URLs (requires :2222)

To switch modes:

# host_vars/arch-vps/main.yml
gitea_ssh_mode: "dedicated"  # or "passthrough"

Then re-run the playbook.

Usage

  1. Add vault password: Set vault_gitea_db_password in host_vars vault
  2. Configure domains (optional): Override gitea_http_domain and gitea_ssh_domain in host_vars
  3. Deploy: ansible-playbook site.yml --tags gitea
  4. Access: Visit https://git.jnss.me to set up admin account

SSH Key Setup

  1. Generate SSH key (if you don't have one):

    ssh-keygen -t ed25519 -C "your_email@example.com"
    
  2. Copy your public key:

    cat ~/.ssh/id_ed25519.pub
    
  3. Add to Gitea:

    • Log into Gitea web interface
    • Go to Settings → SSH/GPG Keys
    • Click "Add Key"
    • Paste your public key
  4. Test SSH connection:

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

Firewall and Security

Automatic Firewall Management

Firewall configuration is mode-aware:

Passthrough Mode:

  • No extra firewall rules needed (uses port 22)
  • System SSH already configured in security playbook

Dedicated Mode:

  • Port 2222 automatically opened via nftables
  • Firewall rules stored in /etc/nftables.d/50-gitea.nft
  • Rules integrated with main security playbook
  • Automatically removed when switching to passthrough

fail2ban Protection

Protection is mode-aware:

Passthrough Mode:

  • System sshd jail protects all SSH traffic (port 22)
  • Covers admin SSH + Git operations automatically
  • No separate Gitea jail needed

Dedicated Mode:

  • gitea-ssh jail monitors Gitea logs (port 2222)
  • Max retries: 5 failed attempts
  • Find time: 10 minutes (600 seconds)
  • Ban time: 1 hour (3600 seconds)
  • Action: IP banned via nftables

Check fail2ban status:

# Passthrough mode
fail2ban-client status sshd

# Dedicated mode
fail2ban-client status gitea-ssh

Firewall Verification

# List active nftables rules
nft list ruleset

# Check for Gitea SSH port (should be empty in passthrough)
nft list ruleset | grep 2222

# Verify SSH connectivity
nc -zv jnss.me 22          # Passthrough
nc -zv jnss.me 2222        # Dedicated

Dependencies

  • PostgreSQL infrastructure role (auto-included)
  • Caddy web server (for HTTPS access)
  • Vault password: vault_gitea_db_password

Self-Contained Design

This role follows rick-infra's self-contained service pattern:

  • Creates its own database and user via PostgreSQL infrastructure
  • Manages its own configuration and data
  • Deploys its own Caddy reverse proxy config
  • Manages its own firewall rules and security (nftables, fail2ban)
  • Flexible domain configuration (not tied to infrastructure variables)
  • Independent lifecycle from other services

Migration Guide

See docs/gitea-ssh-migration-guide.md for:

  • Switching between SSH modes
  • Updating Git remote URLs
  • Bulk migration scripts
  • Troubleshooting

Rick-Infra Gitea Service
Git repository management with flexible SSH modes and domain configuration.