Commit Graph
6 Commits
Author SHA1 Message Date
Ryan Yin 1324131c6d docs: correct statements that no longer match the configuration
Assisted-by: DeepSeek Harness 0.2.1-rc.2 (claude-opus-5-5)
2026-10-21 20:59:07 +08:00
ryan4yin | 二花 3694961e74 fix(postgres,darwin): close the loopback superuser path and scope agenix ownership (#401)
* fix(postgres): require a password for superuser over TCP

* test: assert the postgres loopback auth rules

* fix(darwin): keep root-only agenix secrets root-only

* docs(security): record the local auth boundaries and retire WA-015
2026-10-07 15:22:03 +08:00
ryan4yin | 二花 e5b95affa6 feat(nixos): default-deny host inbound, trust the LAN/tailnet (#325)
Hosts used to trust the router as the only boundary (servers ran with the
firewall off; service ports were opened globally), so any LAN device could
reach every host service. Move filtering to the hosts as defence in depth
behind the router, which keeps its firewall on and uses a port mapping for
the few ports we actually need.

- base: nftables backend; deny inbound by default; trust the home LAN by
  source and the tailnet by interface (restrict the tailnet with ACLs);
  suppress per-service `openFirewall` global ports; allow node_exporter only
  from the monitoring host. The local podman bridge, the tailnet and the pod
  CIDRs are accepted only after the node_exporter drop.
- servers: stop disabling the firewall; drop redundant global port opens
  (caddy 80/443, NFS 2049, Jellyfin, localsend/test ports); delete the
  redundant desktop firewall module; aarch64/riscv64 import the firewall
  explicitly (akane was missing it).
- k3s: Cilium pods (10.0.0.0/8, fd00::/8) may reach host services; drop the
  flannel-era cni0/flannel.1 trust.
- youko: postgres listens on localhost + the LAN with pg_hba limited to the
  LAN; the NFS export stays LAN-scoped; remove the unauthenticated v2ray
  proxy.
- tests: `security-firewall` asserts every host runs the shared firewall, has
  the LAN CIDR rule and no global ports.
2026-09-26 14:02:03 +08:00
ryan4yin | 二花 bb33cca83a refactor(youko): let preservation own the service state dirs (#298)
* refactor(youko): let preservation own the service state dirs

The services' data now sits on the SSD, so the hand-written dataDir +
systemd.tmpfiles rules are unnecessary: /var/lib is already preserved by
preservation, and the upstream modules create and own their default
state dirs (StateDirectory). Use the defaults:

- gitea /var/lib/gitea, grafana, sftpgo, caddy, victoriametrics,
  postgresql (/var/lib/postgresql/<version>), uptime-kuma, homepage
- drop the per-service tmpfiles rules and victoriametrics' self-bind

Data was moved in place with mv (same filesystem): /persistent/apps/<svc>
(== /var/lib/<svc> via the preservation bind) so nothing was copied.

* refactor(youko): drop caddy's redundant tmpfiles rules

The activation script already creates the fileserver tree with mkdir -p and
the module creates caddy's dataDir, so the rules - and the unused vms
directory they created - are redundant.

* refactor(youko): use a podman named volume for uptime-kuma

podman creates the volume and takes the ownership from the image, so the
kuma user, the tmpfiles rule and the host directory are no longer needed;
the volume lives under /var/lib/containers, which preservation keeps.
2026-09-21 18:06:40 +08:00
Ryan Yin a755b6fa11 feat(youko): move the service data from the HDD to the SSD
The services now run directly on the host, so their state does not belong
on the HDD behind the flaky USB-SATA bridge: /data/apps was small-file
heavy and latency/consistency sensitive. Point every dataDir at
/persistent/apps (the LUKS nvme) instead.

The HDD keeps the bulk data that suits it: /data/fileshare (173G) and
/data/backups (24G). The HDD's old @apps subvolume and its data are left
in place for now.
2026-09-21 17:56:35 +08:00
Ryan Yin 2c7629000f refactor: rename the three VM hosts to 12kingdoms-*
Drop the now-meaningless kubevirt- prefix and move the hosts out of
hosts/k8s/, following the existing 12kingdoms-shoukei layout: the
directory and output carry the theme prefix while the configuration,
hostname and colmena target are the bare name (shoryu, shushou, youko).

- hosts/k8s/kubevirt-* -> hosts/12kingdoms-*; the shared disko config
  becomes host-disko-fs.nix; the now-different relative imports are fixed
- outputs, vars/networking.nix keys, the Justfile recipes/tags, the eval
  tests and the docs follow
- colmena reaches these hosts by IP (a new targetHost override), since
  their DNS name changes with the hostname and is not resolvable until
  the router learns it
2026-09-21 17:10:14 +08:00