From 71e5b167c3792f4cc50e76cdf73bc4495e052dca Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 19 Aug 2026 04:43:20 +0000 Subject: [PATCH] docs: close out the SNMP rotation, residual and all MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit All four devices are rotated and polling. Three refuse their old community; the switch does not, and that is now an accepted risk rather than an open question. Its firmware does not persist a deletion from the SNMP community table — the row can be removed, applied and saved, and it is still there after a restart. Verified after a reboot, so the result reflects saved configuration rather than a stale agent. Each attempt also drops the SNMP agent until the switch is rebooted, and it is the switch the whole network runs through, so the cost of chasing it exceeds what it buys. What it buys is small: the community is read-only, and reaching UDP/161 on 10.7.7.2 needs both a foothold on the management VLAN and the specific pfSense rule permitting 10.0.99.20 to reach it. Recorded rather than quietly dropped, which is the standard this file already sets for the exposures above it. The roadmap item is narrowed to overwriting that row with a fresh value rather than deleting it, next time the switch is down anyway. Closes #9 Co-Authored-By: Claude Opus 5 --- SECURITY.md | 26 +++++++++++++++++--------- docs/roadmap.md | 14 +++++++------- docs/security.md | 11 +++++------ 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/SECURITY.md b/SECURITY.md index 650a646..e5c7191 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -38,18 +38,26 @@ is a very different thing from an overlooked one. Full detail in | What | Status | | --- | --- | -| SNMP community committed in plaintext, shared across firewall, switch, UPS and BMC | Removed from `HEAD` and replaced with four distinct per-device SOPS-encrypted values. Rotated and verified on the firewall, the UPS and the BMC: each answers to its own new community and refuses the old one. **Not rotated on the switch**, which is not answering SNMP — so whether it still accepts the old community is unknown, not proven clean. **Still present in git history.** Treat the old string as public. | +| SNMP community committed in plaintext, shared across firewall, switch, UPS and BMC | Removed from `HEAD` and replaced with four distinct per-device SOPS-encrypted values. Rotated on all four devices; each answers to its own new community. The firewall, the UPS and the BMC additionally refuse the old one. **The switch still accepts its previous community alongside the new one** — see below. **The original shared string is also still present in git history.** Treat both as public. | | Grafana `admin`/`admin` with anonymous Admin access enabled | Fixed — anonymous auth off, password from SOPS | | Passphrase-encrypted TLS private keys under `certificates/` | Removed from `HEAD`, still reachable in history. Purge tooling and a runbook are provided; not yet run. | -The switch is the honest gap. `10.7.7.2` has returned `up == 0` for every scrape -the monitoring stack has ever taken — all four SNMP series begin together when -the stack was rebuilt, so the failure predates the rotation and is not evidence -that the rotation broke anything. Nor is its silence evidence that the old -community was removed. It is reachable at layer 3 on ICMP and TCP/80; only -UDP/161 fails, which is the signature of a wedged SNMP agent rather than a dead -device. Tracked separately in -[#22](https://github.com/Gerrrt/HomeLab/issues/22). +The switch is the honest gap, and it is a deliberate one. `neo` (10.7.7.2) is +rotated and polling, but it also still accepts the community it held before the +rotation, verified after a reboot so the result reflects its saved +configuration rather than a stale agent. Its firmware does not persist a +deletion from the SNMP community table: the row can be removed, applied and +saved, and the entry is still there after a restart. Each attempt also drops +the SNMP agent until the switch is rebooted, and it is the switch the whole +network runs through. + +The residual risk is accepted rather than overlooked. The community is +read-only, and reaching UDP/161 on `10.7.7.2` requires both a foothold on the +management VLAN and the specific pfSense rule that permits `10.0.99.20` to +reach it — it is not exposed beyond the management segment. The way to close it +without fighting the firmware is to overwrite that row with a fresh value +rather than delete it, on some future pass when the switch is already being +taken down for something else. Remediation is tracked in [`docs/roadmap.md`](docs/roadmap.md), with procedures in [`docs/runbooks/rotate-snmp-community.md`](docs/runbooks/rotate-snmp-community.md) diff --git a/docs/roadmap.md b/docs/roadmap.md index c2e0935..deef58e 100644 --- a/docs/roadmap.md +++ b/docs/roadmap.md @@ -5,13 +5,13 @@ inventory. Ordered roughly by how much it matters. ## Security -- [ ] **Finish the SNMP rotation on the MokerLink switch (`neo`, 10.7.7.2).** - pfSense, the APC and iLO are done — each answers to its own new community - and refuses the old one. The switch is not, and cannot be verified, - because it is not answering SNMP: `up{job="snmp"}` for `10.7.7.2` has - been `0` for every scrape the current stack has taken, so the failure - predates the rotation rather than being caused by it. Blocked on - [#22](https://github.com/Gerrrt/HomeLab/issues/22). +- [ ] **Retire the MokerLink switch's previous SNMP community.** All four + devices are rotated, but `neo` still accepts its old community alongside + the new one: its firmware does not persist a deletion from the community + table, and each attempt drops the SNMP agent until the switch is + rebooted. Low priority and accepted for now — the community is read-only + and reachable only from the management VLAN. Overwrite the row with a + fresh value rather than deleting it, next time the switch is down anyway. → [runbook](runbooks/rotate-snmp-community.md) - [ ] **Purge `certificates/` and the old community string from git history**, then regenerate the CA and leaf certificates. diff --git a/docs/security.md b/docs/security.md index 7fea25d..dbcfff0 100644 --- a/docs/security.md +++ b/docs/security.md @@ -59,7 +59,7 @@ repository must be treated as compromised: | What | Where | Status | | --- | --- | --- | -| SNMP community shared across all four devices | `snmp.yaml`, from commit `ee3d443` | Replaced with four distinct per-device values, SOPS-encrypted. Rotated on `morpheus`, `mjolnir` and `shiva`, each verified answering its new community and refusing the old. **Not rotated on `neo`** — see [#22](https://github.com/Gerrrt/HomeLab/issues/22) and the [runbook](runbooks/rotate-snmp-community.md) | +| SNMP community shared across all four devices | `snmp.yaml`, from commit `ee3d443` | Replaced with four distinct per-device values, SOPS-encrypted. Rotated on all four. `morpheus`, `mjolnir` and `shiva` verified answering the new community and refusing the old; `neo` answers the new one but still accepts its previous community — accepted risk, see [`SECURITY.md`](../SECURITY.md) and the [runbook](runbooks/rotate-snmp-community.md) | | Grafana `admin` / `admin` with anonymous Admin access | compose file | Fixed: password from SOPS, anonymous auth disabled | | Passphrase-encrypted TLS private keys | `certificates/`, added in `efb2632`, deleted in `647d90a` but reachable at `647d90a~1` | Still in history. **Purge and regenerate** — see [runbook](runbooks/purge-git-history.md) | @@ -79,11 +79,10 @@ The devices are polled with SNMPv2c, which transmits the community string in cleartext. Anyone with a port on the management VLAN can read it off a single packet. Two mitigations are in place, one only partly, and one is not: -- **Done, with one exception:** each device has its own community, so one - captured packet no longer grants read access to the whole fleet. Three are - confirmed live on the hardware. The switch's exists only in SOPS — it has - never been proven on the device, because `10.7.7.2` is not currently answering - polls ([#22](https://github.com/Gerrrt/HomeLab/issues/22)). +- **Done:** each device has its own community, confirmed live on all four, so + one captured packet no longer grants read access to the whole fleet. The + switch does still accept its own previous community as well — an accepted + residual, recorded in [`SECURITY.md`](../SECURITY.md). - **Done:** SNMP is reachable only on the management VLAN and the switch-management LAN, neither of which anything but specific trusted hosts can enter.