Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 17 additions & 9 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
14 changes: 7 additions & 7 deletions docs/roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
11 changes: 5 additions & 6 deletions docs/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -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) |

Expand All @@ -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.
Expand Down
Loading