otbr: bind the REST API to the pod address, not 0.0.0.0 #145

Merged
k.renner merged 1 commits from fix/otbr-rest-bind-eth0 into master 2026-07-10 14:50:51 +00:00
1 Commits
Author SHA1 Message Date
k.rennerandClaude Opus 4.8 75261f039c otbr: bind the REST API to the pod address, not 0.0.0.0
Last of the three IoT-VLAN gate/bind bypasses (shelly-manager #142,
matter-server #144). otbr's net1 is a macvlan on the IoT VLAN (backbone
interface), macvlan bypasses Cilium policy, and REST_HOST=0.0.0.0 bound
otbr-agent's REST API on :8081 to all interfaces — so the unauthenticated
OTBR REST API was reachable from the whole IoT VLAN.

Verified 2026-07-10 from edge-1 (on v30iot): GET http://<net1 ip>:8081/
answered (404 at /, but it is the live otbr-agent REST listener). That API
can read and modify Thread network configuration, including the network
key — i.e. enough to join or disrupt the Thread mesh.

Note the reality vs. the old comment: otbr-agent's REST listens on :8081
(governed by REST_HOST / --rest-listen-address); otbr-web sits on
127.0.0.1:80 (loopback, not exposed); the container's declared rest:8080
port has no listener. So REST_HOST is the whole exposure.

Set REST_HOST to the pod eth0 address via the downward API
(POD_IP=status.podIP; REST_HOST=$(POD_IP)). POD_IP is declared BEFORE
REST_HOST because k8s $(VAR) substitution only sees earlier env entries.
HA's OTBR integration keeps working via the IPv4 ClusterIP Service
(otbr.home-assistant.svc:8081 -> podIP:8081). net1 no longer carries REST.

The border router itself is unaffected: it uses net1 through
BACKBONE_INTERFACE for mDNS/RA/backbone, independent of where REST listens.

Verified: kubectl kustomize builds; rendered env has POD_IP (downward API)
before REST_HOST=$(POD_IP); BACKBONE_INTERFACE=net1 unchanged. Baseline
before change: state=leader, br=running, mesh 2 routers/8 children/8
neighbors.

CAVEAT: this restarts the Thread border router. Expect ~60s of
self-healing CASE-session churn on Thread/Matter end devices as the mesh
re-forms (per the #141 verification). The dataset-restore race and the
protocol-aware probes from #139/#140/#141 mean the pod should come back to
leader/running on its own and only report Ready once Thread is up.

Post-merge checks to run: GET net1:8081 from the IoT VLAN now fails; REST
listens on the pod IP only; HA reaches otbr:8081 via ClusterIP; otbr
returns to leader/br running and the mesh reconverges; matter-server's
Thread nodes re-subscribe.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-10 16:43:26 +02:00