Revamp network config #77

Merged
nerf merged 2 commits from nerf/nixConfig:networking into main 2025-04-01 17:14:29 +00:00
10 changed files with 106 additions and 58 deletions

View file

@ -4,7 +4,6 @@
../../modules/jitsi.nix
../../roles
../../roles/vm.nix
../../modules/vmNetwork.nix
];
services.mathebau-jitsi = {
@ -14,6 +13,5 @@
# System configuration here
networking.hostName = "ghatanothoa";
vmNetwork.ipv4 = "192.168.0.25";
system.stateVersion = "23.11";
}

View file

@ -4,7 +4,6 @@
../../modules/mailman.nix
../../roles
../../roles/vm.nix
../../modules/vmNetwork.nix
];
# System configuration here
@ -16,7 +15,6 @@
};
networking.hostName = "lobon";
vmNetwork.ipv4 = "192.168.0.22";
system.stateVersion = "23.11";
sops.secrets = {

View file

@ -3,7 +3,6 @@
./hardware-configuration.nix
../../roles
../../roles/vm.nix
../../modules/vmNetwork.nix
];
# System configuration here
@ -11,6 +10,5 @@
environment.systemPackages = [pkgs.git];
networking.hostName = "nodens";
vmNetwork.ipv4 = "192.168.0.18";
system.stateVersion = "24.11";
}

View file

@ -4,7 +4,6 @@
../../modules/mail.nix
../../roles
../../roles/vm.nix
../../modules/vmNetwork.nix
];
# System configuration here
@ -40,7 +39,6 @@
};
networking.hostName = "nyarlathotep";
vmNetwork.ipv4 = "192.168.0.17";
system.stateVersion = "24.05";
sops.secrets = let

View file

@ -358,7 +358,7 @@ in {
# We don't want this in order to not need to persist borg cache and simplify new deployments.
BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes";
};
repo = "borg@192.168.1.11:nyarlathotep"; # TODO for https://gitea.mathebau.de/Fachschaft/nixConfig/issues/33
repo = "borg@bragi:nyarlathotep"; # TODO for https://gitea.mathebau.de/Fachschaft/nixConfig/issues/33
Review

should the repo name nyarlathotep be hardcoded?

should the repo name `nyarlathotep` be hardcoded?
startAt = "daily";
user = "root";
group = "root";

View file

@ -117,7 +117,7 @@ in {
# We don't want this in order to not need to persist borg cache and simplify new deployments.
BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK = "yes";
};
repo = "borg@192.168.1.11:lobon"; # TODO for https://gitea.mathebau.de/Fachschaft/nixConfig/issues/33
repo = "borg@bragi:lobon"; # TODO for https://gitea.mathebau.de/Fachschaft/nixConfig/issues/33
Review

should the repo name lobon be hardcoded?

should the repo name `lobon` be hardcoded?
Review

Probably not.

Probably not.
Review

Feels out of scope, I just noted as i changed the ip to a hostname

Feels out of scope, I just noted as i changed the ip to a hostname
startAt = "daily";
user = "root";
group = "root";

View file

@ -1,48 +0,0 @@
{
lib,
config,
...
}: let
inherit
(lib)
mkOption
types
last
init
;
inherit
(lib.strings)
splitString
concatStringsSep
toInt
;
cfg = config.vmNetwork;
in {
imports = [];
options.vmNetwork = {
ipv4 = mkOption {
type = types.str;
description = "the ipv4 adress of this machine";
};
};
config = {
networking = {
interfaces.enX0.ipv4.addresses = [
{
address = cfg.ipv4;
prefixLength = 16;
}
];
defaultGateway = let
addr = splitString "." cfg.ipv4;
addrInit = init addr;
addrLastInt = builtins.toString (toInt (last addr) + 127);
in
concatStringsSep "." (addrInit ++ [addrLastInt]);
# https://www.hrz.tu-darmstadt.de/services/it_services/nameserver_dns/index.de.jsp
nameservers = ["130.83.22.63" "130.83.22.60" "130.83.56.60"];
};
};
}

57
nixos/roles/hostmap.nix Normal file
View file

@ -0,0 +1,57 @@
# This data is taken from /etc/hosts from azatoth
{
bragi = {
ipv4 = "192.168.1.11";
};
tsathoggua = {
ipv4 = "192.168.0.13";
};
nyogtha = {
ipv4 = "192.168.0.14";
};
hastur = {
ipv4 = "192.168.0.15";
};
cthulhu = {
ipv4 = "192.168.0.16";
};
nyarlathotep = {
ipv4 = "192.168.0.17";
nerf marked this conversation as resolved Outdated
Outdated
Review

This vm does not exist anymore and I deleted its record on azathoth now.

This vm does not exist anymore and I deleted its record on azathoth now.
};
nodens = {
nerf marked this conversation as resolved Outdated
Outdated
Review

This vm does not exist anymore and I deleted its record on azathoth now.

This vm does not exist anymore and I deleted its record on azathoth now.
ipv4 = "192.168.0.18";
};
uvhash = {
ipv4 = "192.168.0.19";
};
aphoom-zhah = {
ipv4 = "192.168.0.20";
};
dagon = {
ipv4 = "192.168.0.21";
};
lobon = {
ipv4 = "192.168.0.22";
};
yibb-tstll = {
ipv4 = "192.168.0.23";
};
eihort = {
ipv4 = "192.168.0.24";
};
ghatanothoa = {
ipv4 = "192.168.0.25";
};
toth = {
ipv4 = "192.168.0.26";
};
ithaqua = {
ipv4 = "192.168.0.27";
};
cthugha = {
ipv4 = "192.168.0.30";
};
Outdated
Review

192.168.0.92 sanctamariamaterdei is missing

`192.168.0.92 sanctamariamaterdei` is missing
sanctamariamaterdei = {
ipv4 = "192.168.0.92";
};
}

View file

@ -1,5 +1,6 @@
{modulesPath, ...}: {
imports = [
(modulesPath + "/virtualisation/xen-domU.nix")
./vmNetwork.nix
];
}

46
nixos/roles/vmNetwork.nix Normal file
View file

@ -0,0 +1,46 @@
{
Gonne marked this conversation as resolved Outdated
Outdated
Review

Will this assumption fail with IPv6?

Can we perhaps instead manage a record containing records of per-vm network config? Then we could extract and complete this towards it network config and generate the hostfile via some function.

I imagine some structure like

{
lobon = {
  interfaces.enX0.ipv4.addresses = [
    {
      address = "192.168.0.22";
    }
  ];
};
nyarlathotep =  …
};
Will this assumption fail with IPv6? Can we perhaps instead manage a record containing records of per-vm network config? Then we could extract and complete this towards it network config and generate the hostfile via some function. I imagine some structure like ``` { lobon = { interfaces.enX0.ipv4.addresses = [ { address = "192.168.0.22"; } ]; }; nyarlathotep = … }; ```
Outdated
Review

I did not spend a single thought about ipv6, I wanted to restructure the existing config not add new features.

In general we could do something similar this, I choose this way, because it directly corresponds to hostfiles.
What are we doing with hostfile entries that are not nix machines?

Right now we just specify exactly one ipv4 and let all the interface set up to modules/vmNetworking.nix. This already assumes exactly one ipv4 address, and always configures enX0. Adding support for a singular ipv6 address should be easy (and still feels out of scope to me). (But I see that extracting two different types of addresses out of this hostfile like syntax would be annoying).

Do we want support for different interfaces and multiple addresses per nix machine? If we don't need it, it
will only make the config more repetitive.

So if we want to turn the structure around i would propose something like

{
lobon = {
  ipv4 = "192.168.0.22";
};
nyarlathotep = ...
}

which is less flexible, but also comes with less overhead that we might not need.

I did not spend a single thought about ipv6, I wanted to restructure the existing config not add new features. In general we could do something similar this, I choose this way, because it directly corresponds to hostfiles. What are we doing with hostfile entries that are not nix machines? Right now we just specify exactly one ipv4 and let all the interface set up to `modules/vmNetworking.nix`. This already assumes exactly one ipv4 address, and always configures `enX0`. Adding support for a singular ipv6 address should be easy (and still feels out of scope to me). (But I see that extracting two different types of addresses out of this hostfile like syntax would be annoying). Do we want support for different interfaces and multiple addresses per nix machine? If we don't need it, it will only make the config more repetitive. So if we want to turn the structure around i would propose something like ``` { lobon = { ipv4 = "192.168.0.22"; }; nyarlathotep = ... } ``` which is less flexible, but also comes with less overhead that we might not need.
Outdated
Review

I did not spend a single thought about ipv6, I wanted to restructure the existing config not add new features.

Fair. I mentioned it because introducing it might make all the effort spent here obsolete and thus polishing a non-compatible solution might be a waste of time. Otherwise, we don't need to include it now.

In general we could do something similar this, I choose this way, because it directly corresponds to hostfiles.
What are we doing with hostfile entries that are not nix machines?

Since we may have dependencies on non-nix vms (e.g. sanctamariamaterdei), I prefer to include them perhaps the way you currently do with all vms.

Do we want support for different interfaces and multiple addresses per nix machine? If we don't need it, it
will only make the config more repetitive.

I don't see where we need multiple interfaces, but IPv6 usually has multiple addresses per interface (global, link-local, ?).

So if we want to turn the structure around i would propose something like

lobon = {
  ipv4 = "192.168.0.22";
};
nyarlathotep = ...
}

which is less flexible, but also comes with less overhead that we might not need.

👍

> I did not spend a single thought about ipv6, I wanted to restructure the existing config not add new features. Fair. I mentioned it because introducing it might make all the effort spent here obsolete and thus polishing a non-compatible solution might be a waste of time. Otherwise, we don't need to include it now. > In general we could do something similar this, I choose this way, because it directly corresponds to hostfiles. > What are we doing with hostfile entries that are not nix machines? Since we may have dependencies on non-nix vms (e.g. `sanctamariamaterdei`), I prefer to include them perhaps the way you currently do with all vms. > Do we want support for different interfaces and multiple addresses per nix machine? If we don't need it, it will only make the config more repetitive. I don't see where we need multiple interfaces, but IPv6 usually has multiple addresses per interface (global, link-local, ?). > So if we want to turn the structure around i would propose something like > ```{ > lobon = { > ipv4 = "192.168.0.22"; > }; > nyarlathotep = ... > } > ``` > which is less flexible, but also comes with less overhead that we might not need. 👍
Outdated
Review

shouldn't we get all the non global ipv6 stuff from SLAAC?
And if not we could still do

lobon = {
  ipv4 = "192,168.0.22";
  ipv6 = { some complicated structure};
};
shouldn't we get all the non global ipv6 stuff from SLAAC? And if not we could still do ``` lobon = { ipv4 = "192,168.0.22"; ipv6 = { some complicated structure}; }; ```
lib,
config,
...
}: let
Gonne marked this conversation as resolved Outdated
Outdated
Review

I don't see why this is a role and not part of the vmNetwork module.

I don't see why this is a role and not part of the `vmNetwork` module.
Outdated
Review

I does not eat config options. This distinction is kind of weird and we inherited it from maralorn to have some starting point. It felt to me like it is more part of having the vm role, (this is also why it is hooked via roles/vm.nix ), than being an alone standing module. But I don't have hard feelings about that.

I also thought about integrating modules/vmNetwork.nix into this role (as the argument is now superfluous).

I does not eat config options. This distinction is kind of weird and we inherited it from maralorn to have some starting point. It felt to me like it is more part of having the vm role, (this is also why it is hooked via `roles/vm.nix` ), than being an alone standing module. But I don't have hard feelings about that. I also thought about integrating `modules/vmNetwork.nix` into this role (as the argument is now superfluous).
Outdated
Review

I don't really have an opinion either.

I don't really have an opinion either.
inherit (lib) mapAttrsToList;
inherit (lib.attrsets) foldAttrs concatMapAttrs;
inherit (lib.asserts) assertMsg;
inherit (lib.lists) filter last init;
inherit (lib.strings) splitString toInt concatStringsSep;
inherit (builtins) elem toString;
hostmap = import ./hostmap.nix;
myhostName = config.networking.hostName;
# To turn the hostmap around suitable for networking.hosts the following simple code almost works
# concatMapAttrs (hostname: ipData: { ${ipData.ipv4} = [hostname]; }) hostmap
# but breaks as soon as we want to map two different names to the same ip.
# So the code looks uglier than one would expect.
globalhosts = foldAttrs (a: b: a ++ b) [] (mapAttrsToList (hostname: ipData: {${ipData.ipv4} = [hostname];}) hostmap);
# We replace our own ip with 127.0.0.1 in /etc/hosts
myhosts = concatMapAttrs (ip: hosts:
if (elem myhostName hosts)
# nixos maps the hostname to the loopback 127.0.0.2 by default, so we exclude it here.
# there is also a default localhost to 127.0.0.1 in place
then {"127.0.0.1" = filter (x: x != myhostName) hosts;}
else {${ip} = hosts;})
globalhosts;
myIp = assert (assertMsg (hostmap ? ${myhostName}.ipv4) "${myhostName} has no ip configured in nixos/roles/hostmap.nix"); hostmap.${myhostName}.ipv4;
in {
networking = {
hosts = myhosts;
interfaces.enX0.ipv4.addresses = [
{
address = myIp;
prefixLength = 16;
}
];
defaultGateway = let
addr = splitString "." myIp;
addrInit = init addr;
addrLastInt = toString (toInt (last addr) + 127);
in
concatStringsSep "." (addrInit ++ [addrLastInt]);
# https://www.hrz.tu-darmstadt.de/services/it_services/nameserver_dns/index.de.jsp
nameservers = ["130.83.22.63" "130.83.22.60" "130.83.56.60"];
};
}