spike(R-6): S4b name-resolution finding — wsdd visible but flat name unresolvable

Human Explorer leg exposed the split: FELHOM-SPIKE renders (WSD PASS) but the
double-click fails 0x80070035 — flat name resolves by no path (DNS/LLMNR/NetBIOS
all silent; disable netbios=yes). By-IP mount works => SMB is healthy, the gap is
name resolution. Fix verified live: adding nmbd (NetBIOS) => nbtstat lists
FELHOM-SPIKE, ping resolves, \FELHOM-SPIKE\spike-share mounts by name. R-7 must
ship smbd+wsdd+nmbd (+avahi/.local), not wsdd alone.
This commit is contained in:
2026-07-18 10:46:53 +02:00
parent 900d3041fa
commit d3eb8099a3
2 changed files with 86 additions and 23 deletions
@@ -41,13 +41,18 @@ container). Docker's default bridge cannot receive LAN multicast at all**, so WS
are dead there while a published unicast port still works. Empirically, guest-netns (S1) and
host-network (S2) are byte-for-byte equivalent and pass SSDP/mDNS/WSD in **both** directions; the
default bridge (S3) fails multicast RX for all three. A real **samba + wsdd** stack on host-network
is discovered by Windows 11 (ProbeMatch confirmed), answers on TCP 445, and serves an authenticated
read/write SMB round-trip. A real **SSDP `MediaServer:1`** advertisement from host-network is received
by both LAN clients. **Recommendation for R-7: run the samba/wsdd stack as a host-network infra
stack, LAN-bound.** For R-8: Jellyfin's built-in DLNA is physically viable on this topology **if it
runs host-network**. One caveat R-7/R-8 must carry: `vmbr0` runs with `multicast_snooping=1` and no
STP — it worked here because the household router (.1) is an active IGMP querier, but a customer LAN
with snooping-on-and-no-querier could prune the groups (§7d).
is discovered by Windows 11 (ProbeMatch confirmed + **FELHOM-SPIKE renders in Explorer**), answers on TCP
445, and serves an authenticated read/write SMB round-trip. A real **SSDP `MediaServer:1`**
advertisement from host-network is received by both LAN clients. **But the human leg exposed a second
requirement wsdd alone does not meet (S4b):** the Explorer *double-click* on FELHOM-SPIKE failed with
`0x80070035` because the flat name resolved by no path — WSD gives visibility, not name resolution.
Adding **nmbd (NetBIOS name service)** fixed it live (`\\FELHOM-SPIKE` then resolves and mounts).
**Recommendation for R-7: run the stack host-network, LAN-bound — `smbd` + `wsdd` (visibility) +
`nmbd` (flat-name resolution), and ideally `avahi`/`.local` for modern clients.** For R-8: Jellyfin's
built-in DLNA is physically viable on this topology **if it runs host-network**. One caveat R-7/R-8
must carry: `vmbr0` runs with `multicast_snooping=1` and no STP — it worked here because the household
router (.1) is an active IGMP querier, but a customer LAN with snooping-on-and-no-querier could prune
the groups (§7d).
---
@@ -141,7 +146,7 @@ Throwaway host-network stack in the guest: `spike-samba` (alpine + `apk add samb
| 1. WS-Discovery ProbeMatch | scripted Probe (`Types=wsdp:Device`) from the workstation | **PASS** — ProbeMatch from `192.168.0.127`; wsdd logged our exact `MessageID` from `192.168.0.110` |
| 2. Port 445 reachability | `Test-NetConnection 192.168.0.127 -Port 445` | **PASS**`TcpTestSucceeded: True` |
| 3. SMB round-trip | `New-SmbMapping` as `spikeuser` → write `roundtrip.txt` → read back → byte-compare | **PASS**`BYTE-COMPARE: PASS`; dir listed `README.txt` (24B) + `roundtrip.txt` (28B) |
| 4. Explorer Network view (human) | Viktor: Explorer → Network shows **FELHOM-SPIKE**, double-click opens the share | **PENDING — human leg; stack left live** |
| 4. Explorer Network view (human) | Viktor: Explorer → Network | **SPLIT: device VISIBLE (WSD PASS), double-click FAILED `0x80070035`** — see S4b |
wsdd log for leg 1:
```
@@ -151,8 +156,58 @@ wsdd log for leg 1:
The scripted client's friendly-name auto-fetch reported FAIL only because python-wsdd's metadata
HTTP endpoint (`:5357/<uuid>/`) requires the native WS-Discovery **Resolve→Transfer/Get** handshake
that Windows Explorer performs itself (a direct throwaway `Get` 404s). The **objective discovery gate
is the ProbeMatch (PASS)**; the `FELHOM-SPIKE` name is what wsdd is configured to present and is the
subject of the human leg. Optional S4.5 (mDNS `.local` name + phone) was **skipped**.
is the ProbeMatch (PASS)**; the `FELHOM-SPIKE` name is what wsdd is configured to present. Optional
S4.5 (mDNS `.local` name + phone) was **skipped**.
## S4b — the Explorer double-click failure (THE sharpest R-7 finding)
Viktor's human leg surfaced a split result Windows-side that the by-IP scripted tests had masked:
- **Visibility: PASS.** Explorer → Network → **Computer** renders **`FELHOM-SPIKE`** (wsdd/WSD works
as a discovery beacon — screenshot on file).
- **Double-click: FAIL** → `Windows cannot access \\FELHOM-SPIKE` · **`0x80070035` "network path
not found."**
Diagnosis from the workstation (192.168.0.110) isolates the cause as **flat-name resolution, not
SMB**:
| Check | Result |
|---|---|
| `Test-NetConnection 192.168.0.127 -Port 445` + `New-SmbMapping \\192.168.0.127\spike-share` | **PASS** — mounts by IP, lists files. SMB/auth/445 are fine. |
| `Resolve-DnsName FELHOM-SPIKE` (DNS) | fail — "DNS name does not exist" |
| `Resolve-DnsName FELHOM-SPIKE -LlmnrNetbiosOnly` | fail — timeout (nobody answers LLMNR) |
| `ping FELHOM-SPIKE` | "could not find host" |
| `nbtstat -A 192.168.0.127` | "Host not found" — no NetBIOS name service (`disable netbios=yes`) |
**Root cause:** WSD hands Explorer a device *icon* named FELHOM-SPIKE, but the double-click issues a
plain UNC `\\FELHOM-SPIKE`, whose flat name Windows must resolve via DNS → LLMNR → NetBIOS. With
`disable netbios=yes` and no mDNS/LLMNR responder, **nothing answers**`0x80070035`. Mounting by IP
bypasses all name resolution and works — proving the SMB server itself is healthy.
**Fix verified live (S4b relaunch: samba with `disable netbios=no` + `nmbd`):**
| Check (after nmbd) | Result |
|---|---|
| `nbtstat -A 192.168.0.127` | **`FELHOM-SPIKE <00>/<03>/<20> Registered`** |
| `ping FELHOM-SPIKE` | **`Reply from 192.168.0.127`** — flat name resolves via NetBIOS broadcast |
| `New-SmbMapping \\FELHOM-SPIKE\spike-share` | **MOUNT BY NAME: OK** — lists the share |
**Conclusion for R-7:** `wsdd` alone makes the box *visible* but is **not sufficient** for the
one-click UX — a **flat-name resolver is required** for `\\FELHOM-SPIKE` to open. Options, in order of
how well they serve the exact WSD-shown flat name:
1. **nmbd / NetBIOS name service** (samba's `disable netbios=no` + run nmbd) — *directly resolves the
flat `\\FELHOM-SPIKE`*, proven here. The catch: NetBIOS-over-TCP is legacy (Microsoft is slowly
deprecating it) and can be off on hardened client networks; needs UDP 137/138 and
`interfaces = eth0` + `bind interfaces only = yes` in production (nmbd bound the docker 172.x
bridges too here — must be pinned to the LAN iface).
2. **mDNS / avahi** advertising `felhom-spike.local` — Windows 10/11 resolve `.local` natively and
it is the future-proof path, **but** it serves `\\felhom-spike.local\…`, not the flat name the
WSD icon double-clicks — so it's an *additional* access path, not a drop-in fix for the Explorer
double-click. (Not tested live — R-7 should.)
3. **Accept "mount by IP / by `.local`"** and treat WSD as visibility-only — the weakest UX.
R-7 recommendation: ship **wsdd + nmbd (LAN-bound)** for the classic one-click experience *and*
**avahi/.local** for the modern clients, so both the flat name and `.local` resolve.
## S5 — SSDP / DLNA pre-check for R-8 (scripted only)
@@ -185,14 +240,18 @@ future deployment must avoid host-network port collisions (§7c).
| mDNS 5353 RX / TX | PASS / PASS | PASS / PASS | **FAIL / FAIL** · unicast-publish PASS | not run |
| WSD 3702 RX / TX | PASS / PASS | PASS / PASS | **FAIL / FAIL** · unicast-publish PASS | not run |
| SMB 445 unicast | n/a | **PASS** (S4) | publish PASS | not run |
| Explorer visibility (human) | n/a | **PENDING** (S4.4) | n/a | not run |
| Explorer visibility (human) | n/a | **PASS** — FELHOM-SPIKE renders (S4.4) | n/a | not run |
| Explorer double-click → open share | n/a | **FAIL w/ wsdd-only → PASS w/ nmbd** (S4b) | n/a | not run |
**(a) Recommended transport for the R-7 SMB stack — HOST-NETWORK, LAN-bound.** The matrix is
unambiguous: WSD (Windows Explorer's actual discovery) and mDNS require the responder in the guest
netns; the default docker bridge is categorically deaf to LAN multicast. So samba + wsdd (and any
avahi) must run `network_mode: host`. Bind SMB to the LAN interface only; **never expose 445 over the
tunnel** (the LAN-only rule R-7 already states). This is the expected outcome — and the matrix, not
the expectation, now backs it.
**(a) Recommended transport + services for the R-7 SMB stack — HOST-NETWORK, LAN-bound, THREE
daemons.** The matrix is unambiguous on transport: WSD (Explorer's actual discovery) and mDNS require
the responder in the guest netns; the default docker bridge is categorically deaf to LAN multicast.
So the stack must run `network_mode: host`, SMB bound to the LAN interface only, **never over the
tunnel**. On *services*, S4b proved wsdd is not enough: ship **`smbd` (445) + `wsdd` (WSD visibility)
+ `nmbd` (NetBIOS flat-name resolution, so the Explorer double-click on `\\FELHOM-SPIKE` actually
opens) + ideally `avahi` (`.local` for modern/Apple clients)**. Pin every daemon to the LAN iface
(`interfaces = eth0` + `bind interfaces only = yes`) — nmbd otherwise also binds the docker 172.x
bridges. Without nmbd/mDNS the box is *visible but not openable by name* (`0x80070035`).
**(b) R-8 "try Jellyfin built-in DLNA first" — PLAUSIBLE on this topology.** SSDP `MediaServer:1`
adverts physically reach both LAN clients (S5). The only structural requirement carried over from
@@ -216,7 +275,10 @@ generalizes.
## NOT tested (explicit)
- **Explorer Network render** (S4.4) — human leg, pending Viktor; stack left live.
- **mDNS / avahi `.local`** as a flat-name/`.local` resolver alternative to nmbd (S4b option 2) —
NOT tested; R-7 should validate `\\felhom-spike.local` on Win11 + Apple/phone clients.
- **LLMNR responder** as a third name-resolution path — not tested (client LLMNR is on, but nothing
on the box answered it).
- **macvlan** (S6) — not needed (host-net passed).
- **Real DLNA client / TV** rendering actual media — R-8 owns.
- **Phone mDNS** `.local` resolution (optional S4.5) — skipped.
@@ -229,9 +291,10 @@ generalizes.
## CLEANUP
Throwaway containers `spike-hostnet-*`, `spike-bridge-*`, `spike-ssdp-ms` and all guest-netns
responder processes were `docker rm -f` / `pkill`'d at the end of each leg. **Intentionally left
live for the S4.4 human leg:** `spike-samba` + `spike-wsdd` (host-network), share
`\\192.168.0.127\spike-share` as **FELHOM-SPIKE**. Teardown one-liner once Viktor confirms Explorer:
responder processes were `docker rm -f` / `pkill`'d at the end of each leg. **Left live through the
S4/S4b legs:** `spike-samba` (now with nmbd) + `spike-wsdd` (host-network), share
`\\FELHOM-SPIKE\spike-share` / `\\192.168.0.127\spike-share`. Teardown one-liner (all objective legs
done — safe to run any time):
```
ssh felhom-pve "pct exec 9201 -- docker rm -f spike-samba spike-wsdd; \
+2 -2
View File
@@ -30,8 +30,8 @@
| ID | Item | Size | Status | Notes |
|----|------|------|--------|-------|
| R-5 | Hub: offsite storage visibility — RESTIC box aggregate (v0.64.0) + PBS DR datastore (v0.65.0), each with fill + operator alert; Offsite tabs + dual dashboard gauges | M | **SHIPPED (hub v0.64.0 + v0.65.0 + tenantsync v1.2.0, 2026-07-17)** | Restic: `monitor.OffsiteBoxChecker` (throttled Hetzner GET; fill 80/90% + oversub 2.0×; scope `"pool-box"`). PBS DR (v0.65.0, Option A): read-only `usage` op on the ep0 `felhom-tenantsync` forced command (`df`, no mutation) → `monitor.PBSDRBoxChecker` (fill 80/90%, states ok/unavailable/degraded, scope `"pbsdr-box"`); `/offsite` Restic/PBS-DR tabs + two gauges; hub deploy ⟂ ep0 update (graceful "n/a"). **Both data pipelines PROVEN-LIVE** (restic `0.2% full`; PBS `19.1% full, 7.1 GB of 37.2 GB` after ep0 → v1.2.0). Thresholds pending Viktor (named keys; separate restic/PBS pairs). OPEN: UI render unit-only (password-gated), alert emails unit + red-proof only (both nominal). See hub v0.64.0 + v0.65.0 REPORTs |
| R-6 | **Spike: LAN service discovery from the guest** — SSDP multicast (UDP 1900, DLNA), WSD (Windows discovery), mDNS; host-network vs macvlan; is the customer LXC LAN-bridged in appliance deployments? | M | **spiked (2026-07-18)** | **VERDICT: appliance guest IS LAN-bridged (own DHCP lease on the household /24); multicast discovery works ONLY in the guest netns — guest-direct or Docker `--network host` (SSDP/mDNS/WSD all PASS both ways); the default docker bridge is categorically DEAF to LAN multicast (WSD/mDNS RX FAIL, unicast-publish PASS). Real samba+wsdd on host-net → Windows 11 ProbeMatch + 445 + authenticated SMB round-trip all PASS; real SSDP `MediaServer:1` advert reaches both LAN clients. → R-7 SMB stack MUST be host-network LAN-bound; R-8 Jellyfin-DLNA plausible if host-network. Caveat: `vmbr0 multicast_snooping=1` worked only because the household router is a live querier — customer LANs w/ snooping+no-querier, and Peti's BYO bridge, are UNTESTED gaps.** Doc: `audits/SPIKE-lan-discovery-2026-07-18.md`. Open sub-leg: S4.4 Explorer render (human, pending Viktor) |
| R-7 | SMB **server** share (**gate input now exists — R-6 spiked 2026-07-18: host-network, LAN-bound**): samba + wsdd, LAN-only binding (never tunnel), user model (single household user first), which roots are shared (dedicated `shares/` vs app userdata — every SMB-writable path needs a backup class), uid-1000 convention, paperless consume flow | L | idea (unblocked) | Flips map row E/MISSING. Alpha-relevant: "my box is a NAS" is a core household expectation. **R-6 settled the transport: `network_mode: host`; carry the port-collision + snooping/querier caveats from the spike into the spec** |
| R-6 | **Spike: LAN service discovery from the guest** — SSDP multicast (UDP 1900, DLNA), WSD (Windows discovery), mDNS; host-network vs macvlan; is the customer LXC LAN-bridged in appliance deployments? | M | **spiked (2026-07-18)** | **VERDICT: appliance guest IS LAN-bridged (own DHCP lease on the household /24); multicast discovery works ONLY in the guest netns — guest-direct or Docker `--network host` (SSDP/mDNS/WSD all PASS both ways); the default docker bridge is categorically DEAF to LAN multicast (WSD/mDNS RX FAIL, unicast-publish PASS). Real samba+wsdd on host-net → Windows 11 ProbeMatch + FELHOM-SPIKE renders in Explorer + 445 + authenticated SMB round-trip all PASS; real SSDP `MediaServer:1` advert reaches both LAN clients. → R-7 SMB stack MUST be host-network LAN-bound; R-8 Jellyfin-DLNA plausible if host-network. Caveat: `vmbr0 multicast_snooping=1` worked only because the household router is a live querier — customer LANs w/ snooping+no-querier, and Peti's BYO bridge, are UNTESTED gaps.** **S4b (human leg, the sharpest finding): wsdd makes the box VISIBLE but the Explorer double-click FAILS `0x80070035` — WSD gives no name resolution; the flat `\\FELHOM-SPIKE` resolved by no path. Adding `nmbd` (NetBIOS) fixed it live (flat name resolves + mounts). → R-7 needs smbd+wsdd+nmbd (+avahi/.local for modern clients), not wsdd alone.** Doc: `audits/SPIKE-lan-discovery-2026-07-18.md`. |
| R-7 | SMB **server** share (**gate input now exists — R-6 spiked 2026-07-18: host-network, LAN-bound, smbd+wsdd+nmbd**): samba + wsdd + nmbd, LAN-only binding (never tunnel), user model (single household user first), which roots are shared (dedicated `shares/` vs app userdata — every SMB-writable path needs a backup class), uid-1000 convention, paperless consume flow | L | idea (unblocked) | Flips map row E/MISSING. Alpha-relevant: "my box is a NAS" is a core household expectation. **R-6 settled the transport (`network_mode: host`) AND the service set: wsdd for WSD visibility is NOT enough — add `nmbd` so the Explorer double-click on `\\FELHOM-SPIKE` resolves (S4b proved wsdd-only fails `0x80070035`); ideally avahi/.local too. Pin daemons to eth0 (`bind interfaces only`). Carry the port-collision + snooping/querier caveats into the spec** |
| R-8 | DLNA (**gate input now exists — R-6 spiked 2026-07-18: SSDP reaches LAN clients from host-net**): validate Jellyfin's built-in DLNA server first; only add minidlna to the catalog if Jellyfin-DLNA fails | S | idea (unblocked) | Don't add catalog weight before proving the cheap path. **R-6 confirmed the cheap path is physically viable — Jellyfin DLNA must run host-network (same multicast constraint as R-7)** |
| R-9 | Uninstaller trio (from 07-15 Peti session): cluster-aware `felhom_guests` guard (node-local `pct list` deletes cluster-wide pveum objects); saferemove detection + time estimate + opt-in `--quick-remove` (never mutate `storage.cfg`); smarter `restore_storage` default for BYO clusters (shared storage, not local-lvm) | M | idea | Second item's rejected alternative (temp-disable-and-restore) stays rejected — crash window silently downgrades cluster wipe policy |
| R-10 | T-6E-1: DB-dump dir-fsync asymmetry (LOW, confirmed in 6E) | XS | idea | One-line hardening; batch with the next controller task |