Service cards now have: - Public/Private toggle (switches reach) - Subdomains toggle (include *.domain) - TLS badge (passthrough vs terminate, read-only for now) - Inline status details (DNS, Proxy, TLS status) - Deregister button - Add Service form with toggles instead of dropdowns The card speaks the user's language (public/private, subdomains on/off) not implementation details (tcp-passthrough vs http, reach: internal). Also updated docs/registrations.md: - Added "User-facing concepts" section mapping API fields to toggles - Added batch deregister endpoint - Added backend.health field - Cleaner examples Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
120 lines
4.5 KiB
Markdown
120 lines
4.5 KiB
Markdown
# Service Registrations
|
|
|
|
Wild Central provides DNS, proxy routing, TLS, and DDNS for services on the LAN. External consumers (Wild Cloud, Wild Works) register their domains with Central's API, and Central handles the networking.
|
|
|
|
## Registration API
|
|
|
|
```
|
|
POST /api/v1/services Register a domain
|
|
GET /api/v1/services List all registrations
|
|
GET /api/v1/services/{domain} Get registration details
|
|
PATCH /api/v1/services/{domain} Update a registration
|
|
DELETE /api/v1/services/{domain} Remove a registration
|
|
DELETE /api/v1/services/deregister?source=X&backend=Y Batch cleanup
|
|
```
|
|
|
|
The domain is the unique key. One registration per domain.
|
|
|
|
## Fields
|
|
|
|
| Field | Type | Required | Default | Description |
|
|
|-------|------|----------|---------|-------------|
|
|
| `domain` | string | yes | — | FQDN to route. Unique key. |
|
|
| `source` | string | no | `"manual"` | Who registered this: `wild-cloud`, `wild-works`, `manual`. |
|
|
| `backend.address` | string | yes | — | Target host:port (e.g., `192.168.8.240:443`). |
|
|
| `backend.type` | string | yes | — | `tcp-passthrough` or `http`. |
|
|
| `backend.health` | string | no | — | Health check path for L7 services (e.g., `/health`). |
|
|
| `subdomains` | bool | no | `false` | If true, also routes `*.domain` traffic to this backend. |
|
|
| `reach` | string | yes | — | `internal` or `public`. |
|
|
| `tls` | string | no | inferred | `passthrough` or `terminate`. Defaults based on backend type. |
|
|
|
|
## User-facing concepts
|
|
|
|
The API fields map to three user-visible controls:
|
|
|
|
### Public / Private
|
|
|
|
`reach: "public"` or `reach: "internal"`
|
|
|
|
- **Private** (internal): Domain resolves only on the LAN. No public DNS record. Accessible only from your local network or VPN.
|
|
- **Public**: Domain resolves on the LAN AND has a public DNS A record. Accessible from the internet through Central's HAProxy.
|
|
|
|
### Subdomains
|
|
|
|
`subdomains: true` or `subdomains: false`
|
|
|
|
- **Off** (default): Only the exact domain is routed (`payne.io` routes, but `foo.payne.io` does not).
|
|
- **On**: Both the domain and all subdomains are routed (`cloud.payne.io` AND `matrix.cloud.payne.io`, `vaultwarden.cloud.payne.io`, etc.).
|
|
|
|
### TLS handling
|
|
|
|
`tls: "passthrough"` or `tls: "terminate"`
|
|
|
|
- **Passthrough**: Central forwards encrypted traffic directly to the backend. The backend handles its own TLS certificates (e.g., a k8s cluster with traefik). Maps to `backend.type: "tcp-passthrough"`.
|
|
- **Terminate**: Central provisions a TLS certificate and handles HTTPS. Traffic is decrypted at Central and proxied as HTTP to the backend. Maps to `backend.type: "http"`.
|
|
|
|
## What Central does per registration
|
|
|
|
When a service is registered, Central automatically:
|
|
|
|
| Effect | Passthrough | Terminate |
|
|
|--------|-------------|-----------|
|
|
| **LAN DNS** | `address=/<domain>/<backend-IP>` — direct to backend | `address=/<domain>/<central-IP>` — through Central |
|
|
| **LAN DNS (private)** | Also `local=/<domain>/` — prevents upstream forwarding | Same |
|
|
| **Public DNS** | DDNS A record if public | Same |
|
|
| **Proxy** | L4 SNI passthrough. Subdomains adds `*.domain` matching. | L7 HTTP reverse proxy by Host header. |
|
|
| **TLS** | Backend handles — Central passes through | Central provisions cert via Let's Encrypt |
|
|
|
|
## Examples
|
|
|
|
### k8s cluster (passthrough, public, with subdomains)
|
|
|
|
```json
|
|
{
|
|
"domain": "cloud.payne.io",
|
|
"source": "wild-cloud",
|
|
"backend": {"address": "192.168.8.240:443", "type": "tcp-passthrough"},
|
|
"subdomains": true,
|
|
"reach": "public"
|
|
}
|
|
```
|
|
|
|
Central creates: LAN DNS → 192.168.8.240, public DNS A record, HAProxy L4 SNI + wildcard *.cloud.payne.io, TLS passthrough.
|
|
|
|
### Internal web app (terminate, private)
|
|
|
|
```json
|
|
{
|
|
"domain": "wild-cloud.payne.io",
|
|
"source": "wild-cloud",
|
|
"backend": {"address": "127.0.0.1:5055", "type": "http"},
|
|
"reach": "internal"
|
|
}
|
|
```
|
|
|
|
Central creates: LAN DNS → Central IP (with `local=/`), HAProxy L7 reverse proxy, TLS cert via certbot. No public DNS.
|
|
|
|
### Custom domain (passthrough, public, exact match)
|
|
|
|
```json
|
|
{
|
|
"domain": "payne.io",
|
|
"source": "wild-cloud",
|
|
"backend": {"address": "192.168.8.240:443", "type": "tcp-passthrough"},
|
|
"subdomains": false,
|
|
"reach": "public"
|
|
}
|
|
```
|
|
|
|
Central creates: LAN DNS → 192.168.8.240, public DNS A record, HAProxy L4 SNI exact match only. No wildcard.
|
|
|
|
## What is NOT a registration
|
|
|
|
Central's own services come from config, not the registration API:
|
|
|
|
- Central's UI domain (`cloud.central.domain`)
|
|
- VPN (`cloud.vpn.*`)
|
|
- Firewall rules (`cloud.nftables.*`)
|
|
- DHCP (`cloud.dnsmasq.dhcp.*`)
|
|
- CrowdSec, certbot credentials, DDNS provider config
|