Files
rick-infra/roles/gitea
Joakim 90bbcd97b1 Add Gitea email configuration and document SMTP authentication troubleshooting
Changes:
- Configure Gitea mailer with Titan Email SMTP settings
- Add SMTP_AUTH = PLAIN for authentication method specification
- Update SMTP password in vault (vault_gitea_smtp_password)

Email Status:
Currently non-functional due to SMTP authentication rejection by Titan Email
servers. Error: 535 5.7.8 authentication failed

Troubleshooting Performed:
- Tested both port 587 (STARTTLS) and 465 (SSL/TLS)
- Verified credentials work in webmail
- Tested AUTH PLAIN and AUTH LOGIN methods
- Removed conflicting TLS settings
- Both authentication methods rejected despite correct credentials

Root Cause:
The issue is NOT a Gitea configuration problem. Titan Email SMTP server
is rejecting all authentication attempts from the VPS (69.62.119.31)
despite credentials being correct and working in webmail.

Possible causes:
- SMTP access may need to be enabled in Hostinger control panel
- VPS IP may require whitelisting
- Account may need additional verification for SMTP access
- Titan Email plan may not include external SMTP access

Documentation:
Created comprehensive troubleshooting guide at:
docs/gitea-email-troubleshooting.md

Files Modified:
- roles/gitea/templates/app.ini.j2 (+1 line: SMTP_AUTH = PLAIN)
- docs/gitea-email-troubleshooting.md (new file, complete troubleshooting log)
- host_vars/arch-vps/vault.yml (updated SMTP password - not committed)

Next Steps:
- Check Hostinger control panel for SMTP/IMAP access toggle
- Test SMTP from different IP to rule out IP blocking
- Contact Hostinger/Titan support for SMTP access verification
- Consider alternative email providers if Titan SMTP unavailable
2025-12-19 21:25:14 +01:00
..

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.