1
1
Fork 1
mirror of https://github.com/oddlama/nix-config.git synced 2025-10-11 07:10:39 +02:00

feat: add macvtap networking to microvms

This commit is contained in:
oddlama 2023-05-10 02:07:09 +02:00
parent 8cb904c44c
commit 24655ece76
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
7 changed files with 95 additions and 29 deletions

View file

@ -67,6 +67,7 @@ This is my personal nix config.
- (Optional) ssh into the target (keys are already set up) - (Optional) ssh into the target (keys are already set up)
- Run `install-system` and reboot - Run `install-system` and reboot
- Retrieve the new host identity by using `ssh-keyscan <host/ip> | grep -o 'ed25519.*' > host/<host>/secrets/host.pub` - Retrieve the new host identity by using `ssh-keyscan <host/ip> | grep -o 'ed25519.*' > host/<host>/secrets/host.pub`
- (If the host has microvms, also retrieve their identities!)
- Rekey the secrets for the new identity `nix run .#rekey` - Rekey the secrets for the new identity `nix run .#rekey`
- Deploy again remotely via colmena - Deploy again remotely via colmena

View file

@ -12,10 +12,21 @@
libWithNet = (import "${inputs.lib-net}/net.nix" {inherit lib;}).lib; libWithNet = (import "${inputs.lib-net}/net.nix" {inherit lib;}).lib;
in in
lib.recursiveUpdate libWithNet { lib.recursiveUpdate libWithNet {
net.cidr = rec { net = {
hostCidr = n: x: "${libWithNet.net.cidr.host n x}/${libWithNet.net.cidr.length x}"; cidr = rec {
ip = x: lib.head (lib.splitString "/" x); hostCidr = n: x: "${libWithNet.net.cidr.host n x}/${libWithNet.net.cidr.length x}";
canonicalize = x: libWithNet.net.cidr.make (libWithNet.net.cidr.length x) (ip x); ip = x: lib.head (lib.splitString "/" x);
canonicalize = x: libWithNet.net.cidr.make (libWithNet.net.cidr.length x) (ip x);
};
mac = {
# Adds offset to the given base address and ensures the result is in
# a locally administered range by replacing the second nibble with a 2.
addPrivate = base: offset: let
added = libWithNet.net.mac.add base offset;
pre = lib.substring 0 1 added;
suf = lib.substring 2 (-1) added;
in "${pre}2${suf}";
};
}; };
}; };

View file

@ -3,6 +3,7 @@
inputs, inputs,
lib, lib,
nixos-hardware, nixos-hardware,
nodeSecrets,
pkgs, pkgs,
... ...
}: { }: {
@ -25,7 +26,16 @@
boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"]; boot.initrd.availableKernelModules = ["xhci_pci" "ahci" "nvme" "usbhid" "usb_storage" "sd_mod" "sdhci_pci" "r8169"];
extra.microvms.test.system = "x86_64-linux"; extra.microvms = let
macOffset = config.lib.net.mac.addPrivate nodeSecrets.networking.interfaces."wan-nic".mac;
in {
test = {
autostart = true;
mac = macOffset "00:00:00:00:00:01";
macvtap = "wan";
system = "x86_64-linux";
};
};
#services.authelia.instances.main = { #services.authelia.instances.main = {
# enable = true; # enable = true;

View file

@ -13,7 +13,30 @@ in {
boot.initrd.systemd.network = { boot.initrd.systemd.network = {
enable = true; enable = true;
networks = {inherit (config.systemd.network.networks) "10-wan";}; networks."10-wan" = {
DHCP = "yes";
#address = [
# "192.168.178.2/24"
# "fd00::1/64"
#];
#gateway = [
#];
matchConfig.MACAddress = nodeSecrets.networking.interfaces."wan-nic".mac;
networkConfig.IPv6PrivacyExtensions = "kernel";
dhcpV4Config.RouteMetric = 20;
dhcpV6Config.RouteMetric = 20;
};
};
systemd.network.netdevs."10-wan" = {
netdevConfig = {
Name = "wan";
Kind = "macvtap";
};
extraConfig = ''
[MACVTAP]
Mode=bridge
'';
}; };
systemd.network.networks = { systemd.network.networks = {
@ -27,7 +50,14 @@ in {
dhcpV4Config.RouteMetric = 10; dhcpV4Config.RouteMetric = 10;
dhcpV6Config.RouteMetric = 10; dhcpV6Config.RouteMetric = 10;
}; };
"10-wan" = { "10-wan-nic" = {
matchConfig.MACAddress = nodeSecrets.networking.interfaces."wan-nic".mac;
extraConfig = ''
[Network]
MACVTAP=wan
'';
};
"11-wan" = {
DHCP = "yes"; DHCP = "yes";
#address = [ #address = [
# "192.168.178.2/24" # "192.168.178.2/24"
@ -35,7 +65,7 @@ in {
#]; #];
#gateway = [ #gateway = [
#]; #];
matchConfig.MACAddress = nodeSecrets.networking.interfaces.wan.mac; matchConfig.Name = "wan";
networkConfig.IPv6PrivacyExtensions = "kernel"; networkConfig.IPv6PrivacyExtensions = "kernel";
dhcpV4Config.RouteMetric = 20; dhcpV4Config.RouteMetric = 20;
dhcpV6Config.RouteMetric = 20; dhcpV6Config.RouteMetric = 20;

Binary file not shown.

View file

@ -1,16 +1,21 @@
{ {
inputs,
config, config,
extraLib,
inputs,
lib, lib,
microvm,
nodeName, nodeName,
nodePath, nodePath,
microvm,
pkgs, pkgs,
... ...
}: let }: let
inherit inherit
(lib) (lib)
attrNames
concatStringsSep
filterAttrs
mapAttrs mapAttrs
mapAttrsToList
mdDoc mdDoc
mkDefault mkDefault
mkForce mkForce
@ -40,9 +45,9 @@
interfaces = [ interfaces = [
{ {
type = "macvtap"; type = "macvtap";
id = "macvtap1"; id = "vm-${vmName}";
macvtap = { macvtap = {
link = "wan0"; link = vmCfg.macvtap;
mode = "bridge"; mode = "bridge";
}; };
inherit (vmCfg) mac; inherit (vmCfg) mac;
@ -79,37 +84,46 @@ in {
description = "Provides a base configuration for MicroVMs."; description = "Provides a base configuration for MicroVMs.";
type = types.attrsOf (types.submodule { type = types.attrsOf (types.submodule {
options = { options = {
system = mkOption { autostart = mkOption {
type = types.str; type = types.bool;
description = mdDoc "The system that this microvm should use"; default = false;
description = mdDoc "Whether this VM should be started automatically with the host";
}; };
mac = mkOption { mac = mkOption {
type = types.mac; type = config.lib.net.types.mac;
description = mdDoc "The MAC address to assign to this VM"; description = mdDoc "The MAC address to assign to this VM";
}; };
macvtap = mkOption {
type = types.str;
description = mdDoc "The macvtap interface to attach to";
};
system = mkOption {
type = types.str;
description = mdDoc "The system that this microvm should use";
};
}; };
}); });
}; };
config = { config = {
assertions = let
duplicateMacs = extraLib.duplicates (mapAttrsToList (_: vmCfg: vmCfg.mac) cfg);
in [
{
assertion = duplicateMacs == [];
message = "Duplicate MicroVM MAC addresses: ${concatStringsSep ", " duplicateMacs}";
}
];
microvm = { microvm = {
host.enable = cfg != {}; host.enable = cfg != {};
declarativeUpdates = true; declarativeUpdates = true;
restartIfChanged = true; restartIfChanged = true;
vms = mkIf (cfg != {}) (mapAttrs defineMicrovm cfg); vms = mkIf (cfg != {}) (mapAttrs defineMicrovm cfg);
autostart = mkIf (cfg != {}) (attrNames (filterAttrs (_: v: v.autostart) cfg));
}; };
#systemd.network.netdevs.jrsptap = {
# netdevConfig = {
# Name = "jrsptap";
# Kind = "macvtap";
# MACAddress = "...";
# };
#};
#systemd.network.networks.vms = {
# matchConfig.Name = "vms";
# networkConfig.MACVTAP = "jrsptap";
#};
}; };
} }

View file

@ -37,7 +37,7 @@ in rec {
in in
foldl' addOrUpdate {} xs; foldl' addOrUpdate {} xs;
# Returns all elements in xs that occur at least once # Returns all elements in xs that occur at least twice
duplicates = xs: let duplicates = xs: let
occurrences = countOccurrences xs; occurrences = countOccurrences xs;
in in