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
This commit is contained in:
245
docs/gitea-ssh-migration-guide.md
Normal file
245
docs/gitea-ssh-migration-guide.md
Normal file
@@ -0,0 +1,245 @@
|
|||||||
|
# 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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
#!/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:**
|
||||||
|
```bash
|
||||||
|
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`:
|
||||||
|
```yaml
|
||||||
|
gitea_ssh_mode: "dedicated"
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
ansible-playbook -i inventory/hosts.yml rick-infra.yml --limit arch-vps
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Update Git Remotes
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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)
|
||||||
|
```bash
|
||||||
|
# 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)
|
||||||
|
```bash
|
||||||
|
# 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:
|
||||||
|
```bash
|
||||||
|
git remote -v
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Update if needed:
|
||||||
|
```bash
|
||||||
|
# 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:
|
||||||
|
```bash
|
||||||
|
# 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:
|
||||||
|
```bash
|
||||||
|
ssh-add -l # List loaded keys
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Try with explicit key:
|
||||||
|
```bash
|
||||||
|
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**:
|
||||||
|
```bash
|
||||||
|
# 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.
|
||||||
367
docs/service-domain-configuration.md
Normal file
367
docs/service-domain-configuration.md
Normal file
@@ -0,0 +1,367 @@
|
|||||||
|
# Service Domain Configuration Standard
|
||||||
|
|
||||||
|
Standard pattern for domain configuration in rick-infra service roles.
|
||||||
|
|
||||||
|
## Architecture Philosophy
|
||||||
|
|
||||||
|
Rick-infra follows a **direct domain specification** pattern for service configuration:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Direct and explicit
|
||||||
|
service_domain: "subdomain.jnss.me"
|
||||||
|
|
||||||
|
# NOT this (complex and inflexible)
|
||||||
|
service_subdomain: "subdomain"
|
||||||
|
service_domain: "{{ caddy_domain }}"
|
||||||
|
service_full_domain: "{{ service_subdomain }}.{{ service_domain }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
1. **Simplicity**: One variable instead of three
|
||||||
|
2. **Flexibility**: Can use any domain (subdomain, root, or completely different)
|
||||||
|
3. **Explicitness**: Clear what domain the service uses
|
||||||
|
4. **No Forced Inheritance**: Not tied to infrastructure `caddy_domain`
|
||||||
|
5. **Consistency**: All services follow the same pattern
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Standard Pattern
|
||||||
|
|
||||||
|
### Basic Service (Single Domain)
|
||||||
|
|
||||||
|
For services that only need one domain:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# roles/service/defaults/main.yml
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
|
||||||
|
# host_vars/host/main.yml (explicit override)
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Examples:**
|
||||||
|
- Authentik: `authentik_domain: "auth.jnss.me"`
|
||||||
|
- Nextcloud: `nextcloud_domain: "cloud.jnss.me"`
|
||||||
|
|
||||||
|
### Advanced Service (Multiple Domains)
|
||||||
|
|
||||||
|
For services that need separate domains for different purposes:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# roles/service/defaults/main.yml
|
||||||
|
service_http_domain: "service.jnss.me" # Web interface
|
||||||
|
service_api_domain: "api.jnss.me" # API endpoint
|
||||||
|
service_ssh_domain: "jnss.me" # SSH/CLI operations
|
||||||
|
|
||||||
|
# host_vars/host/main.yml (explicit override)
|
||||||
|
service_http_domain: "service.jnss.me"
|
||||||
|
service_api_domain: "api.jnss.me"
|
||||||
|
service_ssh_domain: "jnss.me"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Example:**
|
||||||
|
- Gitea:
|
||||||
|
- `gitea_http_domain: "git.jnss.me"` (web interface)
|
||||||
|
- `gitea_ssh_domain: "jnss.me"` (Git operations)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Usage in Templates
|
||||||
|
|
||||||
|
### Caddy Configuration
|
||||||
|
|
||||||
|
```jinja
|
||||||
|
# roles/service/templates/service.caddy.j2
|
||||||
|
{{ service_domain }} {
|
||||||
|
reverse_proxy 127.0.0.1:{{ service_port }}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Application Configuration
|
||||||
|
|
||||||
|
```jinja
|
||||||
|
# roles/service/templates/service.conf.j2
|
||||||
|
[server]
|
||||||
|
DOMAIN = {{ service_domain }}
|
||||||
|
ROOT_URL = https://{{ service_domain }}/
|
||||||
|
```
|
||||||
|
|
||||||
|
### Task Display Messages
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# roles/service/tasks/main.yml
|
||||||
|
- name: Display service information
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
🌐 Web Interface: https://{{ service_domain }}
|
||||||
|
📍 Access your service at the domain above
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Domain Selection Guidelines
|
||||||
|
|
||||||
|
### Use Root Domain When:
|
||||||
|
- Service is the primary purpose of the infrastructure
|
||||||
|
- You want cleaner URLs (e.g., SSH: `git@jnss.me` vs `git@git.jnss.me`)
|
||||||
|
- Industry standard uses root domain (e.g., GitHub uses `github.com` for SSH)
|
||||||
|
|
||||||
|
### Use Subdomain When:
|
||||||
|
- Service is one of many
|
||||||
|
- You want explicit service identification
|
||||||
|
- You need clear separation between services
|
||||||
|
|
||||||
|
### Use Different Domain When:
|
||||||
|
- Service needs to be on a different apex domain
|
||||||
|
- External service integration requires specific domain
|
||||||
|
- Multi-domain setup for geographical distribution
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Examples by Service Type
|
||||||
|
|
||||||
|
### Identity/Auth Service
|
||||||
|
```yaml
|
||||||
|
authentik_domain: "auth.jnss.me"
|
||||||
|
```
|
||||||
|
**Rationale**: Auth subdomain is an industry standard
|
||||||
|
|
||||||
|
### Storage Service
|
||||||
|
```yaml
|
||||||
|
nextcloud_domain: "cloud.jnss.me"
|
||||||
|
```
|
||||||
|
**Rationale**: "cloud" clearly indicates storage/sync service
|
||||||
|
|
||||||
|
### Git Service
|
||||||
|
```yaml
|
||||||
|
gitea_http_domain: "git.jnss.me" # Web UI
|
||||||
|
gitea_ssh_domain: "jnss.me" # SSH operations
|
||||||
|
```
|
||||||
|
**Rationale**:
|
||||||
|
- HTTP uses `git.` for clarity
|
||||||
|
- SSH uses root domain to avoid `git@git.jnss.me` redundancy
|
||||||
|
- Matches GitHub/GitLab pattern
|
||||||
|
|
||||||
|
### Monitoring Service
|
||||||
|
```yaml
|
||||||
|
grafana_domain: "monitor.jnss.me"
|
||||||
|
prometheus_domain: "metrics.jnss.me"
|
||||||
|
```
|
||||||
|
**Rationale**: Different subdomains for different monitoring tools
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration Layers
|
||||||
|
|
||||||
|
### 1. Role Defaults (`roles/service/defaults/main.yml`)
|
||||||
|
|
||||||
|
Provide sensible defaults:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Option A: Use specific domain (explicit)
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
|
||||||
|
# Option B: Use caddy_domain if it makes sense (flexible)
|
||||||
|
service_domain: "service.{{ caddy_domain | default('localhost') }}"
|
||||||
|
|
||||||
|
# Recommendation: Use Option A for clarity
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Host Variables (`host_vars/hostname/main.yml`)
|
||||||
|
|
||||||
|
**Always explicitly set** in production:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# =================================================================
|
||||||
|
# Service Configuration
|
||||||
|
# =================================================================
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Why explicit?**
|
||||||
|
- Clear what domain is configured
|
||||||
|
- Easy to change without understanding defaults
|
||||||
|
- Easier to audit configuration
|
||||||
|
- Documentation in configuration itself
|
||||||
|
|
||||||
|
### 3. Group Variables (`group_vars/production/main.yml`)
|
||||||
|
|
||||||
|
For settings shared across production hosts:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Common production settings
|
||||||
|
service_enable_ssl: true
|
||||||
|
service_require_auth: true
|
||||||
|
|
||||||
|
# Generally avoid setting domains in group_vars
|
||||||
|
# (domains are usually host-specific)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Anti-Patterns to Avoid
|
||||||
|
|
||||||
|
### ❌ Subdomain Composition
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# DON'T DO THIS
|
||||||
|
service_subdomain: "service"
|
||||||
|
service_domain: "{{ caddy_domain }}"
|
||||||
|
service_full_domain: "{{ service_subdomain }}.{{ service_domain }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problems:**
|
||||||
|
- Complex (3 variables for 1 domain)
|
||||||
|
- Inflexible (can't use root or different domains)
|
||||||
|
- Forces inheritance from infrastructure variable
|
||||||
|
- Inconsistent with other services
|
||||||
|
|
||||||
|
### ❌ Implicit Inheritance
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# DON'T DO THIS
|
||||||
|
service_domain: "{{ caddy_domain }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problems:**
|
||||||
|
- Not explicit what domain is used
|
||||||
|
- Harder to change
|
||||||
|
- Hides actual configuration
|
||||||
|
- Requires understanding of infrastructure variables
|
||||||
|
|
||||||
|
### ❌ Mixed Patterns
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# DON'T DO THIS
|
||||||
|
authentik_domain: "auth.jnss.me" # Direct
|
||||||
|
nextcloud_subdomain: "cloud" # Composition
|
||||||
|
service_domain: "{{ caddy_domain }}" # Inheritance
|
||||||
|
```
|
||||||
|
|
||||||
|
**Problems:**
|
||||||
|
- Inconsistent
|
||||||
|
- Confusing for maintainers
|
||||||
|
- Different patterns for same purpose
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Migration from Old Pattern
|
||||||
|
|
||||||
|
If you have services using the old subdomain composition pattern:
|
||||||
|
|
||||||
|
### Step 1: Identify Current Variables
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# Old pattern
|
||||||
|
service_subdomain: "service"
|
||||||
|
service_domain: "{{ caddy_domain }}"
|
||||||
|
service_full_domain: "{{ service_subdomain }}.{{ service_domain }}"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 2: Replace with Direct Domain
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# New pattern
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Update Template References
|
||||||
|
|
||||||
|
```jinja
|
||||||
|
# Old
|
||||||
|
{{ service_full_domain }}
|
||||||
|
|
||||||
|
# New
|
||||||
|
{{ service_domain }}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 4: Remove Unused Variables
|
||||||
|
|
||||||
|
Delete `service_subdomain` and `service_full_domain` from defaults.
|
||||||
|
|
||||||
|
### Step 5: Add Explicit Host Configuration
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
# host_vars/arch-vps/main.yml
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Testing Domain Configuration
|
||||||
|
|
||||||
|
### Verify Caddy Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check generated Caddy config
|
||||||
|
cat /etc/caddy/sites-enabled/service.caddy
|
||||||
|
|
||||||
|
# Test Caddy configuration syntax
|
||||||
|
caddy validate --config /etc/caddy/Caddyfile
|
||||||
|
|
||||||
|
# Check TLS certificate
|
||||||
|
curl -I https://service.jnss.me
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify Application Configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check service configuration
|
||||||
|
cat /etc/service/config.ini | grep -i domain
|
||||||
|
|
||||||
|
# Test service accessibility
|
||||||
|
curl https://service.jnss.me
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify DNS Resolution
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Check DNS resolution
|
||||||
|
dig service.jnss.me
|
||||||
|
|
||||||
|
# Test connectivity
|
||||||
|
nc -zv service.jnss.me 443
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Checklist for New Services
|
||||||
|
|
||||||
|
When creating a new service role:
|
||||||
|
|
||||||
|
- [ ] Use direct domain specification (not subdomain composition)
|
||||||
|
- [ ] Define domain(s) in `roles/service/defaults/main.yml`
|
||||||
|
- [ ] Add explicit domain(s) to host_vars
|
||||||
|
- [ ] Update all templates to use domain variable(s)
|
||||||
|
- [ ] Document domain configuration in role README
|
||||||
|
- [ ] Follow naming convention: `service_domain` or `service_[type]_domain`
|
||||||
|
- [ ] Test with different domain configurations
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Summary
|
||||||
|
|
||||||
|
**Standard Pattern:**
|
||||||
|
```yaml
|
||||||
|
# Defaults: Provide reasonable default
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
|
||||||
|
# Host vars: Always explicit in production
|
||||||
|
service_domain: "service.jnss.me"
|
||||||
|
|
||||||
|
# Templates: Use variable directly
|
||||||
|
{{ service_domain }}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Key Principles:**
|
||||||
|
1. Direct and explicit
|
||||||
|
2. One variable per domain
|
||||||
|
3. No forced inheritance
|
||||||
|
4. Consistent across all services
|
||||||
|
5. Flexible for any domain pattern
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Rick-Infra Domain Configuration Standard**
|
||||||
|
Simple, flexible, and consistent domain configuration for all services.
|
||||||
@@ -72,6 +72,12 @@ nextcloud_admin_password: "{{ vault_nextcloud_admin_password }}"
|
|||||||
nextcloud_service_enabled: true
|
nextcloud_service_enabled: true
|
||||||
nextcloud_service_state: "started"
|
nextcloud_service_state: "started"
|
||||||
|
|
||||||
|
# =================================================================
|
||||||
|
# Gitea Configuration
|
||||||
|
# =================================================================
|
||||||
|
gitea_http_domain: "git.jnss.me"
|
||||||
|
gitea_ssh_domain: "jnss.me"
|
||||||
|
|
||||||
# =================================================================
|
# =================================================================
|
||||||
# Security & Logging
|
# Security & Logging
|
||||||
# =================================================================
|
# =================================================================
|
||||||
|
|||||||
@@ -12,8 +12,8 @@
|
|||||||
- [ ] Contacts and calendars
|
- [ ] Contacts and calendars
|
||||||
- [ ] Storage bucket integration?
|
- [ ] Storage bucket integration?
|
||||||
|
|
||||||
- [ ] Gitea
|
- [x] Gitea
|
||||||
- [ ] SSH setup
|
- [x] SSH passthrough setup
|
||||||
|
|
||||||
- [ ] Authentik Invitations for users?
|
- [ ] Authentik Invitations for users?
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
# Usage:
|
# Usage:
|
||||||
# ansible-playbook playbooks/homelab.yml
|
# ansible-playbook playbooks/homelab.yml
|
||||||
|
|
||||||
- import_playbook: playbooks/security.yml
|
# - import_playbook: playbooks/security.yml
|
||||||
- name: Deploy Homelab Infrastructure
|
- name: Deploy Homelab Infrastructure
|
||||||
hosts: homelab
|
hosts: homelab
|
||||||
become: true
|
become: true
|
||||||
|
|||||||
@@ -8,8 +8,10 @@ Self-contained Gitea Git service for rick-infra following the established archit
|
|||||||
- ✅ **Native Arch installation**: Uses pacman packages
|
- ✅ **Native Arch installation**: Uses pacman packages
|
||||||
- ✅ **PostgreSQL integration**: Uses shared PostgreSQL infrastructure
|
- ✅ **PostgreSQL integration**: Uses shared PostgreSQL infrastructure
|
||||||
- ✅ **Caddy integration**: Deploys reverse proxy configuration
|
- ✅ **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
|
- ✅ **Security hardened**: SystemD restrictions and secure defaults
|
||||||
- ✅ **Firewall management**: Automatically configures nftables for SSH access
|
- ✅ **Firewall management**: Automatic nftables configuration per mode
|
||||||
- ✅ **fail2ban protection**: Brute force protection for SSH authentication
|
- ✅ **fail2ban protection**: Brute force protection for SSH authentication
|
||||||
- ✅ **Production ready**: HTTPS, SSH access, LFS support
|
- ✅ **Production ready**: HTTPS, SSH access, LFS support
|
||||||
|
|
||||||
@@ -17,11 +19,11 @@ Self-contained Gitea Git service for rick-infra following the established archit
|
|||||||
|
|
||||||
- **Dependencies**: PostgreSQL infrastructure role
|
- **Dependencies**: PostgreSQL infrastructure role
|
||||||
- **Database**: Self-managed gitea database and user
|
- **Database**: Self-managed gitea database and user
|
||||||
- **Network**: HTTP on :3000 (localhost), SSH on :2222 (public)
|
- **Network**: HTTP on :3000 (localhost), SSH via system SSH (port 22) or dedicated (port 2222)
|
||||||
- **Web access**: https://git.domain.com (via Caddy reverse proxy)
|
- **Web access**: https://git.jnss.me (via Caddy reverse proxy)
|
||||||
- **SSH access**: ssh://git@git.domain.com:2222
|
- **SSH access**: git@jnss.me:user/repo.git (passthrough mode, default)
|
||||||
- **Firewall**: Port 2222 automatically opened via nftables
|
- **Firewall**: Managed per SSH mode (no extra ports in passthrough)
|
||||||
- **Security**: fail2ban monitors and blocks SSH brute force attempts
|
- **Security**: fail2ban protects SSH authentication (system or dedicated jail)
|
||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
@@ -31,11 +33,13 @@ Key variables (defaults in `defaults/main.yml`):
|
|||||||
# Service
|
# Service
|
||||||
gitea_service_enabled: true
|
gitea_service_enabled: true
|
||||||
gitea_http_port: 3000
|
gitea_http_port: 3000
|
||||||
gitea_ssh_port: 2222
|
|
||||||
|
|
||||||
# Domain
|
# Domain Configuration
|
||||||
gitea_subdomain: "git"
|
gitea_http_domain: "git.jnss.me" # Web interface
|
||||||
gitea_domain: "{{ caddy_domain }}"
|
gitea_ssh_domain: "jnss.me" # SSH/Git operations
|
||||||
|
|
||||||
|
# SSH Mode
|
||||||
|
gitea_ssh_mode: "passthrough" # or "dedicated"
|
||||||
|
|
||||||
# Database (self-managed)
|
# Database (self-managed)
|
||||||
gitea_db_name: "gitea"
|
gitea_db_name: "gitea"
|
||||||
@@ -46,36 +50,108 @@ gitea_db_password: "{{ vault_gitea_db_password }}"
|
|||||||
gitea_app_name: "Gitea: Git with a cup of tea"
|
gitea_app_name: "Gitea: Git with a cup of tea"
|
||||||
gitea_disable_registration: false
|
gitea_disable_registration: false
|
||||||
gitea_enable_lfs: true
|
gitea_enable_lfs: true
|
||||||
|
|
||||||
# Firewall and Security
|
|
||||||
gitea_manage_firewall: true # Automatically manage nftables rules
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 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:**
|
||||||
|
```yaml
|
||||||
|
# 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
|
||||||
|
|
||||||
|
### Passthrough Mode (Default - Recommended)
|
||||||
|
|
||||||
|
System SSH handles Git operations via AuthorizedKeysCommand:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 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:**
|
||||||
|
```yaml
|
||||||
|
# host_vars/arch-vps/main.yml
|
||||||
|
gitea_ssh_mode: "dedicated" # or "passthrough"
|
||||||
|
```
|
||||||
|
Then re-run the playbook.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
1. **Add vault password**: Set `vault_gitea_db_password` in host_vars vault
|
1. **Add vault password**: Set `vault_gitea_db_password` in host_vars vault
|
||||||
2. **Deploy**: `ansible-playbook site.yml --tags gitea`
|
2. **Configure domains** (optional): Override `gitea_http_domain` and `gitea_ssh_domain` in host_vars
|
||||||
3. **Access**: Visit https://git.yourdomain.com to set up admin account
|
3. **Deploy**: `ansible-playbook site.yml --tags gitea`
|
||||||
|
4. **Access**: Visit https://git.jnss.me to set up admin account
|
||||||
|
|
||||||
## Dependencies
|
## SSH Key Setup
|
||||||
|
|
||||||
- PostgreSQL infrastructure role (auto-included)
|
|
||||||
- Caddy web server (for HTTPS access)
|
|
||||||
- Vault password: `vault_gitea_db_password`
|
|
||||||
|
|
||||||
## SSH Access
|
|
||||||
|
|
||||||
Gitea provides Git repository access via SSH on port 2222:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Clone a repository
|
|
||||||
git clone ssh://git@git.jnss.me:2222/username/repository.git
|
|
||||||
|
|
||||||
# Or add as remote
|
|
||||||
git remote add origin ssh://git@git.jnss.me:2222/username/repository.git
|
|
||||||
```
|
|
||||||
|
|
||||||
### SSH Key Setup
|
|
||||||
|
|
||||||
1. **Generate SSH key** (if you don't have one):
|
1. **Generate SSH key** (if you don't have one):
|
||||||
```bash
|
```bash
|
||||||
@@ -95,40 +171,52 @@ git remote add origin ssh://git@git.jnss.me:2222/username/repository.git
|
|||||||
|
|
||||||
4. **Test SSH connection**:
|
4. **Test SSH connection**:
|
||||||
```bash
|
```bash
|
||||||
ssh -T -p 2222 git@git.jnss.me
|
# Passthrough mode
|
||||||
|
ssh -T git@jnss.me
|
||||||
|
|
||||||
|
# Dedicated mode
|
||||||
|
ssh -T -p 2222 git@jnss.me
|
||||||
```
|
```
|
||||||
|
|
||||||
## Firewall and Security
|
## Firewall and Security
|
||||||
|
|
||||||
### Automatic Firewall Management
|
### Automatic Firewall Management
|
||||||
|
|
||||||
The Gitea role automatically manages firewall rules via nftables:
|
Firewall configuration is mode-aware:
|
||||||
|
|
||||||
- **Port 2222** is opened automatically when Gitea is deployed
|
**Passthrough Mode:**
|
||||||
- Firewall rules are stored in `/etc/nftables.d/gitea.nft`
|
- No extra firewall rules needed (uses port 22)
|
||||||
- Rules are integrated with the main security playbook configuration
|
- System SSH already configured in security playbook
|
||||||
- To disable automatic firewall management, set `gitea_manage_firewall: false`
|
|
||||||
|
**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
|
### fail2ban Protection
|
||||||
|
|
||||||
SSH brute force protection is automatically configured:
|
Protection is mode-aware:
|
||||||
|
|
||||||
- **Jail**: `gitea-ssh` monitors Gitea SSH authentication attempts
|
**Passthrough Mode:**
|
||||||
- **Max retries**: 5 failed attempts
|
- System `sshd` jail protects all SSH traffic (port 22)
|
||||||
- **Find time**: 10 minutes (600 seconds)
|
- Covers admin SSH + Git operations automatically
|
||||||
- **Ban time**: 1 hour (3600 seconds)
|
- No separate Gitea jail needed
|
||||||
- **Action**: IP banned via nftables
|
|
||||||
|
**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:
|
Check fail2ban status:
|
||||||
```bash
|
```bash
|
||||||
# Check Gitea SSH jail status
|
# Passthrough mode
|
||||||
|
fail2ban-client status sshd
|
||||||
|
|
||||||
|
# Dedicated mode
|
||||||
fail2ban-client status gitea-ssh
|
fail2ban-client status gitea-ssh
|
||||||
|
|
||||||
# View banned IPs
|
|
||||||
fail2ban-client get gitea-ssh banned
|
|
||||||
|
|
||||||
# Unban an IP if needed
|
|
||||||
fail2ban-client set gitea-ssh unbanip 203.0.113.100
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Firewall Verification
|
### Firewall Verification
|
||||||
@@ -137,13 +225,20 @@ fail2ban-client set gitea-ssh unbanip 203.0.113.100
|
|||||||
# List active nftables rules
|
# List active nftables rules
|
||||||
nft list ruleset
|
nft list ruleset
|
||||||
|
|
||||||
# Check if Gitea SSH port is open
|
# Check for Gitea SSH port (should be empty in passthrough)
|
||||||
nft list ruleset | grep 2222
|
nft list ruleset | grep 2222
|
||||||
|
|
||||||
# Verify from external machine
|
# Verify SSH connectivity
|
||||||
nc -zv git.jnss.me 2222
|
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
|
## Self-Contained Design
|
||||||
|
|
||||||
This role follows rick-infra's self-contained service pattern:
|
This role follows rick-infra's self-contained service pattern:
|
||||||
@@ -151,9 +246,18 @@ This role follows rick-infra's self-contained service pattern:
|
|||||||
- Manages its own configuration and data
|
- Manages its own configuration and data
|
||||||
- Deploys its own Caddy reverse proxy config
|
- Deploys its own Caddy reverse proxy config
|
||||||
- Manages its own firewall rules and security (nftables, fail2ban)
|
- Manages its own firewall rules and security (nftables, fail2ban)
|
||||||
|
- Flexible domain configuration (not tied to infrastructure variables)
|
||||||
- Independent lifecycle from other services
|
- 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**
|
**Rick-Infra Gitea Service**
|
||||||
Git repository management with integrated CI/CD capabilities.
|
Git repository management with flexible SSH modes and domain configuration.
|
||||||
|
|||||||
@@ -20,16 +20,14 @@ gitea_home: "/var/lib/gitea"
|
|||||||
|
|
||||||
# Network Configuration
|
# Network Configuration
|
||||||
gitea_http_port: 3000
|
gitea_http_port: 3000
|
||||||
gitea_ssh_port: 2222
|
|
||||||
|
|
||||||
# =================================================================
|
# =================================================================
|
||||||
# Domain and Caddy Integration
|
# Domain and Caddy Integration
|
||||||
# =================================================================
|
# =================================================================
|
||||||
|
|
||||||
# Domain setup (follows rick-infra pattern)
|
# Domain setup (follows rick-infra pattern)
|
||||||
gitea_subdomain: "git"
|
gitea_http_domain: "git.jnss.me"
|
||||||
gitea_domain: "{{ caddy_domain | default('localhost') }}"
|
gitea_ssh_domain: "jnss.me"
|
||||||
gitea_full_domain: "{{ gitea_subdomain }}.{{ gitea_domain }}"
|
|
||||||
|
|
||||||
# Caddy integration
|
# Caddy integration
|
||||||
caddy_sites_enabled_dir: "/etc/caddy/sites-enabled"
|
caddy_sites_enabled_dir: "/etc/caddy/sites-enabled"
|
||||||
@@ -63,15 +61,34 @@ gitea_enable_lfs: true
|
|||||||
gitea_disable_registration: false
|
gitea_disable_registration: false
|
||||||
gitea_require_signin: false
|
gitea_require_signin: false
|
||||||
|
|
||||||
# SSH settings
|
# =================================================================
|
||||||
gitea_start_ssh_server: true
|
# SSH Mode Configuration
|
||||||
|
# =================================================================
|
||||||
|
|
||||||
|
# SSH Mode: 'passthrough' or 'dedicated'
|
||||||
|
# - passthrough (default): Use system SSH on port 22
|
||||||
|
# * More secure (single SSH daemon, smaller attack surface)
|
||||||
|
# * Standard Git URLs (no :2222 port number needed)
|
||||||
|
# * System fail2ban automatically protects Git operations
|
||||||
|
# * Recommended for production use
|
||||||
|
#
|
||||||
|
# - dedicated (fallback): Run Gitea's built-in SSH server on port 2222
|
||||||
|
# * Complete isolation from system SSH
|
||||||
|
# * Independent configuration and restarts
|
||||||
|
# * Requires opening port 2222 in firewall
|
||||||
|
# * Useful for debugging or when passthrough causes issues
|
||||||
|
gitea_ssh_mode: "passthrough"
|
||||||
|
|
||||||
|
# Dynamic SSH configuration based on mode
|
||||||
|
gitea_ssh_port: "{{ 22 if gitea_ssh_mode == 'passthrough' else 2222 }}"
|
||||||
|
gitea_start_ssh_server: "{{ false if gitea_ssh_mode == 'passthrough' else true }}"
|
||||||
|
|
||||||
# =================================================================
|
# =================================================================
|
||||||
# Firewall Configuration
|
# Firewall Configuration
|
||||||
# =================================================================
|
# =================================================================
|
||||||
|
|
||||||
# Firewall management
|
# Firewall management (only opens port in dedicated mode)
|
||||||
gitea_manage_firewall: true # Set to false if firewall is managed externally
|
gitea_manage_firewall: "{{ true if gitea_ssh_mode == 'dedicated' else false }}"
|
||||||
|
|
||||||
# =================================================================
|
# =================================================================
|
||||||
# Infrastructure Dependencies (Read-only)
|
# Infrastructure Dependencies (Read-only)
|
||||||
@@ -91,4 +108,4 @@ postgresql_port: 5432
|
|||||||
# - Creates its own database and user
|
# - Creates its own database and user
|
||||||
# - Deploys Caddy configuration to sites-enabled
|
# - Deploys Caddy configuration to sites-enabled
|
||||||
# - Uses native Arch Linux Gitea package
|
# - Uses native Arch Linux Gitea package
|
||||||
# - Follows self-contained service pattern
|
# - Follows self-contained service pattern
|
||||||
|
|||||||
@@ -27,4 +27,11 @@
|
|||||||
- name: restart fail2ban
|
- name: restart fail2ban
|
||||||
systemd:
|
systemd:
|
||||||
name: fail2ban
|
name: fail2ban
|
||||||
state: restarted
|
state: restarted
|
||||||
|
|
||||||
|
- name: restart sshd
|
||||||
|
systemd:
|
||||||
|
name: sshd
|
||||||
|
state: restarted
|
||||||
|
# Safety: only restart if not running locally
|
||||||
|
when: ansible_connection != 'local'
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
---
|
---
|
||||||
# Gitea fail2ban Configuration - Rick-Infra
|
# Gitea fail2ban Configuration - Rick-Infra
|
||||||
# Protects Gitea SSH from brute force attacks
|
# Mode-aware: Only protects dedicated mode (port 2222)
|
||||||
# Integrates with system fail2ban service
|
# In passthrough mode, system 'sshd' jail protects port 22
|
||||||
|
|
||||||
- name: Install fail2ban
|
- name: Install fail2ban
|
||||||
pacman:
|
pacman:
|
||||||
@@ -13,6 +13,7 @@
|
|||||||
content: |
|
content: |
|
||||||
# Fail2ban filter for Gitea SSH authentication failures
|
# Fail2ban filter for Gitea SSH authentication failures
|
||||||
# Rick-Infra: Gitea role
|
# Rick-Infra: Gitea role
|
||||||
|
# Only used in dedicated mode (port {{ gitea_ssh_port }})
|
||||||
|
|
||||||
[Definition]
|
[Definition]
|
||||||
# Match failed authentication attempts in Gitea logs
|
# Match failed authentication attempts in Gitea logs
|
||||||
@@ -33,14 +34,17 @@
|
|||||||
modification_time: preserve
|
modification_time: preserve
|
||||||
access_time: preserve
|
access_time: preserve
|
||||||
|
|
||||||
- name: Add Gitea SSH jail to fail2ban
|
- name: Add Gitea SSH jail to fail2ban (mode-aware)
|
||||||
blockinfile:
|
blockinfile:
|
||||||
path: /etc/fail2ban/jail.local
|
path: /etc/fail2ban/jail.local
|
||||||
marker: "# {mark} ANSIBLE MANAGED BLOCK - Gitea SSH"
|
marker: "# {mark} ANSIBLE MANAGED BLOCK - Gitea SSH"
|
||||||
block: |
|
block: |
|
||||||
# Gitea SSH Protection - Rick-Infra
|
# Gitea SSH Protection - Rick-Infra
|
||||||
|
# Mode: {{ gitea_ssh_mode }}
|
||||||
|
# - dedicated: Monitors Gitea logs on port {{ gitea_ssh_port }}
|
||||||
|
# - passthrough: Disabled (system 'sshd' jail protects port 22)
|
||||||
[gitea-ssh]
|
[gitea-ssh]
|
||||||
enabled = true
|
enabled = {{ 'true' if gitea_ssh_mode == 'dedicated' else 'false' }}
|
||||||
port = {{ gitea_ssh_port }}
|
port = {{ gitea_ssh_port }}
|
||||||
filter = gitea-ssh
|
filter = gitea-ssh
|
||||||
logpath = {{ gitea_home }}/log/gitea.log
|
logpath = {{ gitea_home }}/log/gitea.log
|
||||||
@@ -57,19 +61,61 @@
|
|||||||
enabled: yes
|
enabled: yes
|
||||||
state: started
|
state: started
|
||||||
|
|
||||||
- name: Add fail2ban restart handler
|
- name: Flush handlers to ensure fail2ban restarts
|
||||||
meta: flush_handlers
|
meta: flush_handlers
|
||||||
|
|
||||||
- name: Display fail2ban status for Gitea
|
- name: Wait for fail2ban to be ready
|
||||||
|
pause:
|
||||||
|
seconds: 2
|
||||||
|
|
||||||
|
- name: Verify gitea-ssh jail status (dedicated mode only)
|
||||||
|
command: fail2ban-client status gitea-ssh
|
||||||
|
register: gitea_jail_verify
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
when: gitea_ssh_mode == 'dedicated'
|
||||||
|
|
||||||
|
- name: Verify sshd jail status (passthrough mode)
|
||||||
|
command: fail2ban-client status sshd
|
||||||
|
register: sshd_jail_verify
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
when: gitea_ssh_mode == 'passthrough'
|
||||||
|
|
||||||
|
- name: Display fail2ban configuration status
|
||||||
debug:
|
debug:
|
||||||
msg: |
|
msg: |
|
||||||
🛡️ fail2ban configured for Gitea SSH
|
🛡️ fail2ban Protection for Gitea SSH
|
||||||
📍 Filter: /etc/fail2ban/filter.d/gitea-ssh.conf
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
📍 Jail: gitea-ssh (in /etc/fail2ban/jail.local)
|
📍 Mode: {{ gitea_ssh_mode | upper }}
|
||||||
🔒 Protection: Port {{ gitea_ssh_port }}
|
|
||||||
⏱️ Ban time: 1 hour (3600 seconds)
|
|
||||||
🔢 Max retries: 5 attempts in 10 minutes
|
|
||||||
|
|
||||||
Check status: fail2ban-client status gitea-ssh
|
{% if gitea_ssh_mode == 'dedicated' %}
|
||||||
|
📍 Jail: gitea-ssh
|
||||||
|
📍 Port: {{ gitea_ssh_port }}
|
||||||
|
📍 Status: {{ 'Active ✅' if gitea_jail_verify.rc == 0 else 'Not Active ⚠️' }}
|
||||||
|
📍 Filter: /etc/fail2ban/filter.d/gitea-ssh.conf
|
||||||
|
📍 Logfile: {{ gitea_home }}/log/gitea.log
|
||||||
|
|
||||||
|
Protection Settings:
|
||||||
|
• Max retries: 5 attempts
|
||||||
|
• Find time: 10 minutes (600 seconds)
|
||||||
|
• Ban time: 1 hour (3600 seconds)
|
||||||
|
|
||||||
|
Check status:
|
||||||
|
fail2ban-client status gitea-ssh
|
||||||
|
|
||||||
|
{% else %}
|
||||||
|
📍 Jail: sshd (system jail)
|
||||||
|
📍 Port: 22
|
||||||
|
📍 Status: {{ 'Active ✅' if sshd_jail_verify.rc == 0 else 'Not Active ⚠️' }}
|
||||||
|
📍 Coverage: All SSH traffic including Gitea Git operations
|
||||||
|
|
||||||
|
Note: In passthrough mode, the system 'sshd' jail automatically
|
||||||
|
protects all SSH traffic on port 22, including Gitea Git
|
||||||
|
operations. No separate gitea-ssh jail is needed.
|
||||||
|
|
||||||
|
Check status:
|
||||||
|
fail2ban-client status sshd
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
# Rick-Infra: Self-contained fail2ban protection per role
|
# Rick-Infra: Self-contained fail2ban protection per role
|
||||||
|
|||||||
@@ -16,23 +16,30 @@
|
|||||||
name: gitea
|
name: gitea
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
# Firewall configuration - self-managed by Gitea role
|
# SSH Mode Configuration - Conditional based on gitea_ssh_mode
|
||||||
- name: Configure firewall for Gitea SSH
|
# Mode determines how Git SSH operations are handled
|
||||||
import_tasks: firewall.yml
|
|
||||||
tags: ['firewall']
|
|
||||||
when: gitea_manage_firewall | default(true)
|
|
||||||
|
|
||||||
# fail2ban protection - self-managed by Gitea role
|
- name: Configure SSH passthrough mode (default)
|
||||||
- name: Configure fail2ban for Gitea SSH
|
import_tasks: ssh_passthrough.yml
|
||||||
import_tasks: fail2ban.yml
|
when: gitea_ssh_mode == "passthrough"
|
||||||
tags: ['fail2ban', 'security']
|
tags: ['ssh', 'passthrough']
|
||||||
when: gitea_manage_firewall | default(true)
|
|
||||||
|
- name: Configure SSH dedicated mode (fallback)
|
||||||
|
import_tasks: ssh_dedicated.yml
|
||||||
|
when: gitea_ssh_mode == "dedicated"
|
||||||
|
tags: ['ssh', 'dedicated']
|
||||||
|
|
||||||
- name: Install Git
|
- name: Install Git
|
||||||
pacman:
|
pacman:
|
||||||
name: git
|
name: git
|
||||||
state: present
|
state: present
|
||||||
|
|
||||||
|
- name: Create Gitea group
|
||||||
|
group:
|
||||||
|
name: "{{ gitea_group }}"
|
||||||
|
system: yes
|
||||||
|
state: present
|
||||||
|
|
||||||
- name: Create Gitea user and group
|
- name: Create Gitea user and group
|
||||||
user:
|
user:
|
||||||
name: "{{ gitea_user }}"
|
name: "{{ gitea_user }}"
|
||||||
@@ -156,8 +163,8 @@
|
|||||||
msg: |
|
msg: |
|
||||||
✅ Gitea Git service deployed successfully!
|
✅ Gitea Git service deployed successfully!
|
||||||
|
|
||||||
🌐 Web Interface: https://{{ gitea_full_domain }}
|
🌐 Web Interface: https://{{ gitea_http_domain }}
|
||||||
🔗 SSH Clone: ssh://git@{{ gitea_full_domain }}:{{ gitea_ssh_port }}
|
🔗 SSH Clone: ssh://git@{{ gitea_ssh_domain }}:{{ gitea_ssh_port }}
|
||||||
📦 Local HTTP: http://127.0.0.1:{{ gitea_http_port }}
|
📦 Local HTTP: http://127.0.0.1:{{ gitea_http_port }}
|
||||||
🗄️ Database: {{ gitea_db_name }} (self-managed)
|
🗄️ Database: {{ gitea_db_name }} (self-managed)
|
||||||
|
|
||||||
|
|||||||
74
roles/gitea/tasks/ssh_dedicated.yml
Normal file
74
roles/gitea/tasks/ssh_dedicated.yml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
# Gitea Dedicated SSH Server Configuration - Rick-Infra
|
||||||
|
# Configures Gitea to run its own SSH server on port 2222
|
||||||
|
# This is the fallback mode when passthrough is not desired
|
||||||
|
|
||||||
|
- name: Configure firewall for Gitea SSH (dedicated mode)
|
||||||
|
import_tasks: firewall.yml
|
||||||
|
tags: ['firewall']
|
||||||
|
|
||||||
|
- name: Configure fail2ban for Gitea SSH (dedicated mode)
|
||||||
|
import_tasks: fail2ban.yml
|
||||||
|
tags: ['fail2ban', 'security']
|
||||||
|
|
||||||
|
- name: Wait for fail2ban to be ready
|
||||||
|
pause:
|
||||||
|
seconds: 2
|
||||||
|
|
||||||
|
- name: Verify gitea-ssh jail is active
|
||||||
|
command: fail2ban-client status gitea-ssh
|
||||||
|
register: gitea_jail_status
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Display fail2ban protection status
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
🛡️ Gitea SSH fail2ban protection:
|
||||||
|
{% if gitea_jail_status.rc == 0 %}
|
||||||
|
✅ gitea-ssh jail is ACTIVE
|
||||||
|
{{ gitea_jail_status.stdout }}
|
||||||
|
{% else %}
|
||||||
|
⚠️ WARNING: gitea-ssh jail not active!
|
||||||
|
This is a security risk - port {{ gitea_ssh_port }} is vulnerable to brute force attacks.
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- name: Fail if gitea-ssh jail is not running (security critical)
|
||||||
|
fail:
|
||||||
|
msg: |
|
||||||
|
SECURITY ERROR: gitea-ssh fail2ban jail is not active!
|
||||||
|
Port {{ gitea_ssh_port }} is exposed but not protected.
|
||||||
|
Check fail2ban configuration and logs.
|
||||||
|
when: gitea_jail_status.rc != 0
|
||||||
|
|
||||||
|
- name: Remove SSH passthrough configuration if present
|
||||||
|
blockinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
marker: "# {mark} ANSIBLE MANAGED BLOCK - Gitea SSH Passthrough"
|
||||||
|
state: absent
|
||||||
|
backup: yes
|
||||||
|
register: sshd_config_cleaned
|
||||||
|
notify: restart sshd
|
||||||
|
|
||||||
|
- name: Remove AuthorizedKeysCommand script if present
|
||||||
|
file:
|
||||||
|
path: /usr/local/bin/gitea-keys
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Display dedicated mode configuration
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
🔧 Gitea SSH Mode: DEDICATED
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
📍 SSH Server: Gitea built-in (port {{ gitea_ssh_port }})
|
||||||
|
🔗 Clone URL: ssh://git@{{ gitea_ssh_domain }}:{{ gitea_ssh_port }}/user/repo.git
|
||||||
|
🔥 Firewall: Port {{ gitea_ssh_port }} opened (nftables)
|
||||||
|
🛡️ fail2ban: gitea-ssh jail protecting port {{ gitea_ssh_port }}
|
||||||
|
|
||||||
|
Test connection:
|
||||||
|
ssh -T -p {{ gitea_ssh_port }} git@{{ gitea_ssh_domain }}
|
||||||
|
|
||||||
|
Clone repository:
|
||||||
|
git clone ssh://git@{{ gitea_ssh_domain }}:{{ gitea_ssh_port }}/username/repo.git
|
||||||
|
|
||||||
|
# Rick-Infra: Self-contained dedicated SSH mode with full security
|
||||||
128
roles/gitea/tasks/ssh_passthrough.yml
Normal file
128
roles/gitea/tasks/ssh_passthrough.yml
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
---
|
||||||
|
# Gitea SSH Passthrough Configuration - Rick-Infra
|
||||||
|
# Configures system SSH to handle Gitea Git authentication
|
||||||
|
# This is the default mode: more secure, standard Git URLs
|
||||||
|
|
||||||
|
- name: Ensure OpenSSH server is installed
|
||||||
|
pacman:
|
||||||
|
name: openssh
|
||||||
|
state: present
|
||||||
|
|
||||||
|
- name: Create Gitea AuthorizedKeysCommand script
|
||||||
|
template:
|
||||||
|
src: gitea-keys.sh.j2
|
||||||
|
dest: /usr/local/bin/gitea-keys
|
||||||
|
mode: '0755'
|
||||||
|
owner: root
|
||||||
|
group: root
|
||||||
|
register: gitea_keys_script
|
||||||
|
|
||||||
|
- name: Configure SSH for Gitea passthrough
|
||||||
|
blockinfile:
|
||||||
|
path: /etc/ssh/sshd_config
|
||||||
|
marker: "# {mark} ANSIBLE MANAGED BLOCK - Gitea SSH Passthrough"
|
||||||
|
block: |
|
||||||
|
# Gitea SSH Passthrough - Rick-Infra
|
||||||
|
# System SSH delegates git user authentication to Gitea
|
||||||
|
# This allows standard Git URLs: git@{{ gitea_ssh_domain }}:user/repo.git
|
||||||
|
Match User {{ gitea_user }}
|
||||||
|
AuthorizedKeysCommandUser {{ gitea_user }}
|
||||||
|
AuthorizedKeysCommand /usr/local/bin/gitea-keys %u %t %k
|
||||||
|
AllowTcpForwarding no
|
||||||
|
AllowAgentForwarding no
|
||||||
|
X11Forwarding no
|
||||||
|
PermitTTY no
|
||||||
|
backup: yes
|
||||||
|
validate: '/usr/bin/sshd -t -f %s'
|
||||||
|
register: sshd_config_changed
|
||||||
|
notify: restart sshd
|
||||||
|
|
||||||
|
- name: Verify SSH configuration syntax
|
||||||
|
command: sshd -t
|
||||||
|
changed_when: false
|
||||||
|
register: sshd_test
|
||||||
|
|
||||||
|
- name: Display SSH validation result
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
{% if sshd_test.rc == 0 %}
|
||||||
|
✅ SSH configuration is valid
|
||||||
|
{% else %}
|
||||||
|
⚠️ SSH configuration test failed:
|
||||||
|
{{ sshd_test.stderr }}
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
- name: Fail if SSH configuration is invalid
|
||||||
|
fail:
|
||||||
|
msg: "SSH configuration test failed. Rolling back changes."
|
||||||
|
when: sshd_test.rc != 0
|
||||||
|
|
||||||
|
- name: Remove Gitea firewall rule (passthrough uses port 22)
|
||||||
|
file:
|
||||||
|
path: /etc/nftables.d/50-gitea.nft
|
||||||
|
state: absent
|
||||||
|
notify: reload nftables
|
||||||
|
register: firewall_cleaned
|
||||||
|
|
||||||
|
- name: Reload nftables if firewall rule was removed
|
||||||
|
systemd:
|
||||||
|
name: nftables
|
||||||
|
state: reloaded
|
||||||
|
when: firewall_cleaned.changed
|
||||||
|
|
||||||
|
- name: Configure fail2ban for passthrough mode
|
||||||
|
import_tasks: fail2ban.yml
|
||||||
|
tags: ['fail2ban', 'security']
|
||||||
|
|
||||||
|
- name: Flush handlers to ensure sshd restarts if needed
|
||||||
|
meta: flush_handlers
|
||||||
|
|
||||||
|
- name: Wait for SSH service to be available after restart
|
||||||
|
wait_for:
|
||||||
|
port: 22
|
||||||
|
host: "{{ ansible_host | default('127.0.0.1') }}"
|
||||||
|
timeout: 30
|
||||||
|
delegate_to: localhost
|
||||||
|
become: false
|
||||||
|
when: sshd_config_changed.changed
|
||||||
|
|
||||||
|
- name: Test SSH connection after configuration
|
||||||
|
ping:
|
||||||
|
when: sshd_config_changed.changed
|
||||||
|
|
||||||
|
- name: Verify passthrough is working
|
||||||
|
command: sudo -u {{ gitea_user }} /usr/local/bin/gitea-keys ssh-rsa test
|
||||||
|
register: gitea_keys_test
|
||||||
|
changed_when: false
|
||||||
|
failed_when: false
|
||||||
|
|
||||||
|
- name: Display passthrough mode configuration
|
||||||
|
debug:
|
||||||
|
msg: |
|
||||||
|
🔧 Gitea SSH Mode: PASSTHROUGH (Default)
|
||||||
|
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
|
||||||
|
📍 SSH Server: System SSH (port 22)
|
||||||
|
🔗 Clone URL: git@{{ gitea_ssh_domain }}:user/repo.git
|
||||||
|
🔥 Firewall: Port 2222 closed (not needed)
|
||||||
|
🛡️ fail2ban: System 'sshd' jail protects all SSH traffic
|
||||||
|
🔑 AuthorizedKeysCommand: /usr/local/bin/gitea-keys
|
||||||
|
|
||||||
|
How it works:
|
||||||
|
1. User connects: ssh git@{{ gitea_ssh_domain }}
|
||||||
|
2. System SSH checks: /usr/local/bin/gitea-keys
|
||||||
|
3. Script queries Gitea database for SSH key
|
||||||
|
4. If authorized, Gitea handles Git operation
|
||||||
|
|
||||||
|
Test connection:
|
||||||
|
ssh -T git@{{ gitea_ssh_domain }}
|
||||||
|
|
||||||
|
Clone repository:
|
||||||
|
git clone git@{{ gitea_ssh_domain }}:username/repo.git
|
||||||
|
|
||||||
|
Benefits:
|
||||||
|
✅ Standard Git URLs (no :2222 port number)
|
||||||
|
✅ Single SSH daemon (smaller attack surface)
|
||||||
|
✅ System fail2ban protects everything
|
||||||
|
✅ One port to manage and monitor
|
||||||
|
|
||||||
|
# Rick-Infra: Self-contained SSH passthrough mode with enhanced security
|
||||||
@@ -11,14 +11,17 @@ DEFAULT_BRANCH = {{ gitea_default_branch }}
|
|||||||
|
|
||||||
[server]
|
[server]
|
||||||
PROTOCOL = http
|
PROTOCOL = http
|
||||||
DOMAIN = {{ gitea_full_domain }}
|
DOMAIN = {{ gitea_http_domain }}
|
||||||
HTTP_PORT = {{ gitea_http_port }}
|
HTTP_PORT = {{ gitea_http_port }}
|
||||||
ROOT_URL = https://{{ gitea_full_domain }}/
|
ROOT_URL = https://{{ gitea_http_domain }}/
|
||||||
DISABLE_SSH = false
|
DISABLE_SSH = false
|
||||||
|
# SSH Mode: {{ gitea_ssh_mode }}
|
||||||
START_SSH_SERVER = {{ gitea_start_ssh_server | lower }}
|
START_SSH_SERVER = {{ gitea_start_ssh_server | lower }}
|
||||||
SSH_DOMAIN = {{ gitea_full_domain }}
|
SSH_DOMAIN = {{ gitea_ssh_domain }}
|
||||||
SSH_PORT = {{ gitea_ssh_port }}
|
SSH_PORT = {{ gitea_ssh_port }}
|
||||||
|
{% if gitea_ssh_mode == 'dedicated' %}
|
||||||
SSH_LISTEN_PORT = {{ gitea_ssh_port }}
|
SSH_LISTEN_PORT = {{ gitea_ssh_port }}
|
||||||
|
{% endif %}
|
||||||
LOCAL_ROOT_URL = http://127.0.0.1:{{ gitea_http_port }}/
|
LOCAL_ROOT_URL = http://127.0.0.1:{{ gitea_http_port }}/
|
||||||
APP_DATA_PATH = {{ gitea_home }}/data
|
APP_DATA_PATH = {{ gitea_home }}/data
|
||||||
|
|
||||||
@@ -47,7 +50,7 @@ DISABLE_REGISTRATION = {{ gitea_disable_registration | lower }}
|
|||||||
REQUIRE_SIGNIN_VIEW = {{ gitea_require_signin | lower }}
|
REQUIRE_SIGNIN_VIEW = {{ gitea_require_signin | lower }}
|
||||||
DEFAULT_KEEP_EMAIL_PRIVATE = true
|
DEFAULT_KEEP_EMAIL_PRIVATE = true
|
||||||
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
DEFAULT_ALLOW_CREATE_ORGANIZATION = true
|
||||||
NO_REPLY_ADDRESS = noreply.{{ gitea_domain }}
|
NO_REPLY_ADDRESS = noreply@{{ gitea_http_domain }}
|
||||||
|
|
||||||
[log]
|
[log]
|
||||||
MODE = console
|
MODE = console
|
||||||
@@ -63,4 +66,4 @@ CONTENT_PATH = {{ gitea_home }}/data/lfs
|
|||||||
[git]
|
[git]
|
||||||
PATH = /usr/bin/git
|
PATH = /usr/bin/git
|
||||||
|
|
||||||
# Rick-Infra: Simplified Gitea configuration for self-contained service
|
# Rick-Infra: Simplified Gitea configuration for self-contained service
|
||||||
|
|||||||
28
roles/gitea/templates/gitea-keys.sh.j2
Normal file
28
roles/gitea/templates/gitea-keys.sh.j2
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# Gitea SSH Keys AuthorizedKeysCommand - Rick-Infra
|
||||||
|
# Generated by Ansible Gitea role
|
||||||
|
#
|
||||||
|
# This script is called by OpenSSH's AuthorizedKeysCommand to query
|
||||||
|
# Gitea's database for SSH public keys when the 'git' user connects.
|
||||||
|
#
|
||||||
|
# Called by SSH with parameters:
|
||||||
|
# %u = username (should be "git")
|
||||||
|
# %t = key type (ssh-rsa, ssh-ed25519, ecdsa-sha2-nistp256, etc.)
|
||||||
|
# %k = base64 encoded public key content
|
||||||
|
#
|
||||||
|
# The script returns authorized_keys format entries that include
|
||||||
|
# forced commands to execute Gitea's Git server.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
# Gitea keys command queries the database and returns authorized_keys format
|
||||||
|
# If the key is found, it returns a line like:
|
||||||
|
# command="/usr/bin/gitea serv key-123",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAA...
|
||||||
|
|
||||||
|
exec /usr/bin/gitea keys \
|
||||||
|
--config /etc/gitea/app.ini \
|
||||||
|
--username "$1" \
|
||||||
|
--type "$2" \
|
||||||
|
--content "$3"
|
||||||
|
|
||||||
|
# Rick-Infra: AuthorizedKeysCommand for Gitea SSH passthrough mode
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
# Generated by Ansible Gitea role
|
# Generated by Ansible Gitea role
|
||||||
# Deployed to {{ caddy_sites_enabled_dir }}/gitea.caddy
|
# Deployed to {{ caddy_sites_enabled_dir }}/gitea.caddy
|
||||||
|
|
||||||
{{ gitea_full_domain }} {
|
{{ gitea_http_domain }} {
|
||||||
# Reverse proxy to Gitea
|
# Reverse proxy to Gitea
|
||||||
reverse_proxy 127.0.0.1:{{ gitea_http_port }}
|
reverse_proxy 127.0.0.1:{{ gitea_http_port }}
|
||||||
|
|
||||||
@@ -29,4 +29,4 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Rick-Infra: Self-contained Gitea service with Caddy reverse proxy
|
# Rick-Infra: Self-contained Gitea service with Caddy reverse proxy
|
||||||
|
|||||||
Reference in New Issue
Block a user