Skip to content

feat(admin-plane): Headscale and a public Grafana on sensorica-holoport-01 - #72

Draft
Soushi888 wants to merge 3 commits into
mainfrom
feat/sensorica-headscale
Draft

Soushi888 wants to merge 3 commits into
mainfrom
feat/sensorica-headscale

Conversation

@Soushi888

Copy link
Copy Markdown
Contributor

SoushAI analysis. Drafted by Soushi's AI assistant, reviewed and posted by @Soushi888.

Closes part of #70: the module, its test and the fleet wiring. Deployment (DNS, router, switch, joins) is tracked on the issue.

What changes

  • modules/admin-plane.nix, exported as nixosModules.admin-plane (not in default: one machine per fleet runs it, and it opens 80 and 443). Headscale on 127.0.0.1:8080 behind nginx with Let's Encrypt, a 403 "Private server" page on /, the machine's own Headscale name pinned to loopback, public DERP relays. grafana.domain puts Grafana on its own public name with its root URL rewritten and secure cookies. dnsDrift compares the site's public IPv4 with the public names every 15 minutes and publishes admin_plane_dns_matches_public_ip{name} through node_exporter, for registrars without a usable update API (GoDaddy under ten domains).
  • vmTestAdminPlane in checks and in CI.
  • sensorica-holoport-01 enables it: hs.sensorica.co, MagicDNS sensorica.internal, grafana.sensorica.co.
  • docs/admin-plane.md: site prerequisites, deploy, join, revoke, a change of IP, moving the server to another site. docs/module-options.md regenerated.

Same shape as the athanor homelab's Headscale, with the DDNS client replaced by the drift check. acmeEmail is optional so no personal address lands in the repository.

Proof

$ nix build .#checks.x86_64-linux.vmTestAdminPlane -L
subtest: Headscale answers through nginx, the bare name is private   (11.20 s)
subtest: Plain HTTP only redirects                                   (0.09 s)
subtest: Grafana answers on its public name with its public root URL (26.47 s)
subtest: A client joins the tailnet through the proxy                (9.49 s)
subtest: The drift check is installed                                (0.10 s)
test script finished in 72.02s
exit 0

$ nix flake check --no-build --all-systems
exit 0

$ cd examples/sensorica-fleet && nix eval --override-input nixos-holochain path:../.. .#nixosConfigurations.sensorica-holoport-01.config.services.admin-plane ...
{"enable":true,"g":"grafana.sensorica.co","hs":"hs.sensorica.co","td":"/var/lib/prometheus-node-exporter-text-files"}

The first test run failed usefully: Headscale exits at startup when it cannot fetch Tailscale's DERP map, and the sandbox has no internet. The test serves its own relay, as nixpkgs' headscale test does; production keeps the public map, so the admin-plane machine needs internet at boot.

A reusable module for the machine that coordinates a fleet's tailnet:
Headscale on loopback behind nginx and Let's Encrypt, a 403 private page
on the bare name, the machine's own name pinned to 127.0.0.1, and
optionally Grafana on its own public name. A DNS drift check publishes
admin_plane_dns_matches_public_ip for sites whose registrar cannot be
updated automatically.

vmTestAdminPlane joins a Tailscale client through the proxy, checks
/health, the 403 page, the port 80 redirect and Grafana's public root
URL. Refs #70.
hs.sensorica.co for Headscale (MagicDNS sensorica.internal) and
grafana.sensorica.co for Grafana, until a second site takes them over.
Refs #70.
…ertificate-checking health

Both units join services.holochain-services with their versions, and each
gets a health check through nginx by its public name that verifies the
certificate, so the home page reads Not answering while nginx serves the
self-signed placeholder a failed ACME order leaves. The Grafana name is
pinned to loopback like the Headscale one so the checks never depend on
the router's hairpin. The VM test reads both as healthy. Refs #70.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant