Add site gateway role (modules/router) and gw-cnx-1

Reusable cnx.router.* module for the Topton 1U boxes replacing OPNsense:
PPPoE WAN (optionally VLAN-tagged, AIS: 10, secret credentials incl.
username), VLAN-filtering bridge, nftables NAT/firewall with MSS clamp,
Kea DHCP with per-VLAN lease time, Blocky DNS, DHCPv6-PD, CrowdSec with
the ZeroTier mesh whitelisted, optional Omada controller, ZFS disk.

Fleet baseline rides along: admins sops group is now derived for every
machine in clan.nix (secrets encrypt to it from the first vars generate)
and time sync is chrony everywhere instead of systemd-timesyncd.
This commit is contained in:
Berwn
2026-07-28 17:06:07 +07:00
parent a87b579eb7
commit 158252323f
20 changed files with 857 additions and 31 deletions
+23 -9
View File
@@ -1,18 +1,27 @@
let
hosts = import ./modules/hosts.nix;
# Single source of the machine list: inventory AND the per-machine baseline
# below are both derived from it, so no machine can be added without the
# baseline (e.g. admins group encryption for all its generated secrets).
fleet = {
control = { };
ns1 = { };
ns2 = { };
mx1 = { };
web01 = { };
# Site gateways (Topton 1U routers): dynamic PPPoE WAN, so they are NOT in
# modules/hosts.nix / the `internet` instance — clan reaches them over the
# zerotier mesh (or Tor) instead.
gw-cnx-1 = { };
};
in
{
# Ensure this is unique among all clans you want to use.
meta.name = "cnx-network-clan";
meta.domain = "cnx-network.internal";
inventory.machines = {
control = { };
ns1 = { };
ns2 = { };
mx1 = { };
web01 = { };
};
inventory.machines = fleet;
inventory.instances = {
@@ -65,6 +74,11 @@ in
};
};
machines = {
};
# Fleet-wide baseline applied to every machine. Secrets minted by
# `clan vars generate` are encrypted for the admins group from the very
# first run — generating before this took effect is what forced the
# re-encryption dance (`clan vars fix`) on gw-cnx-1.
machines = builtins.mapAttrs (_: _: {
clan.core.sops.defaultGroups = [ "admins" ];
}) fleet;
}