v0.3.0 — Full L2 Topology · TLS Certificate Inventory · Container Images
This release completes the topology story started in v0.2.0 (CDP/Q-BRIDGE/STP probes, radial visualization, neighbor identity inference) and adds a TLS certificate inventory that collects the full cert chain from every TLS-wrapped service on each device. It also introduces official multi-arch container images on GHCR.
| Binary | amd64 | arm64 |
|---|---|---|
mibee-steward (center + Web UI) |
25 MB | 23 MB |
mibee-agent (remote LAN discovery) |
18 MB | 17 MB |
| Container image | tags |
|---|---|
ghcr.io/mi-bee-studio/mibeesteward |
:0.3.0 · :0.3 · :latest · :sha-da5cf70 (linux/amd64 + linux/arm64) |
Binaries are CGO-free (pure Go + modernc.org/sqlite) — no C toolchain on the target, runs as a regular user. The image is the unprivileged variant (LLDP/CDP raw frames + eBPF ship as no-op stubs); build the privileged variant locally with make docker-build-priv.
Full L2 topology
v0.2.0 introduced Bridge-MIB MAC→port adjacency. v0.3.0 closes the gap with three more link-layer probes, so a switch-centric network can be mapped regardless of vendor:
- CDP-MIB (
active:cdp_mib) — walks CISCO-CDP-MIBcdpCacheTableon Cisco/CDP-speaking switches; device id is the neighbor merge key. - Q-BRIDGE-MIB (
active:q_bridge_mib) — walks IEEE 802.1Qdot1qTpFdbPortfor VLAN-aware MAC→port forwarding entries; recovers adjacency on tagged/inter-VLAN topologies. - STP-MIB (
active:stp_mib) — walks BRIDGE-MIBdot1dStpfor Spanning Tree facts (root bridge, designated port, port role/state). - IF-MIB ifName resolution — turns numeric ifIndex values into human-readable names (
GigabitEthernet0/1).
Neighbor edges are persisted to device_neighbors and tagged by protocol (LLDP / CDP / Bridge-MIB / Q-BRIDGE / STP).
TLS certificate inventory
Every TLS-wrapped service on every device now has its full certificate chain collected — not just the leaf. One CollectCertChain call performs a TLS handshake and extracts the peer chain; per-cert data includes Subject/Issuer/SAN, serial, validity, signature & key algorithms (RSA/ECDSA/Ed25519 + bit size), CA/self-signed flags, SHA-256 fingerprint, and PEM.
- 8 TLS-wrapped handlers share one core:
https,ldaps,smtps,imaps,pop3s,ftps,ircs,telnets— handler count 21 → 29. host_tls_certstable — one row per cert in each port's chain (cert_index 0 = leaf, 1..N = issuers); indexed on(ip, port)andnot_afterfor expiry sweeps.- Read API
GET /api/v1/devices/{id}/certificates— per-port grouping with leaf + chain, plus status metadata (TLS version, cipher suite, trust verdict). - Frontend TLS sub-panel — one clickable row per port with status-colored border (green=valid / amber=expiring <15d / red=expired), day-count badge, self-signed/trusted tags.
CertificateModalshows the full chain + PEM with copy-to-clipboard. - Retention
retention.host_tls_certs_days(default 30).
Topology visualization & neighbor identity
- Network topology page (
/topology) — full-network radial tree (EChartstree, newly tree-shaken in). Node color by device type, edge color by protocol, dashed edges for unidentified neighbors. Network filter + 60s auto-refresh; click a node → detail page. - Neighbor identity inference — CDP/LLDP neighbors get vendor/model/type inferred from their platform string via the RuleClassifier;
EnrichDeviceByMACenriches a device by MAC (the neighbor merge key), preserving existing non-empty values. - Device-detail Neighbors panel — table of a device's L2 neighbors with resolved name/IP/type (
neighbor_device_idwas always NULL in v0.2.0; now resolved at query time).
Container images & deployment profiles
The scanner's ICMP/ARP/MAC discovery is network-namespace-sensitive. Measured on the test LAN: the default docker bridge found 0/26 device MACs vs 30/31 with host networking — because /proc/net/arp inside a NAT'd container only sees the bridge gateway. v0.3.0 ships three compose profiles so you pick the deployment shape by intent:
| Profile | Probe fidelity | Use case |
|---|---|---|
bridge (default) |
TCP/SNMP/HTTP ok; MAC/ARP degraded | UI demo, dev |
host (recommended) |
≈ bare-metal | production scanning |
macvlan |
own LAN IP, ARP works | container as a LAN device |
Multi-arch images now auto-publish to GHCR on every v* tag. Pull and run:
docker pull ghcr.io/mi-bee-studio/mibeesteward:0.3.0
docker run -d --name mibee --network host \
--cap-add NET_RAW --cap-add NET_ADMIN \
-v mibee-data:/data \
-v "$PWD/config.yaml:/app/configs/config.yaml:ro" \
ghcr.io/mi-bee-studio/mibeesteward:0.3.0See docs/{en,zh}/deployment.md § "Docker network mode selection" for the full comparison and make docker-* targets.
Operational
- Retention hardening —
device_neighborsandhost_servicesnow have sweepers (they grew unbounded in v0.2.0). Defaults: 90d neighbors, 30d host_services; per-tableretention.*config +days<=0safety guard. - Test coverage — taskservice (scan-task state machine, previously zero-tested) and a fingerprint golden test (quality regression guard on real-world evidence samples).
- Fingerprint library — extended
snmp-data.yamlwith consumer/SMB sysObjectID prefixes (ASUS, D-Link, Zyxel, Tenda, DrayTek); newlldp-cdp.yamlrules. - Fixes: removed deprecated
tls.VersionSSL30(staticcheck SA1019); gofmt + golangci-lint cleanup (QF1008, unused params, embedded selectors); latent sqlc v1.27.0 codegen bug (non-ASCII char in a query comment corrupted sibling-query codegen). - CI — a
docker-buildsmoke-test job now boots the image and waits for/healthon every PR, so Dockerfile/compose regressions surface before a tag.
See the CHANGELOG and the deployment guide for full details.
Full diff: v0.2.0...v0.3.0