Upgrade clan to 26.05
Bump clan-core and nixos-mailserver to 26.05 (NixOS 26.05) and adapt to
the breaking changes surfaced by nix flake check:
- mesh-hosts/clan.nix: read the new shared, instance-scoped zerotier vars
(zerotier-ip-<machine>-zerotier, zerotier-network-zerotier); admit
external members via the controller's native allowedIds.
- monitoring/server.nix: Grafana lost its built-in secret_key default;
mint one via a clan generator and pass it with $__file{}.
- dns/authoritative.nix: services.resolved.extraConfig removed -> settings.
- mail.nix: SNM cert API change (x509.useACMEHost + acme extraDomainNames)
and accounts/dkim option renames.
- docs: mesh runbook updated for the new var paths and allowedIds.
This commit is contained in:
@@ -32,7 +32,7 @@ in
|
||||
|
||||
# knot binds 0.0.0.0@53 and ::@53, so free port 53 by disabling the
|
||||
# systemd-resolved stub listener. Resolution still works via nss-resolve.
|
||||
services.resolved.extraConfig = "DNSStubListener=no";
|
||||
services.resolved.settings.Resolve.DNSStubListener = "no";
|
||||
|
||||
services.knot = {
|
||||
enable = true;
|
||||
|
||||
+12
-10
@@ -98,29 +98,31 @@ in
|
||||
|
||||
mailserver = {
|
||||
enable = true;
|
||||
# Fresh install: declare the latest layout the nixos-25.11 branch ships (3),
|
||||
# Fresh install: declare the latest layout the nixos-26.05 branch ships (3),
|
||||
# so SNM uses the current dovecot mail directory layout with nothing to migrate.
|
||||
stateVersion = 3;
|
||||
inherit fqdn;
|
||||
domains = [ "cnx.email" ];
|
||||
inherit loginAccounts;
|
||||
accounts = loginAccounts;
|
||||
|
||||
# Consume a security.acme cert we obtain ourselves via DNS-01 (below); no
|
||||
# web server and no inbound HTTP needed, so port 80 stays closed. Add the
|
||||
# MTA-STS host as a SAN so the one cert also covers the policy endpoint.
|
||||
certificateScheme = "acme";
|
||||
certificateDomains = [
|
||||
mtaStsHost
|
||||
clientHost
|
||||
];
|
||||
# web server and no inbound HTTP needed, so port 80 stays closed. The extra
|
||||
# SAN hosts (MTA-STS, client alias) are attached to that cert via
|
||||
# security.acme.certs.${fqdn}.extraDomainNames below.
|
||||
x509.useACMEHost = fqdn;
|
||||
|
||||
dkimSelector = "mail";
|
||||
dkim.defaults.selector = "mail";
|
||||
};
|
||||
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = "postmaster@cnx.email";
|
||||
certs.${fqdn} = {
|
||||
# The MTA-STS endpoint and client-facing alias ride this one cert as SANs.
|
||||
extraDomainNames = [
|
||||
mtaStsHost
|
||||
clientHost
|
||||
];
|
||||
dnsProvider = "rfc2136";
|
||||
environmentFile = config.clan.core.vars.generators.dns-acme-rfc2136.files."rfc2136.env".path;
|
||||
# ns1 is the only nameserver that accepts the acme_mx1 UPDATE; check
|
||||
|
||||
+11
-7
@@ -2,16 +2,20 @@
|
||||
# DNS zone transfers and metrics scraping ride this mesh, never the public net.
|
||||
#
|
||||
# Rather than hardcoding the addresses, we read them from the public clan vars
|
||||
# that clan-core's zerotier generator already writes per machine
|
||||
# (vars/per-machine/<m>/zerotier/zerotier-ip/value). This keeps the mesh map in
|
||||
# that clan-core's zerotier service writes. As of clan-core 26.05 these are
|
||||
# shared, instance-scoped generators: the per-machine IP lives at
|
||||
# vars/shared/zerotier-ip-<machine>-<instance>/ip and the network id at
|
||||
# vars/shared/zerotier-network-<instance>/network-id (instance = "zerotier",
|
||||
# the inventory.instances.zerotier name in clan.nix). This keeps the mesh map in
|
||||
# lockstep with the actual identities: regenerate or re-key a node and its
|
||||
# address here follows automatically. Call as: import ../mesh-hosts.nix { inherit config lib; }.
|
||||
{ config, lib }:
|
||||
let
|
||||
dir = config.clan.core.settings.directory;
|
||||
instance = "zerotier";
|
||||
|
||||
readVar =
|
||||
machine: file: builtins.readFile "${dir}/vars/per-machine/${machine}/zerotier/${file}/value";
|
||||
readIp =
|
||||
machine: builtins.readFile "${dir}/vars/shared/zerotier-ip-${machine}-${instance}/ip/value";
|
||||
|
||||
hosts = lib.genAttrs [
|
||||
"control"
|
||||
@@ -19,13 +23,13 @@ let
|
||||
"ns2"
|
||||
"mx1"
|
||||
"web01"
|
||||
] (m: readVar m "zerotier-ip");
|
||||
] readIp;
|
||||
|
||||
# RFC 4193 prefix of this ZeroTier network: fd + the 8-byte network id + the
|
||||
# 0x9993 marker. The network id is a public var on the controller (control).
|
||||
# 0x9993 marker. The network id is a public, shared var for the instance.
|
||||
# The /88 (11 bytes) covers fd + network id + 0x99 + 0x93, i.e. every mesh peer,
|
||||
# and is used to scope mesh-only firewall rules.
|
||||
networkId = readVar "control" "zerotier-network-id";
|
||||
networkId = builtins.readFile "${dir}/vars/shared/zerotier-network-${instance}/network-id/value";
|
||||
full = "fd" + networkId + "9993"; # 22 hex chars = 11 bytes
|
||||
hextet = i: builtins.substring (i * 4) 4 full;
|
||||
subnet = "${hextet 0}:${hextet 1}:${hextet 2}:${hextet 3}:${hextet 4}:${builtins.substring 20 2 full}00::/88";
|
||||
|
||||
@@ -25,6 +25,7 @@ let
|
||||
v6 = addr: "[${addr}]";
|
||||
|
||||
adminPasswordFile = config.clan.core.vars.generators.grafana-admin.files."password".path;
|
||||
secretKeyFile = config.clan.core.vars.generators.grafana-secret-key.files."secret-key".path;
|
||||
in
|
||||
{
|
||||
services.victoriametrics = {
|
||||
@@ -95,6 +96,22 @@ in
|
||||
'';
|
||||
};
|
||||
|
||||
# NixOS 26.05 removed the built-in default for services.grafana's secret_key
|
||||
# (used to sign/encrypt DB secrets). Mint our own instead of hardcoding the old
|
||||
# upstream default. Safe to generate fresh here: the provisioned datasources
|
||||
# carry no credentials, so nothing in Grafana's DB is encrypted with it.
|
||||
clan.core.vars.generators.grafana-secret-key = {
|
||||
files."secret-key" = {
|
||||
secret = true;
|
||||
owner = "grafana";
|
||||
group = "grafana";
|
||||
};
|
||||
runtimeInputs = [ pkgs.openssl ];
|
||||
script = ''
|
||||
openssl rand -base64 32 | tr -d "\n" > "$out"/secret-key
|
||||
'';
|
||||
};
|
||||
|
||||
services.grafana = {
|
||||
enable = true;
|
||||
# VictoriaLogs datasource plugin so journald is greppable from Grafana,
|
||||
@@ -109,6 +126,7 @@ in
|
||||
security = {
|
||||
admin_user = "admin";
|
||||
admin_password = "$__file{${adminPasswordFile}}";
|
||||
secret_key = "$__file{${secretKeyFile}}";
|
||||
};
|
||||
"auth.anonymous".enabled = false;
|
||||
users.allow_sign_up = false;
|
||||
|
||||
Reference in New Issue
Block a user