Files
cnx-network-clan/modules/clan/router/default.nix
2026-09-17 08:57:32 +07:00

68 lines
2.4 KiB
Nix

# Site gateway (OPNsense replacement) for the Topton 1U boxes, as a clan
# service: PPPoE WAN, VLAN-filtering bridge over the LAN ports, per-VLAN
# DHCP/DNS, firewall/NAT, and the optional Omada controller / internal proxy.
#
# Exported as `clan.modules.router` of this flake; used here with
# `module.input = "self"` and from other clans with `module.input =
# "<this flake's input name>"`. README.md has the consumer view. A site joins
# through the inventory:
#
# inventory.instances.router = {
# module = { name = "router"; input = "self"; };
# roles.default.settings.mesh.subnet = ...; # fleet-wide
# roles.default.machines.gw-<city>-<n>.settings = { site = ...; ... };
# };
#
# The settings schema lives in interface.nix. Implementation files that need
# the settings are functions `{ settings }: <NixOS module>`; the evaluated
# settings are handed in with importApply so nothing goes through
# machine-level options. The rest are plain NixOS modules.
{ lib, ... }:
{
_class = "clan.service";
manifest.name = "router";
manifest.description = "Site gateway: PPPoE WAN, VLAN bridge, DHCP/DNS, firewall/NAT";
manifest.categories = [ "Network" ];
manifest.readme = builtins.readFile ./README.md;
roles.default = {
description = "Turns the machine into the site's router (one instance per machine).";
interface = ./interface.nix;
perInstance =
{ settings, machine, ... }:
{
nixosModule.imports = [
./ipv6.nix
]
# The proxy's TSIG secret is shared with the nameserver (acme-secret.nix).
++ lib.optional settings.proxy.enable (import ./acme-secret.nix machine.name)
++ map (file: lib.modules.importApply file { inherit settings; }) [
./network.nix
./pppoe.nix
./firewall.nix
./dns-dhcp.nix
./crowdsec.nix
./omada.nix
./proxy.nix
./iperf.nix
./speedtest.nix
./wifi.nix
];
};
};
# A machine has exactly one WAN port and one VLAN layout; two instances would
# both claim br0/ppp0 and fight over Kea/Blocky/nftables.
perMachine =
{ instances, machine, ... }:
{
nixosModule.assertions = [
{
assertion = lib.length (lib.attrNames instances) == 1;
message = "router: ${machine.name} is a gateway in several instances (${lib.concatStringsSep ", " (lib.attrNames instances)}); a machine can only be one router.";
}
];
};
}