Ops & Security
This is a five-player cozy modded server. It is also a working proof-of-concept:
a hobby workload run with the controls, evidence, and discipline of a regulated one —
SOC 2, ISO 27001, and NIST CSF mappings included. Everything on this page is
backed by version-controlled artifacts in the
public repository:
the threat model, the pentest report, the runbooks, and the incidents. Especially the incidents.
18
Pentest Findings Tracked
428
Homestead Mods Verified
DUAL
Two packs, two services, separate worlds
- Homestead remains on Fabric 1.20.1 at mc.geigercapital.us while SkyFactory 4.2.4 runs on Forge 1.12.2 at sb.geigercapital.us.
- Each service has its own runtime directory, world, Java version, game port, and RCON port. Neither process opens the other server's world.
- The Minecraft TCP listeners on 25565 and 25566 are reachable publicly. RCON 25575 and 25576 remain denied by both firewall layers.
- SkyFactory is controlled independently through a manual GitHub Actions workflow and can be stopped without interrupting Homestead.
· 01 · observability ·
30D
Both worlds measured, failures routed
- Homestead and SkyFactory have separate loopback-only metric exporters and labels, while a node collector reports service state and per-world backup freshness.
- Prometheus rules cover scrape failures, current and forecast disk pressure, memory, sustained CPU load, stale backups, collector health, Cloudflare tunnel redundancy, Loki health, configuration failures, and write-ahead-log corruption. Alertmanager groups and routes the resulting notifications to ntfy.
- Version-controlled Grafana dashboards show host capacity, service and exporter health, backup age, active alerts, tunnel connections, log ingestion, errors, Minecraft events, audit records, and the backup lifecycle. Metrics and logs have bounded retention to protect the game host from unbounded monitoring growth.
- Loki retains 14 days of centralized logs while Alloy collects both profile logs, structured audit events, backup operations, Nginx, cloudflared, and the systemd journal. Both services and their metrics endpoints remain loopback-only.
- Monthly disposable restore drills fully extract each profile's newest archive and validate its world structure. Seven-day availability, player capacity, restore results, and selected game activity are tracked in a dedicated service-level dashboard, with a weekly health digest delivered through ntfy.
- Browser administration is designed for Cloudflare Access over an outbound tunnel. Grafana and Uptime Kuma stay on localhost; Prometheus, Alertmanager, exporters, and RCON are not published.
· 02 · pipeline ·
CI/CD
Nothing lands by hand
- Main is protected for normal changes. Authorized administrator updates may use the audited bypass path when an operational change must deploy directly.
- Merging to main triggers an automated deploy: runtime files are packaged, installed on the server, services restarted, and health-validated (local API checks, metrics presence, config dry-runs) before the deploy counts as done.
- CodeQL and OWASP ZAP scan on a weekly schedule; Checkov lints the infrastructure config; Dependabot keeps dependencies current; gitleaks blocks secrets at commit time. Security-sensitive third-party CI actions are pinned to exact commit hashes.
- The deploy account on the server is a dedicated user with sudo scoped to the exact commands the pipeline needs — not an admin login.
· 03 · backups ·
00:45
Homestead backups that are proven, not assumed
- Every night, Homestead receives a world-consistent snapshot: saving is paused and flushed first, the archive is written atomically, and a free-disk preflight makes exhaustion fail loudly.
- 45 minutes later, an automated job extracts and checks the newest archive and logs a PASS or FAIL — because a backup that has never been restored from is a hope, not a backup.
- 30 minutes after that, retention pruning keeps the archive set under a fixed disk budget — always preserving the newest verified copies, and refusing to run at all if nothing healthy would remain.
Why it looks like this
- On August 13, 2026 we discovered the hard way: the disk had silently filled, three nights of backups were truncated garbage, and manual cleanup had preserved the corrupt newest files while deleting the older good ones. For a window of days, zero valid backups existed. The full post-incident report is public in the repository — every safeguard above exists because that day demanded it.
· 04 · supply chain ·
SHA
428 Homestead mods, none of them on trust
- Every mod jar on the server is SHA-256 baselined. The server refuses to start if any jar fails verification — the integrity check is a boot gate, not a report.
- A file watcher monitors the mods directory in real time and flags any change for manual review.
- Custom API, audit, and integrity services run inside narrow systemd sandboxes. A reviewed-path checksum gate and recursive watcher protect the deployed KubeJS and CraftTweaker script trees without automatically trusting generated pack content.
- New mods enter through a gated installer: the artifact is pinned to an exact upstream release, SHA-512 verified before it touches the server, checked against the running loader's declared compatibility constraints, and installed with an automatic rollback if the server doesn't boot cleanly.
- A software bill of materials tracks what runs and where it came from.
· 05 · security ·
F-001
Findings get numbers, and numbers get closed
- A STRIDE threat model covers every component — game protocol, remote console, map server, CI/CD, mod supply chain — with a risk register reviewed quarterly.
- An April 2026 penetration test produced 18 tracked findings. Each carries a status, evidence, and control references; remediations are documented, not just done.
- Case study — finding F-001: the metrics exporter exposed a credential in the server's process list. It took a compensating-control phase, an exporter upgrade, and an environment-based credential handoff to close it — four months from finding to verified fix, with the credential rotated afterward because it had been exposed. The whole arc is in the public pentest report.
- Day to day: key-only SSH with session auditing, fail2ban, host and provider firewalls default-deny, TLS with strict security headers on every web surface, administrative and reverse-proxied backends bound to localhost, and a structured audit log classifying joins, leaves, op grants, and console commands.
- September hardening check: Grafana and BlueMap were moved to localhost-only listeners and verified healthy; RCON and monitoring ports were confirmed unreachable externally; backups, timers, exporters, availability monitoring, API, and game services all passed live checks.
· 06 · performance ·
3.4%
Optimized by profiler, not by folklore
- August 2026: a spark profile under real player load measured 19.97 TPS with comfortable headroom per tick — after a server-side performance stack (Lithium, FerriteCore, ModernFix, Krypton) was installed one gated phase at a time.
- The profile attributed just 3.4% of tick time to Create, the pack's flagship mod — so two further "Create optimizer" mods that folklore recommends were declined, with the reasoning recorded. Restraint is also an optimization decision.
- The world was pre-generated to a 10,000-block radius, which is why chunk generation contributes nothing to tick time — and why the world (and its backups) stay a predictable size.
· 07 · timeline ·
2026
The paper trail so far
April 2026
- Server launch, then the SDLC proof-of-concept: repository, CI/CD scaffolding, 30-control framework, STRIDE threat model, baseline penetration test (18 findings), hardening audit.
May 2026
- Public-readiness review and v1.1 summary; post-audit follow-up hardened the deploy pipeline, backup verification, and web security headers. Automated deploys with health validation went live.
August 2026
- Quarterly threat-model review (no new threats). Dependency refresh across the pipeline.
- Backup integrity incident: found, fixed, and published the same day — and the entire backup lifecycle was rebuilt as code with scheduled verification and disk-budget retention.
- F-001 closed with evidence after four months; the exposed credential rotated.
- Performance stack installed through the supply-chain gate; profiled under load; optimizer decisions documented, including the ones declined.
September 2026
- Small attack-surface pass completed: administrative backends moved to localhost where supported, external firewall isolation re-verified, and the audit logger repaired to follow Minecraft log rotation safely.
- Public site security headers made explicit and automated regression coverage added for audit logging and shell syntax.