feat[server]: preparations for router config

This commit is contained in:
Leon Schwarzäugl 2025-11-10 01:28:25 +01:00
parent e1569ba472
commit 30a97098af
Signed by: swarsel
GPG key ID: 26A54C31F2A4FD84
31 changed files with 586 additions and 92 deletions

View file

@ -4,6 +4,91 @@ let
mkOption
types
;
networkOptions = netSubmod: {
cidrv4 = mkOption {
type = types.nullOr types.net.cidrv4;
description = "The CIDRv4 of this network";
default = null;
};
subnetMask4 = mkOption {
type = types.nullOr types.net.cidrv4;
description = "The dotted decimal form of the subnet mask of this network";
readOnly = true;
default = lib.swarselsystems.cidrToSubnetMask netSubmod.cidrv4;
};
cidrv6 = mkOption {
type = types.nullOr types.net.cidrv6;
description = "The CIDRv6 of this network";
default = null;
};
hosts = mkOption {
default = { };
type = types.attrsOf (
types.submodule (hostSubmod: {
options = {
id = mkOption {
type = types.int;
description = "The id of this host in the network";
};
mac = mkOption {
type = types.nullOr types.net.mac;
description = "The MAC of the interface on this host that belongs to this network.";
default = null;
};
ipv4 = mkOption {
type = types.nullOr types.net.ipv4;
description = "The IPv4 of this host in this network";
readOnly = true;
default =
if netSubmod.config.cidrv4 == null then
null
else
lib.net.cidr.host hostSubmod.config.id netSubmod.config.cidrv4;
};
ipv6 = mkOption {
type = types.nullOr types.net.ipv6;
description = "The IPv6 of this host in this network";
readOnly = true;
default =
if netSubmod.config.cidrv6 == null then
null
else
lib.net.cidr.host hostSubmod.config.id netSubmod.config.cidrv6;
};
cidrv4 = mkOption {
type = types.nullOr types.str; # FIXME: this is not types.net.cidr because it would zero out the host part
description = "The IPv4 of this host in this network, including CIDR mask";
readOnly = true;
default =
if netSubmod.config.cidrv4 == null then
null
else
lib.net.cidr.hostCidr hostSubmod.config.id netSubmod.config.cidrv4;
};
cidrv6 = mkOption {
type = types.nullOr types.str; # FIXME: this is not types.net.cidr because it would zero out the host part
description = "The IPv6 of this host in this network, including CIDR mask";
readOnly = true;
default =
if netSubmod.config.cidrv6 == null then
null
else
lib.net.cidr.hostCidr hostSubmod.config.id netSubmod.config.cidrv6;
};
};
})
);
};
};
in
{
options = {
@ -39,12 +124,44 @@ in
);
};
networks = mkOption {
default = { };
type = types.attrsOf (
types.submodule (netSubmod: {
options = networkOptions netSubmod // {
vlans = mkOption {
default = { };
type = types.attrsOf (
types.submodule (vlanNetSubmod: {
options = networkOptions vlanNetSubmod // {
id = mkOption {
type = types.ints.between 1 4094;
description = "The VLAN id";
};
name = mkOption {
description = "The name of this VLAN";
default = vlanNetSubmod.config._module.args.name;
type = types.str;
};
};
})
);
};
};
})
);
};
hosts = mkOption {
type = types.attrsOf (
types.submodule {
options = {
ipv4 = mkOption {
type = types.str;
defaultGateway4 = mkOption {
type = types.nullOr types.net.ipv4;
};
defaultGateway6 = mkOption {
type = types.nullOr types.net.ipv6;
};
};
}

View file

@ -5,7 +5,7 @@ let
servicePort = 27701;
serviceName = "ankisync";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
ankiUser = globals.user.name;
in

View file

@ -3,7 +3,7 @@ let
servicePort = 8888;
serviceName = "atuin";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -0,0 +1,34 @@
{ self, lib, config, globals, ... }:
let
localIp = globals.networks.home.hosts.${config.node.name}.ipv4;
subnetMask = globals.networks.home.subnetMask4;
gatewayIp = globals.hosts.${config.node.name}.defaultGateway4;
in
{
options.swarselmodules.server.diskEncryption = lib.mkEnableOption "enable disk encryption config";
config = lib.mkIf (config.swarselmodules.server.diskEncryption && config.swarselsystems.isCrypted) {
boot.kernelParams = lib.mkIf (!config.swarselsystems.isLaptop) [ "ip=${localIp}::${gatewayIp}:${subnetMask}:${config.networking.hostName}::none" ];
boot.initrd = {
availableKernelModules = [ "r8169" ];
network = {
enable = true;
udhcpc.enable = lib.mkIf config.swarselsystems.isLaptop true;
flushBeforeStage2 = true;
ssh = {
enable = true;
port = 22;
authorizedKeyFiles = [
(self + /secrets/keys/ssh/yubikey.pub)
(self + /secrets/keys/ssh/magicant.pub)
];
hostKeys = [ "/etc/secrets/initrd/ssh_host_ed25519_key" ];
};
postCommands = ''
echo 'cryptsetup-askpass || echo "Unlock was successful; exiting SSH session" && exit 1' >> /root/.profile
'';
};
};
};
}

View file

@ -5,7 +5,7 @@ let
serviceGroup = serviceUser;
serviceName = "firefly-iii";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
nginxGroup = "nginx";

View file

@ -7,7 +7,7 @@ let
serviceGroup = serviceUser;
serviceName = "forgejo";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
kanidmDomain = globals.services.kanidm.domain;
in

View file

@ -5,7 +5,7 @@ let
serviceUser = "freshrss";
serviceGroup = serviceName;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
inherit (config.swarselsystems) sopsFile;
in

View file

@ -5,7 +5,7 @@ let
serviceName = "garage";
servicePort = 3900;
serviceDomain = config.repo.secrets.common.services.domains."${serviceName}-${configName}";
serviceAddress = globals.hosts.${configName}.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
cfg = config.services.${serviceName};
metadata_dir = "/var/lib/garage/meta";

View file

@ -3,7 +3,7 @@ let
servicePort = 7745;
serviceName = "homebox";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -4,7 +4,7 @@ let
serviceUser = "immich";
serviceName = "immich";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -4,7 +4,7 @@ let
serviceName = "jellyfin";
serviceUser = "jellyfin";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -3,7 +3,7 @@ let
servicePort = 8088;
serviceName = "jenkins";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -8,7 +8,7 @@ let
serviceGroup = serviceUser;
serviceName = "kanidm";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
oauth2ProxyDomain = globals.services.oauth2Proxy.domain;
immichDomain = globals.services.immich.domain;

View file

@ -6,7 +6,7 @@ let
serviceName = "kavita";
serviceUser = "kavita";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -6,7 +6,7 @@ let
servicePort = 2282;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceDir = "/Vault/data/koillection";
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
postgresUser = config.systemd.services.postgresql.serviceConfig.User; # postgres
postgresPort = config.services.postgresql.settings.port; # 5432

View file

@ -6,7 +6,7 @@ let
serviceName = "matrix";
serviceDomain = config.repo.secrets.common.services.domains.matrix;
serviceUser = "matrix-synapse";
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
federationPort = 8448;
whatsappPort = 29318;

View file

@ -5,7 +5,7 @@ let
serviceGroup = serviceUser;
serviceName = "grafana";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
prometheusPort = 9090;
prometheusUser = "prometheus";

View file

@ -5,7 +5,7 @@ let
serviceUser = "navidrome";
serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -0,0 +1,26 @@
{ lib, config, ... }:
{
options.swarselmodules.server.network = lib.mkEnableOption "enable server network config";
config = lib.mkIf config.swarselmodules.server.network {
globals.networks.home.hosts.${config.node.name} = {
inherit (config.repo.secrets.local.networking.networks.home) id;
mac = config.repo.secrets.local.networking.networks.home.mac or null;
};
globals.hosts.${config.node.name} = {
inherit (config.repo.secrets.local.networking) defaultGateway4;
};
networking = {
inherit (config.repo.secrets.local.networking) hostId;
hostName = config.node.name;
nftables.enable = lib.mkDefault true;
enableIPv6 = lib.mkDefault true;
firewall = {
enable = lib.mkDefault true;
};
};
};
}

View file

@ -8,7 +8,7 @@ let
serviceGroup = serviceUser;
serviceName = "nextcloud";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
in
{
options.swarselmodules.server.${serviceName} = lib.mkEnableOption "enable ${serviceName} on server";

View file

@ -7,7 +7,7 @@ let
serviceGroup = serviceUser;
serviceName = "paperless";
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
tikaPort = 9998;
gotenbergPort = 3002;

View file

@ -7,7 +7,7 @@ let
serviceUser = "radicale";
serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
cfg = config.services.${serviceName};
in

View file

@ -9,7 +9,7 @@ let
serviceUser = "snipeit";
serviceGroup = serviceUser;
serviceDomain = config.repo.secrets.common.services.domains.${serviceName};
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
mysqlPort = 3306;
in

View file

@ -7,7 +7,7 @@ let
serviceUser = "syncthing";
serviceGroup = serviceUser;
serviceName = "syncthing";
serviceAddress = globals.hosts.winters.ipv4;
serviceAddress = globals.networks.home.hosts.${config.node.name}.ipv4;
specificServiceName = "syncthing-${configName}";
cfg = config.services.${serviceName};