Files
homelab/infra/ubiquiti/README.md
Julia McGhee 71442a0405 Switch from homelab.local to coreworlds.io with split-horizon DNS and LAN-only access controls
- Migrate all ingress hostnames from *.homelab.local to *.coreworlds.io
- Remove broken Traefik certresolver config (cert-manager handles TLS)
- Add internal-only IP allowlist middleware for platform services
- Add IngressRoutes for ArgoCD, Grafana, Longhorn (LAN-only via middleware)
- Seal and add Cloudflare API token for cert-manager DNS-01 challenges
- Update cert-manager ClusterIssuers with real email
- Update k3s TLS SAN to k3s.coreworlds.io
- Rewrite Ubiquiti docs for single-node topology and split-horizon DNS
- Fix seal-secret.sh controller name to match Helm release
- Add UCG DNS setup script using API key auth
2026-03-20 19:21:46 +00:00

89 lines
3.3 KiB
Markdown

# Ubiquiti Cloud Gateway Configuration
Documentation for the Ubiquiti Cloud Gateway (UCG) that manages network ingress for the homelab cluster.
## Network Layout
```
Internet
UCG (Ubiquiti Cloud Gateway)
└── LAN (192.168.1.0/24)
└── catherby (192.168.1.50) — k3s single-node cluster
```
## Node
| Hostname | IP Address | Role |
|-----------|---------------|-------------------|
| catherby | 192.168.1.50 | k3s server (all) |
## Port Forwarding Rules
| Name | External Port | Internal IP | Internal Port | Protocol |
|-------|---------------|----------------|---------------|----------|
| HTTP | 80 | 192.168.1.50 | 80 | TCP |
| HTTPS | 443 | 192.168.1.50 | 443 | TCP |
> **Note**: HTTP/HTTPS traffic routes to catherby where Traefik runs as the ingress controller.
> Do NOT forward port 6443 (k3s API) — kubectl access is LAN-only or via VPN.
## Split-Horizon DNS
Same hostnames (`*.coreworlds.io`) resolve differently depending on the client's network:
| Source | Resolution | Path |
|----------|-------------------------------------|--------------------------------------------|
| Internet | Cloudflare DNS → public IP → UCG | WAN:443 → port-forward → 192.168.1.50:443 |
| LAN | UCG local DNS → 192.168.1.50 | Direct to 192.168.1.50:443 (no hairpin) |
### Why split-horizon?
Without it, LAN clients hitting the public IP would require hairpin NAT (traffic leaves the network and comes back in). UCG local DNS overrides avoid this — LAN clients resolve directly to the node IP.
## UCG Local DNS Configuration
Add these entries in **Settings → Networks → DNS**:
| Hostname | IP Address |
|----------------------|----------------|
| `coreworlds.io` | 192.168.1.50 |
| `*.coreworlds.io` | 192.168.1.50 |
> If the UCG doesn't support wildcard DNS entries, add individual records:
> `api.coreworlds.io`, `argocd.coreworlds.io`, `grafana.coreworlds.io`, `longhorn.coreworlds.io`,
> `preview.coreworlds.io`, `api-preview.coreworlds.io`
## Cloudflare DNS (External)
Managed in Cloudflare dashboard for `coreworlds.io`:
| Type | Name | Value | Proxy |
|-------|-------------------|-------------------|-------|
| A | `coreworlds.io` | (public static IP) | Off |
| CNAME | `*` | `coreworlds.io` | Off |
> Cloudflare proxy must be **off** (DNS-only / grey cloud) so that cert-manager DNS-01 challenges work and Traefik sees real client IPs for the internal-only middleware.
## Firewall Rules
### Inbound Rules
- Allow established/related connections
- Allow HTTP (80) and HTTPS (443) to 192.168.1.50
- Drop all other inbound
## Setup Steps
1. **Add port forwarding rules** (Settings → Firewall & Security → Port Forwarding)
- WAN 80 → 192.168.1.50:80
- WAN 443 → 192.168.1.50:443
2. **Configure local DNS** (Settings → Networks → DNS)
- `*.coreworlds.io` → 192.168.1.50
3. **Configure Cloudflare DNS** (Cloudflare dashboard)
- A record: `coreworlds.io` → public IP
- CNAME: `*``coreworlds.io`
4. **Configure firewall rules** (Settings → Firewall & Security → Firewall Rules)