From c58d6c89b346697c83c3315881262409848be2f4 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Tue, 30 Jan 2024 22:32:09 +0100 Subject: [PATCH] improve networking templating and configuration --- nixos/lab.nix | 7 +- nixos/machines/default.nix | 70 +++++++++---------- nixos/modules/data-sharing.nix | 2 +- nixos/modules/networking/default.nix | 30 +++++++- nixos/modules/networking/dmz/dnsmasq.nix | 6 +- .../networking/dmz/zones/geokunis2.nl.nix | 6 +- nixos/modules/networking/dmz/zones/kun.is.nix | 4 +- nixos/virtual.nix | 50 +++++++++---- 8 files changed, 111 insertions(+), 64 deletions(-) diff --git a/nixos/lab.nix b/nixos/lab.nix index 310b4fe..fac3ea7 100644 --- a/nixos/lab.nix +++ b/nixos/lab.nix @@ -1,11 +1,14 @@ { lab.networking = { publicIPv4 = "192.145.57.90"; - dockerSwarmInternalIPv4 = "192.168.30.8"; + publicRouterIPv6 = "2a0d:6e00:1a77::1"; + dockerSwarmIPv4 = "192.168.30.8"; dockerSwarmIPv6 = "2a0d:6e00:1a77:30:c8fe:c0ff:feff:ee08"; dmzRouterIPv4 = "192.168.30.1"; + dmzRouterIPv6 = "2a0d:6e00:1a77:30::1"; dmzServicesIPv4 = "192.168.30.7"; - # TODO: configure prefix length as well dmzServicesIPv6 = "2a0d:6e00:1a77:30::7"; + dmzIPv4PrefixLength = "24"; + dmzIPv6PrefixLength = "64"; }; } diff --git a/nixos/machines/default.nix b/nixos/machines/default.nix index 45754c7..5e4387c 100644 --- a/nixos/machines/default.nix +++ b/nixos/machines/default.nix @@ -24,48 +24,35 @@ atlas = { type = "physical"; - nixosModule = { config, ... }: - let inherit (config.lab.networking) dmzServicesIPv4 dmzServicesIPv6; in - { - lab = { - # networking = { - # # TODO: Ideally, we don't have to set this here. - # staticDMZIPv4Address = "${dmzServicesIPv4}/24"; - # staticDMZIPv6Address = "${dmzServicesIPv6}/64"; - # dmzServices.enable = true; - # }; - - storage = { - osDisk = "/dev/sda"; - dataPartition = "/dev/nvme0n1p1"; - }; - - ssh = { - useCertificates = true; - hostCert = builtins.readFile ./atlas_host_ed25519-cert.pub; - userCert = builtins.readFile ./atlas_user_ed25519-cert.pub; - }; - }; + nixosModule.lab = { + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; }; + + ssh = { + useCertificates = true; + hostCert = builtins.readFile ./atlas_host_ed25519-cert.pub; + userCert = builtins.readFile ./atlas_user_ed25519-cert.pub; + }; + }; }; lewis = { type = "physical"; - nixosModule = { - lab = { - dataHost.enable = true; + nixosModule.lab = { + dataHost.enable = true; - storage = { - osDisk = "/dev/sda"; - dataPartition = "/dev/nvme0n1p1"; - }; + storage = { + osDisk = "/dev/sda"; + dataPartition = "/dev/nvme0n1p1"; + }; - ssh = { - useCertificates = true; - hostCert = builtins.readFile ./lewis_host_ed25519-cert.pub; - userCert = builtins.readFile ./lewis_user_ed25519-cert.pub; - }; + ssh = { + useCertificates = true; + hostCert = builtins.readFile ./lewis_host_ed25519-cert.pub; + userCert = builtins.readFile ./lewis_user_ed25519-cert.pub; }; }; }; @@ -75,7 +62,8 @@ hypervisorName = "lewis"; nixosModule = { pkgs, ... }: { - lab.vmMacAddress = "BA:DB:EE:F0:00:00"; + # TODO: would be cool to create a check that a mac address is only ever assigned to one VM. + lab.vm.macAddress = "BA:DB:EE:F0:00:00"; programs.bash.interactiveShellInit = '' echo "Hello world from inside a virtual machine!!" | ${pkgs.lolcat}/bin/lolcat @@ -86,11 +74,17 @@ hermes = { type = "virtual"; hypervisorName = "lewis"; - nixosModule = { + + nixosModule = { config, ... }: { lab = { - vmMacAddress = "BA:DB:EE:F0:00:07"; - vmIsDHCPServer = true; networking.dmzServices.enable = true; + + vm = { + macAddress = "BA:DB:EE:F0:00:07"; + staticNetworking = true; + staticIPv4 = config.lab.networking.dmzServicesIPv4; + staticIPv6 = config.lab.networking.dmzServicesIPv6; + }; }; }; }; diff --git a/nixos/modules/data-sharing.nix b/nixos/modules/data-sharing.nix index 772a9a5..744b87f 100644 --- a/nixos/modules/data-sharing.nix +++ b/nixos/modules/data-sharing.nix @@ -19,7 +19,7 @@ let nfsExports = lib.strings.concatLines ( builtins.map (share: - "${cfg.nfsRoot}${share} 192.168.30.0/24(rw,sync,no_subtree_check,no_root_squash)" + "${cfg.nfsRoot}${share} 192.168.30.0/${config.lab.networking.dmzIPv4PrefixLength}(rw,sync,no_subtree_check,no_root_squash)" ) nfsShares ); diff --git a/nixos/modules/networking/default.nix b/nixos/modules/networking/default.nix index f5e72a8..3924953 100644 --- a/nixos/modules/networking/default.nix +++ b/nixos/modules/networking/default.nix @@ -35,7 +35,14 @@ in { ''; }; - dockerSwarmInternalIPv4 = lib.mkOption { + publicRouterIPv6 = lib.mkOption { + type = lib.types.str; + description = '' + Publicly routable IPv6 address of the router. + ''; + }; + + dockerSwarmIPv4 = lib.mkOption { type = lib.types.str; description = '' Internal IPv4 address of the Docker Swarm. @@ -56,6 +63,13 @@ in { ''; }; + dmzRouterIPv6 = lib.mkOption { + type = lib.types.str; + description = '' + The router's IPv6 address on the DMZ network. + ''; + }; + dmzServicesIPv4 = lib.mkOption { type = lib.types.str; description = '' @@ -85,6 +99,20 @@ in { Pattern to match the name of this machine's main NIC. ''; }; + + dmzIPv4PrefixLength = lib.mkOption { + type = lib.types.str; + description = '' + IPv4 prefix length of DMZ network. + ''; + }; + + dmzIPv6PrefixLength = lib.mkOption { + type = lib.types.str; + description = '' + IPv6 prefix length of DMZ network. + ''; + }; }; config = { diff --git a/nixos/modules/networking/dmz/dnsmasq.nix b/nixos/modules/networking/dmz/dnsmasq.nix index e49446b..6140184 100644 --- a/nixos/modules/networking/dmz/dnsmasq.nix +++ b/nixos/modules/networking/dmz/dnsmasq.nix @@ -1,6 +1,6 @@ { config, ... }: let - inherit (config.lab.networking) publicIPv4 dockerSwarmInternalIPv4 dmzServicesIPv4 dmzServicesIPv6 dmzRouterIPv4; + inherit (config.lab.networking) publicIPv4 dockerSwarmIPv4 dmzServicesIPv4 dmzServicesIPv6 dmzRouterIPv4; in { no-resolv = true; @@ -11,7 +11,7 @@ in domain = "dmz"; dhcp-authoritative = true; ra-param = "*,0,0"; - alias = "${publicIPv4},${dockerSwarmInternalIPv4}"; + alias = "${publicIPv4},${dockerSwarmIPv4}"; log-dhcp = true; log-queries = true; port = "5353"; @@ -34,7 +34,7 @@ in dhcp-host = [ "b8:27:eb:b9:ab:e2,esrom" - "ca:fe:c0:ff:ee:08,maestro,${dockerSwarmInternalIPv4}" + "ca:fe:c0:ff:ee:08,maestro,${dockerSwarmIPv4}" ]; dhcp-option = [ diff --git a/nixos/modules/networking/dmz/zones/geokunis2.nl.nix b/nixos/modules/networking/dmz/zones/geokunis2.nl.nix index 8a32dc7..65d8a40 100644 --- a/nixos/modules/networking/dmz/zones/geokunis2.nl.nix +++ b/nixos/modules/networking/dmz/zones/geokunis2.nl.nix @@ -1,7 +1,7 @@ { config, dns, ... }: with dns.lib.combinators; let - inherit (config.lab.networking) publicIPv4 dmzServicesIPv6 dockerSwarmIPv6; + inherit (config.lab.networking) publicIPv4 dmzServicesIPv6 dockerSwarmIPv6 publicRouterIPv6; in { SOA = { @@ -52,7 +52,7 @@ in wg = { A = [ publicIPv4 ]; - AAAA = [ "2a0d:6e00:1a77::1" ]; + AAAA = [ publicRouterIPv6 ]; }; wg4 = { @@ -62,7 +62,7 @@ in wg6 = { A = [ ]; - AAAA = [ "2a0d:6e00:1a77::1" ]; + AAAA = [ publicRouterIPv6 ]; }; }; } diff --git a/nixos/modules/networking/dmz/zones/kun.is.nix b/nixos/modules/networking/dmz/zones/kun.is.nix index 80e1730..41ba5b7 100644 --- a/nixos/modules/networking/dmz/zones/kun.is.nix +++ b/nixos/modules/networking/dmz/zones/kun.is.nix @@ -1,7 +1,7 @@ { config, dns, ... }: with dns.lib.combinators; let - inherit (config.lab.networking) publicIPv4 dmzServicesIPv6 dockerSwarmIPv6; + inherit (config.lab.networking) publicIPv4 dmzServicesIPv6 dockerSwarmIPv6 publicRouterIPv6; in { CAA = letsEncrypt "caa@kun.is"; @@ -57,7 +57,7 @@ in # Override because wg is on opnsense so ipv6 differs from "dmzServicesIPv6" wg = { A = [ publicIPv4 ]; - AAAA = [ "2a0d:6e00:1a77::1" ]; + AAAA = [ publicRouterIPv6 ]; }; }; diff --git a/nixos/virtual.nix b/nixos/virtual.nix index 56473a7..65dae01 100644 --- a/nixos/virtual.nix +++ b/nixos/virtual.nix @@ -1,18 +1,32 @@ { lib, config, hypervisorConfig, ... }: { - options.lab = { - vmMacAddress = lib.mkOption { + options.lab.vm = { + macAddress = lib.mkOption { type = lib.types.str; description = '' The MAC address of the VM's main NIC. ''; }; - # TODO: remove this ugly option - vmIsDHCPServer = lib.mkOption { + staticNetworking = lib.mkOption { default = false; type = lib.types.bool; description = '' - Whether this VM is the DHCP server. + Whether this VM has static networking configuration applied. + Routing is prepopulated, but IP addresses have to be set. + ''; + }; + + staticIPv4 = lib.mkOption { + type = lib.types.str; + description = '' + Static IPv4 address for the VM. + ''; + }; + + staticIPv6 = lib.mkOption { + type = lib.types.str; + description = '' + Static IPv6 address for the VM. ''; }; }; @@ -31,11 +45,11 @@ interfaces = [{ type = "tap"; id = "vm-${config.networking.hostName}"; - mac = config.lab.vmMacAddress; + mac = config.lab.vm.macAddress; }]; }; - networking.useDHCP = lib.mkForce false; + networking.useDHCP = false; systemd.network = { enable = true; @@ -45,22 +59,30 @@ matchConfig.Name = "en*"; networkConfig = { - IPv6AcceptRA = ! config.lab.vmIsDHCPServer; - DHCP = lib.mkIf (! config.lab.vmIsDHCPServer) "yes"; - Address = lib.mkIf config.lab.vmIsDHCPServer [ "192.168.30.7/24" "2a0d:6e00:1a77:30::7/64" ]; - DNS = lib.mkIf config.lab.vmIsDHCPServer [ "192.168.30.1" "fe80::4262:31ff:fe02:c55f" ]; + IPv6AcceptRA = ! config.lab.vm.staticNetworking; + DHCP = lib.mkIf (! config.lab.vm.staticNetworking) "yes"; + + Address = lib.mkIf config.lab.vm.staticNetworking [ + "${config.lab.vm.staticIPv4}/${config.lab.networking.dmzIPv4PrefixLength}" + "${config.lab.vm.staticIPv6}/${config.lab.networking.dmzIPv6PrefixLength}" + ]; + + DNS = lib.mkIf config.lab.vm.staticNetworking [ + config.lab.networking.dmzRouterIPv4 + config.lab.networking.dmzRouterIPv6 + ]; }; - routes = lib.mkIf config.lab.vmIsDHCPServer [ + routes = lib.mkIf config.lab.vm.staticNetworking [ { routeConfig = { - Gateway = "192.168.30.1"; + Gateway = config.lab.networking.dmzRouterIPv4; Destination = "0.0.0.0/0"; }; } { routeConfig = { - Gateway = "fe80::4262:31ff:fe02:c55f"; + Gateway = config.lab.networking.dmzRouterIPv6; Destination = "::/0"; }; }