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
368 lines
8.0 KiB
Markdown
368 lines
8.0 KiB
Markdown
# 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.
|