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
This commit is contained in:
@@ -10,64 +10,79 @@ Internet
|
||||
▼
|
||||
UCG (Ubiquiti Cloud Gateway)
|
||||
│
|
||||
├── VLAN 1 - Management (10.0.1.0/24)
|
||||
├── VLAN 10 - Servers (10.0.10.0/24)
|
||||
├── VLAN 20 - IoT (10.0.20.0/24)
|
||||
└── VLAN 99 - Guest (10.0.99.0/24)
|
||||
└── LAN (192.168.1.0/24)
|
||||
│
|
||||
└── catherby (192.168.1.50) — k3s single-node cluster
|
||||
```
|
||||
|
||||
## VLAN Configuration
|
||||
## Node
|
||||
|
||||
| VLAN ID | Name | Subnet | Purpose |
|
||||
|---------|------------|-----------------|------------------------|
|
||||
| 1 | Management | 10.0.1.0/24 | Network devices, admin |
|
||||
| 10 | Servers | 10.0.10.0/24 | k3s cluster nodes |
|
||||
| 20 | IoT | 10.0.20.0/24 | IoT devices |
|
||||
| 99 | Guest | 10.0.99.0/24 | Guest WiFi |
|
||||
|
||||
## DHCP Reservations (VLAN 10 — Servers)
|
||||
|
||||
| Hostname | IP Address | MAC Address | Role |
|
||||
|----------|-------------|-------------------|-------------|
|
||||
| nuc01 | 10.0.10.11 | XX:XX:XX:XX:XX:01 | k3s server |
|
||||
| nuc02 | 10.0.10.12 | XX:XX:XX:XX:XX:02 | k3s agent |
|
||||
| nuc03 | 10.0.10.13 | XX:XX:XX:XX:XX:03 | k3s agent |
|
||||
| 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 | 10.0.10.11 | 80 | TCP |
|
||||
| HTTPS | 443 | 10.0.10.11 | 443 | TCP |
|
||||
| k3s API | 6443 | 10.0.10.11 | 6443 | TCP |
|
||||
| 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 nuc01 where Traefik runs as the ingress controller.
|
||||
> k3s API port is only forwarded if external kubectl access is needed.
|
||||
> **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
|
||||
|
||||
### Inter-VLAN Rules
|
||||
- **Servers → Internet**: Allow all outbound
|
||||
- **Servers → Management**: Allow (for UCG API access)
|
||||
- **IoT → Servers**: Deny (isolate IoT from cluster)
|
||||
- **Guest → ***: Allow Internet only, block all local
|
||||
|
||||
### Inbound Rules
|
||||
- Allow established/related connections
|
||||
- Allow HTTP (80) and HTTPS (443) to VLAN 10
|
||||
- Allow HTTP (80) and HTTPS (443) to 192.168.1.50
|
||||
- Drop all other inbound
|
||||
|
||||
## DNS Configuration
|
||||
|
||||
- **Internal DNS**: Use UCG as DNS server for VLAN 10
|
||||
- **External DNS**: Cloudflare (1.1.1.1, 1.0.0.1)
|
||||
- **Local DNS entries**: Add `*.homelab.local` → 10.0.10.11 for internal access
|
||||
|
||||
## Setup Steps
|
||||
|
||||
1. **Create VLANs** in UniFi Network → Settings → Networks
|
||||
2. **Assign ports** on the switch to VLAN 10 for NUC connections
|
||||
3. **Create DHCP reservations** for each NUC (Settings → Networks → VLAN 10)
|
||||
4. **Add port forwarding rules** (Settings → Firewall & Security → Port Forwarding)
|
||||
5. **Configure firewall rules** (Settings → Firewall & Security → Firewall Rules)
|
||||
6. **Set local DNS** entries for *.homelab.local
|
||||
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)
|
||||
|
||||
@@ -1,37 +1,66 @@
|
||||
# Network Diagram
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ Internet │
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌──────┴───────┐
|
||||
│ UCG │
|
||||
│ 10.0.1.1 │
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌────────────┼────────────┐
|
||||
│ │ │
|
||||
┌──────┴───┐ ┌─────┴────┐ ┌────┴──────┐
|
||||
│ VLAN 10 │ │ VLAN 20 │ │ VLAN 99 │
|
||||
│ Servers │ │ IoT │ │ Guest │
|
||||
└──────┬───┘ └──────────┘ └───────────┘
|
||||
│
|
||||
┌────────────┼────────────┐
|
||||
│ │ │
|
||||
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
|
||||
│ nuc01 │ │ nuc02 │ │ nuc03 │
|
||||
│ .10.11 │ │ .10.12 │ │ .10.13 │
|
||||
│ server │ │ agent │ │ agent │
|
||||
└─────────┘ └─────────┘ └─────────┘
|
||||
## External Traffic Flow
|
||||
|
||||
Services on k3s cluster:
|
||||
┌─────────────────────────────────────┐
|
||||
│ Traefik (Ingress) ← :80/:443 │
|
||||
│ ArgoCD ← :8080 │
|
||||
│ Grafana ← :3001 │
|
||||
│ PostgreSQL (CNPG) ← :5432 │
|
||||
│ Valkey ← :6379 │
|
||||
│ Longhorn UI ← :8000 │
|
||||
└─────────────────────────────────────┘
|
||||
```
|
||||
┌──────────────┐
|
||||
│ Internet │
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌────────┴────────┐
|
||||
│ Cloudflare DNS │
|
||||
│ coreworlds.io │
|
||||
│ → public IP │
|
||||
└────────┬────────┘
|
||||
│
|
||||
┌──────┴───────┐
|
||||
│ UCG │
|
||||
│ WAN :443 │
|
||||
└──────┬───────┘
|
||||
│ port-forward
|
||||
┌──────┴───────┐
|
||||
│ catherby │
|
||||
│ 192.168.1.50 │
|
||||
│ Traefik │
|
||||
└──────┬───────┘
|
||||
│
|
||||
┌─────────────┼─────────────┐
|
||||
│ │ │
|
||||
coreworlds.io api.coreworlds.io ...
|
||||
(web app) (api server)
|
||||
```
|
||||
|
||||
## LAN Traffic Flow (Split-Horizon DNS)
|
||||
|
||||
```
|
||||
┌──────────────┐
|
||||
│ LAN Client │
|
||||
└──────┬───────┘
|
||||
│ DNS query: argocd.coreworlds.io
|
||||
┌──────┴───────┐
|
||||
│ UCG DNS │
|
||||
│ *.coreworlds │
|
||||
│ → 192.168.1 │
|
||||
│ .50 │
|
||||
└──────┬───────┘
|
||||
│ direct (no hairpin NAT)
|
||||
┌──────┴───────┐
|
||||
│ catherby │
|
||||
│ 192.168.1.50 │
|
||||
│ Traefik │
|
||||
└──────────────┘
|
||||
```
|
||||
|
||||
## Service Routing
|
||||
|
||||
```
|
||||
Traefik (192.168.1.50:443)
|
||||
│
|
||||
├── coreworlds.io → web (public)
|
||||
├── api.coreworlds.io → api (public)
|
||||
├── preview.coreworlds.io → web (public, preview ns)
|
||||
├── api-preview.coreworlds.io → api (public, preview ns)
|
||||
├── argocd.coreworlds.io → argocd (LAN only — internal-only middleware)
|
||||
├── grafana.coreworlds.io → grafana (LAN only — internal-only middleware)
|
||||
└── longhorn.coreworlds.io → longhorn (LAN only — internal-only middleware)
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user