- 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
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
- Add port forwarding rules (Settings → Firewall & Security → Port Forwarding)
- WAN 80 → 192.168.1.50:80
- WAN 443 → 192.168.1.50:443
- Configure local DNS (Settings → Networks → DNS)
*.coreworlds.io→ 192.168.1.50
- Configure Cloudflare DNS (Cloudflare dashboard)
- A record:
coreworlds.io→ public IP - CNAME:
*→coreworlds.io
- A record:
- Configure firewall rules (Settings → Firewall & Security → Firewall Rules)