Files
vps/runbooks/matter-packet-capture.md
T

299 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Matter packet capture (read-only)
## Purpose
Capture Matter-related traffic on LAN55 (mDNS discovery + PASE/CASE commissioning +
operational traffic) to determine whether a device is on the network, is in
commissioning mode, and whether the commissioning handshake completes. Capture
is read-only and changes no device or network state.
## Scope
- Environment: LAN55 (`hass.windy.lan`, Aqara M3, ESP32-C2 Matter bulbs,
phone / HA matter-server all on the 55 subnet).
- Subject: Matter over Wi-Fi and Thread relay nodes. The Thread 802.15.4 air
side itself is not capturable — only IPv6 forwarding by a Thread relay such
as the M3 is visible.
- Not applicable: BLE commissioning, Thread 802.15.4 frames, cross-subnet
multicast (66-subnet hosts cannot see the 55 subnet's mDNS — link-local
multicast does not cross the routed 55/66 boundary, there is no reflector).
- Read-only: no AP/device/network config is modified; state returns to normal
when tcpdump exits.
### Capture-point selection
Matter commissioning is a two-party conversation and the commissioner
participates in every message of it, so capturing on the commissioner host
equals capturing the whole flow.
| Capture point | Sees | Blind spot | Notes |
|---|---|---|---|
| **hass `end0` — commissioner side (recommended)** | The full HA-driven commissioning conversation: all mDNS queries/announcements (segment multicast) + the complete TCP 5540 PASE/CASE session | Phone-as-commissioner flows (the phone's session to the device does not pass through hass) | `core_matter_server` uses **host networking**, so tcpdump on `end0` sees the add-on's traffic directly; `/` is overlay with ~42 GB free — no 60 MB tmpfs rotation needed |
| **UAP-AC-Lite `br0` (192.168.55.5)** | All mDNS multicast (flooded; igmp snooping off) + all wireless-client unicast + unicast to/from the AP | Wired↔wired unicast — e.g. HA↔M3 TCP 5540 while a Thread device commissions via the M3 (wired, observed) — is switched locally and never traverses the AP | AP `/tmp` is a ~60 MB tmpfs → rotating capture is **mandatory** |
For the common "add device" case with HA matter-server as the commissioner,
capture on hass `end0`. Use the AP `br0` point for wireless-device or
phone-driven flows (a wireless client's unicast to/from its AP is only visible
there).
A third candidate point, `gw` `switch0`, is topology-dependent and is **not yet
a documented capture point** — see
[Conditional capture point: gw switch0](#conditional-capture-point-gw-switch0).
## Ownership
- Owner: personal ops (Windy)
- Last reviewed: 2026-08-22
- Related systems: UAP-AC-Lite AP `192.168.55.5` (br0), `core_matter_server` on
`hass.windy.lan` (`end0`), Aqara M3, ESP32-C2 Matter bulbs
## Preconditions
- SSH to the capture point:
- AP: `ssh zhiqiangf@192.168.55.5` (key-only, `BatchMode=yes` verified).
- hass: `ssh hassio@hass.windy.lan`. Non-interactive SSH does **not** source
`.zprofile`, so run tcpdump as `sudo -n -i tcpdump …` (verified 2026-08-22).
- tcpdump available:
- AP: full 4.9.2 / libpcap 1.8.1 (verified 2026-08-22).
- hass: `/usr/bin/tcpdump` via `sudo -n -i` (verified 2026-08-22).
- Trigger source ready: put the Matter device into commissioning mode, or have
HA/phone perform discovery/commissioning — otherwise no relevant packets.
- AP `/tmp` is a ~60 MB tmpfs (61.3 M total, 60.4 M free): rotating capture
(`-C`/`-W`) is mandatory on the AP. hass `/` is overlay — rotation optional
but keep the habit for long captures.
## Safety
### Non-negotiable rules
- Read-only diagnosis: no installs, config changes, or service restarts on the
AP, hass, devices, or network.
- pcap files are limited to `/tmp`; pull them off and delete them afterwards
(mandatory on the AP; same hygiene on hass).
- Never write captured content (including any plaintext key material) into this
repository or Linear.
### Stop conditions
- Capture point unreachable (ssh fails) → `STOP`, fix the network first.
- tcpdump reports "Permission denied" or cannot listen → `STOP` (admin needed;
on hass verify `sudo -n -i` works).
- Filter expression syntax error → `STOP`, use only expressions verified in
this document.
- AP `/tmp` nearly full (rotation file count × single-file size ≈ 60 MB) →
`STOP` and clean old pcaps.
## Procedure
### Step 1 — Choose the capture point
**Action**
- HA matter-server is the commissioner (the "add device" case) → hass `end0`.
- Wireless device or phone-driven flow → AP `br0`.
**Expected**
- The chosen point is reachable and tcpdump starts listening.
**Decision**
- Capture point chosen and reachable → Step 2.
- Neither applies or the choice is unclear → `STOP` and record why.
### Step 2 — Realtime observation (quick confirm traffic appears)
**Action**
AP:
```bash
ssh zhiqiangf@192.168.55.5 "tcpdump -ni br0 -s 0 -tt 'udp port 5353 or tcp port 5540 or tcp port 5552'"
```
hass (commissioner side):
```bash
ssh hassio@hass.windy.lan "sudo -n -i tcpdump -ni end0 -s 0 -tt 'udp port 5353 or tcp port 5540 or tcp port 5552'"
```
Keep the window open, trigger the device behavior (enter commissioning mode /
start commissioning / send a command), `Ctrl+C` to stop.
**Expected**
- `_matterc._udp` / `_matter._tcp` mDNS announcements (UDP 5353, multicast
`224.0.0.251` / `ff02::fb`).
- During commissioning: TCP **5540** (PASE/CASE) SYN/SYN-ACK between the device
IP and HA/M3.
- If the target device's MAC is known, add `and ether host <mac>` to keep only
that device (see variants).
- `5552` is not a standard Matter port; it is an observed port for the Aqara M3
Thread-relay node (see `docs/matter-pairing-troubleshoot.md`).
**Decision**
- Expected packets present → Step 3 to save evidence, or judge directly against
the stage table (`docs/matter-pairing-troubleshoot.md` §4).
- No packets at all → `STOP`: fix device online / commissioning-mode first; the
network side is repeatedly verified healthy (see troubleshooting doc).
- mDNS present but no 5540 → see troubleshooting doc decision tree, item 4
(§5).
### Step 3 — Rotating capture + pull to WSL
**Action** (`-C 5` = rotate every 5 MB, `-W 12` = max 12 files, ≈ 60 MB ≤ AP tmpfs)
AP:
```bash
ssh zhiqiangf@192.168.55.5 "tcpdump -ni br0 -s 0 -C 5 -W 12 -w /tmp/matter.pcap 'udp port 5353 or tcp port 5540 or tcp port 5552'"
```
hass (rotation optional — overlay disk):
```bash
ssh hassio@hass.windy.lan "sudo -n -i tcpdump -ni end0 -s 0 -C 5 -W 12 -w /tmp/matter.pcap 'udp port 5353 or tcp port 5540 or tcp port 5552'"
```
Trigger the traffic, then `Ctrl+C`. Files are `/tmp/matter.pcap`,
`/tmp/matter.pcap1`, …
**Expected**
- tcpdump prints capture statistics (`N packets captured`).
- `ls -la /tmp/matter.pcap*` shows the files; total stays < 60 MB on the AP.
**Verification**
```bash
ssh zhiqiangf@192.168.55.5 "ls -la /tmp/matter.pcap*"
# or
ssh hassio@hass.windy.lan "ls -la /tmp/matter.pcap*"
```
**Pull to WSL for analysis and clean up afterwards**
```bash
scp zhiqiangf@192.168.55.5:/tmp/matter.pcap* .
# or
scp hassio@hass.windy.lan:/tmp/matter.pcap* .
# clean up on the capture point
ssh zhiqiangf@192.168.55.5 "rm -f /tmp/matter.pcap*"
ssh hassio@hass.windy.lan "sudo -n -i rm -f /tmp/matter.pcap*"
```
### Step 4 — Wireshark analysis (optional)
**Action**
Open the pcap in Wireshark. mDNS (UDP 5353) is plaintext and directly
readable; Matter payloads on TCP/UDP 5540 show only the handshake by default —
plaintext needs the dissector plus session keys (Step 5).
**Expected**
- `mDNS` filter shows all discovery records; `tcp.port==5540` shows the
commissioning handshake.
### Step 5 — Decrypt Matter plaintext (optional, needs session keys)
Matter payloads are encrypted (AES-CCM); mDNS plaintext contains no keys. To
decrypt, one of:
1. **Capture-side key leak with a chip tool (most common)**: the commissioner
(HA matter-server / chip-tool) prints or exports session keys during
commissioning; enter them in Wireshark → Preferences → Protocols → Matter.
See [matter-dissector README](https://github.com/project-chip/matter-dissector#security-features).
2. **well-known CASE keys**: both sides compiled with
`MATTER_CONFIG_SECURITY_TEST_MODE` / `CASEUseKnownECDHKey`; not enabled in
this environment (ESP32-C2 + HA official matter-server).
**Expected**
- Matter dissector expands protocol headers, IM commands, and cluster content.
**Stop condition (decryption)**: with no session keys or test keys obtainable,
do not fabricate keys to force a decrypt — plaintext mDNS + TCP handshake
still resolves most troubleshooting; for plaintext payloads, upgrade to
exporting keys on the commissioner side, then return to this runbook.
## Targeted capture variants
### One device only (known MAC)
```bash
ssh zhiqiangf@192.168.55.5 "tcpdump -ni br0 -s 0 -tt 'ether host 34:98:7a:27:7f:08 and (udp port 5353 or tcp port 5540 or tcp port 5552)'"
```
MACs from `docs/matter-pairing-troubleshoot.md` §3 (working bulb
`34:98:7a:25:a1:f0`, broken bulb `34:98:7a:27:7f:08`).
### mDNS announcements only (no 5540 noise)
```bash
ssh zhiqiangf@192.168.55.5 "tcpdump -ni br0 -s 0 -tt 'udp port 5353'"
```
### Rotating capture with timestamped filename (multiple runs)
```bash
ssh zhiqiangf@192.168.55.5 "tcpdump -ni br0 -s 0 -C 5 -W 12 -w /tmp/matter-\$(date +%H%M%S).pcap 'udp port 5353 or tcp port 5540 or tcp port 5552'"
```
> The nested `$(date)` must be escaped as `\$(...)` inside the double-quoted ssh
> command so the remote shell expands it.
For the hass point, prefix the same commands with
`ssh hassio@hass.windy.lan "sudo -n -i tcpdump -ni end0 …"`.
## Conditional capture point: gw switch0
**Status: NOT yet a documented capture point.** Its coverage depends on the
live topology; verify before relying on it.
- `gw` `switch0` (`eth1``eth3`, `192.168.55.254/24`) is LAN55's L2 aggregation
point only while devices plug directly into the ER-X. EdgeOS ships tcpdump,
and `tcpdump -ni switch0` follows Linux bridge semantics.
- **Live state (verified 2026-08-22): the SE5420 core switch is deployed**
(management `192.168.66.253` reachable; TP-Link "Web Switch" on :80/:443).
With the flat-VLAN55 single-uplink design, same-segment traffic switches
locally on the SE5420 and never reaches `switch0`. In that state `switch0`
sees only: cross-subnet (66↔55) unicast, gateway-bound traffic, and LAN55
mDNS multicast (flooded) — **not a full mirror**. The full-mirror point
becomes the SE5420 itself, which cannot run tcpdump (port mirroring only).
- **Before using this point**, run these read-only checks from a machine with
gw SSH access:
```bash
ssh -4 zhiqiang@192.168.66.254 'show interfaces ethernet' # which switch0 member ports have link
ssh -4 zhiqiang@192.168.66.254 'show ethernet-switch port all' # per-port MAC table
ssh -4 zhiqiang@192.168.66.254 'show mac-address-table' # where LAN55 wired devices land
```
- LAN55 wired devices all on a single member port → single uplink confirmed;
`tcpdump -ni switch0 …` is then valid with the limited coverage above.
- Devices spread across `eth1``eth3` → SE5420 not in the LAN55 path;
`switch0` is the full mirror point.
- Until one of these is confirmed, do not treat `switch0` as a capture point.
## Pass criteria
- Realtime capture consistently shows the target device's mDNS announcements
(`_matterc` / `_matter._tcp`) on the chosen point.
- Commissioning shows the TCP 5540 handshake (SYN/SYN-ACK/ACK); on the hass
`end0` point this includes wired Thread-relay commissioning (HA↔M3), which
the AP point cannot see.
- Saved pcap opens in Wireshark and filters by `mDNS` / `tcp.port==5540`.
## References
- [docs/matter-pairing-troubleshoot.md](../docs/matter-pairing-troubleshoot.md) —
troubleshooting decision tree, stage table, device MAC/fabric facts
- [docs/unifi-network.md](../docs/unifi-network.md) — UniFi network/IPv6/SSID records
- [hosts/hass.windy.lan.md](../hosts/hass.windy.lan.md) — matter-server host
networking + `sudo -n -i` non-interactive note
- [hosts/gw.md](../hosts/gw.md) — DHCP `matter` reservation MAC mismatch (pending, W1N-207)
- [matter-dissector](https://github.com/project-chip/matter-dissector) —
Wireshark Matter dissector (incl. decryption)
- [Silabs: Using Wireshark to Capture Network Traffic in Matter](https://docs.silabs.com/matter/2.9.1/matter-references/matter-wireshark)