docs/networking/vlans.md

# VLANs

The homelab uses four VLANs served off a single trunk port from the
OPNsense box to the main unifi switch. All *.home.arpa names live in
the DNS zone served by Adguard Home; VLAN firewall rules sit on
OPNsense.

See also: mercemay.top/src/homelab-compose/

## Layout

| VLAN | CIDR            | Name      | Purpose                                  |
|------|-----------------|-----------|------------------------------------------|
| 10   | 10.10.10.0/24   | MGMT      | Router, AP, switch, IPMI                 |
| 20   | 10.10.20.0/24   | TRUSTED   | Workstations, laptops, admin phones      |
| 30   | 10.10.30.0/24   | IOT       | WiFi-only, no east-west, egress filtered |
| 40   | 10.10.40.0/24   | GUEST     | Guest WiFi, internet-only                |
| 50   | 10.10.50.0/24   | LAB       | homelab-1 host + docker bridges          |

## Key firewall rules

- TRUSTED -> LAB on 80/443/22 only. Everything else goes through the
  Caddy reverse proxy, which sits on LAB.
- IOT -> LAB: deny. IOT can only reach the router (DNS/NTP) and the
  internet. If an IOT device needs a server (mqtt, scrypted), we
  expose it via Caddy on a 10.10.30.x service IP with forward_auth.
- LAB -> TRUSTED: deny. Breaks backup agents that push "home" - we
  pull instead (see backup/stages/rclone-sync.sh).
- MGMT -> anything: allow (admin override).
- GUEST: internet only. UDP 53 forced to the router's resolver so
  nothing leaks to upstream.

## DNS

Adguard Home runs on the router and serves `home.arpa` from a static
zone file. There is no split-horizon: the public zone (`example.net`)
has no records that resolve into RFC1918 space. Internal apps are
never reachable from outside the LAN, full stop.

## Docker bridges

Each stack defines its own internal bridge (`net-<stack>`) and
attaches to the shared `caddy-edge` bridge for services that need to
be reverse-proxied.

```
+---------------+
|   caddy-edge  |<---- caddy container
+---------------+
       ^
       |
+------+-------+ +--------+-------+ +-------+
| net-monitor  | | net-media      | |net-auth|
| prometheus   | | jellyfin       | |authelia|
| grafana      | | sonarr ...     | |lldap   |
| loki         | | gluetun-qbt    | |redis   |
+--------------+ +----------------+ +--------+
```

## WireGuard (optional)

`wg0` on the router provides a remote-access tunnel into VLAN 20 only.
Nothing routable to VLAN 50 (LAB) is exposed. See
`docs/networking/ipv6.md` for the v6 side.