feat(esh-matter): Matter server (matter.js 1.4.0) on a VLAN-90-only LXC for Home Assistant
For ha-dev (operator-approved 2026-09-26). CT 111 on esh-pve at 10.0.90.20: Matter/Thread IPv6 (Echo ULA + RA route-information) is link-only, so the server sits on esh-iot and HA reaches it over routed IPv4 ws :5580. - playbooks/esh-matter-lxc.yaml: kernel RA (accept_ra=1, rt_info_max_plen=64), forwarding off, Docker ip-forward/iptables off; nftables admits 5580 from HA 10.0.50.46 only and SSH from mgmt ranges; the CT is added to esh-pve's vzdump job (fabric credentials). - stacks/matter-server: ghcr.io/matter-js/matterjs-server:1.4.0 (digest), host networking, /data on the CT. - Acceptance: fdad:: SLAAC, ping6 thermostat, 2 Thread RIO routes learned, ws server_info from inside the HA container; 5580 refused from 10.0.50.45, nh3-dev and a temporary VLAN 90 netns vantage.
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
# esh-matter
|
||||
|
||||
LXC **CT 111 on esh-pve** whose **only network leg is VLAN 90 (esh-iot)**. It runs
|
||||
the **Matter server** (`stacks/matter-server`, matter.js 1.4.0) for Home Assistant.
|
||||
Built 2026-09-26 for ha-dev (operator-approved) by
|
||||
[`playbooks/esh-matter-lxc.yaml`](../../playbooks/esh-matter-lxc.yaml).
|
||||
|
||||
| | |
|
||||
|---|---|
|
||||
| **IPv4** | `10.0.90.20/24`, gateway `10.0.90.1`. Static, below the UDM's `.40–.250` DHCP pool |
|
||||
| **IPv6** | SLAAC from the Echo's RA: `fdad:29e:d492:fd87:be24:11ff:fe3d:c6c7` (Thread ULA) + link-local. No global prefix exists on VLAN 90 |
|
||||
| **DNS** | `esh-matter.esh.internal` (HA uses the IP: its container can't resolve `.internal`) |
|
||||
| **SSH** | `ssh esh-matter` → `infra-ops@10.0.90.20`, or `pct enter 111` on esh-pve |
|
||||
| **OS** | Debian 12, unprivileged, `nesting=1,keyctl=1` (Docker), 2 cores / 1 GB / 8 GB |
|
||||
| **Backup** | **in esh-pve's vzdump job** (PBS-ANA 03:30, synced to PBS-NH3). `/opt/docker/data/matter-server` holds the Matter **fabric root credentials**; losing it means re-commissioning every device |
|
||||
|
||||
## Why it is built this way
|
||||
|
||||
- **It must be on the devices' link.** Matter's operational traffic is IPv6, and
|
||||
VLAN 90's only IPv6 is the Thread ULA advertised by an Echo border router.
|
||||
Thread routes arrive as RA route-information options, which are link-only. HA
|
||||
(VLAN 50) reaches the server over IPv4 `ws://10.0.90.20:5580/ws`, routed by the
|
||||
UDM (policy `InternalToIOT`), so the HA container did not change.
|
||||
- **Kernel RA processing, forwarding off.** Set in `/etc/sysctl.d/60-matter-ipv6.conf`:
|
||||
`accept_ra=1`, `accept_ra_rt_info_max_plen=64`, `all.forwarding=0`. With
|
||||
forwarding on, RFC 4191 reachability probing stops (matter.js OS requirements).
|
||||
Docker is configured with `ip-forward/iptables/ip6tables: false`; the server
|
||||
uses host networking.
|
||||
- **Firewall (in-CT nftables, `/etc/nftables.conf`):**
|
||||
- TCP **5580** (websocket + dashboard, **unauthenticated**) is accepted only
|
||||
from **HA at 10.0.50.46**, then dropped.
|
||||
- SSH is accepted only from 10.0.50/24, 10.0.10/24, 10.0.250/24, 10.100/16 and
|
||||
100.64/10.
|
||||
- Everything else is accepted on purpose, so Matter UDP and mDNS never meet
|
||||
conntrack. The matter.js docs warn that a stateful firewall's 120 s UDP
|
||||
timeout drops sleepy-device reports.
|
||||
- The PVE firewall is disabled on esh-pve, so this in-CT table is the control.
|
||||
- **An LXC, not a macvlan on esh-docker-vm:** the untrusted IoT leg stays off the
|
||||
VM that runs HA and everything else.
|
||||
|
||||
## Acceptance (2026-09-26 ~1305)
|
||||
|
||||
- `ip -6 addr`: link-local + `fdad:29e:d492:fd87:…` ✓. `ping -6` to the Aqara
|
||||
thermostat `fdad:29e:d492:fd87:56ef:44ff:fea1:7a36`: 3/3 ✓.
|
||||
- `ip -6 route` learned **two Thread routes by RA**:
|
||||
- `fd0e:3007:2ebd::/64 via fe80::56ef:44ff:fea1:7a36` (the Aqara W200, Apple
|
||||
Thread network);
|
||||
- `fdb6:ee32:f4c2:1::/64 via fe80::5a9a:3eff:fe49:6d36` (the Echo).
|
||||
- `ws://10.0.90.20:5580/ws` from **inside the homeassistant container**: answered
|
||||
`server_info` (schema 13, `matter-server/1.4.0 (matter.js/0.17.9)`, fabric 1) ✓.
|
||||
- **Negative controls:** 5580 is refused from the esh-docker-vm host (10.0.50.45),
|
||||
from nh3-dev, and from a **VLAN 90 vantage** (a temporary netns on esh-pve at
|
||||
10.0.90.39, which can ping the CT). SSH is also refused from that VLAN 90
|
||||
vantage. The drop counters incremented.
|
||||
|
||||
## Not yet wired
|
||||
|
||||
- **Monitoring.** Kuma can't probe 5580 (only HA may reach it), and there is no
|
||||
Beszel agent yet. HA's Matter integration surfaces an outage.
|
||||
- **UniFi mDNS reflector is ON for esh-iot** (`mdns_enabled`). matter.js warns
|
||||
mDNS forwarders can hinder Matter. It is left alone because other devices may
|
||||
rely on it; revisit only if commissioning or discovery misbehaves.
|
||||
@@ -0,0 +1 @@
|
||||
infra-ops@10.0.90.20
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user