DEV Community

Cover image for My NAS kept its encryption keys on itself — so I built a KMIP server into my open-source monitoring tool
tyxak
tyxak

Posted on

My NAS kept its encryption keys on itself — so I built a KMIP server into my open-source monitoring tool

I maintain RemotePower, an open-source (MIT)
self-hosted control plane for a small fleet or a homelab — monitoring, alerting,
CVE scanning, patching, a CMDB. It started as a tool for my own machines and
grew from there. Version 6.4.1 just shipped, and the headline feature came out
of a realisation that had been quietly bothering me for a while.

The itch

My Synology encrypts its volumes. Good. It stores the encryption keys for those
volumes... on the Synology. Same box, same disks, same burglar. Whoever walks
off with the appliance gets the lock and the key together, which defeats a lot
of the point of encrypting at all.

The industry already has an answer: KMIP (Key Management Interoperability
Protocol), the OASIS standard that lets an appliance fetch its keys from an
external key manager at mount time. Synology DSM, TrueNAS and VMware vSphere
all speak it natively. The problem is the other end of the conversation —
everything I found that implements the server side is an enterprise appliance
or a heavyweight commercial suite. There was no small, self-hostable KMIP
server a homelab could point a NAS at.

So I built one into the tool that was already monitoring those boxes.

What it looks like

It's deliberately conservative in design:

  • Off by default. Nothing listens until you enable it.
  • A separate, sandboxed sidecar (remotepower-kmipd on tcp/5696) that terminates mutual TLS and parses the KMIP wire format — and holds no keys, no database access, no master key. It runs under systemd DynamicUser=yes with no access to the data directory. All the material that matters (the CA, the key objects, encryption at rest, the activity log) lives behind the main API, reached over loopback with a shared secret.
  • Mutual TLS only. Enabling it generates a private CA; each appliance gets its own client certificate through a three-step wizard, and the private key is shown once and never stored server-side.
  • An encrypted recovery bundle, because key custody without a way back isn't a feature — it's a liability.

Setup is one installer flag:

sudo ./install-server.sh --with-kmip
Enter fullscreen mode Exit fullscreen mode

The supported operation set is deliberately matched to what DSM actually calls
in practice (an appliance that hits an unimplemented KMIP operation tends to
abort its whole setup with a generic error, so partial support is worse than
none).

The footgun, stated plainly

External key custody has a real trade-off, and I'd rather write it here than
have someone discover it at 2am: once an appliance stores its keys here, it
needs this server reachable at its own boot time to mount encrypted storage.
A NAS that keeps its keys on a VM hosted by that same NAS will not come back
from a reboot. That circular dependency is the classic self-hosted key-server
mistake, and the docs lead with it.

Two things in 6.4.1 exist specifically to soften the sharp edges: the key
server now has its own row on the server-status page (it was the one sidecar
without one, despite being the one whose outage stops volumes mounting), and it
warns ahead of its own certificate expiry — because an expired client cert
silently ends an appliance's access to its keys, and the failure surfaces at
the next reboot, which is the worst possible moment.

The rest of the release

Less glamorous, but honest work:

  • A per-destination minimum severity filter that had never filtered — the saved values sat in a range below every event's actual priority, so all four choices behaved identically. It works now, and existing settings keep exactly the behaviour they had, so nobody's alerting changes without asking.
  • Laptops on Windows and macOS report like laptops. Three signals were Linux-only, which left the laptop features dead on precisely the hosts they were designed for: a closed lid was treated like a dead server instead of getting the grace period, and battery health never reached the alerts.
  • A UI pass for the small stuff — one body size, one icon size, buttons that sit in a row, panels that scroll instead of growing without limit.

Try it
There's a read-only demo seeded with synthetic devices, alerts and CVEs —
no install needed: https://demoremote.tvipper.com (login demo / demo, resets every few hours).
Code and docs: https://github.com/tyxak/remotepower
It's a one-person project and I have no illusions about that. If you've run key
servers in production — or you can poke a hole in the KMIP design — I would genuinely rather hear it from you than from an incident. Issues and discussions
are open.

Top comments (0)