network/nix/nixos-module/server/network.nix

119 lines
2.9 KiB
Nix

# Server network configuration
{ config, lib, ... }:
let
# LXC containers on this host
containers =
lib.filterAttrs (_: { role, model, ... }:
role == "container" &&
model == "lxc"
) config.site.hosts;
# Every bridged veth network required by all containers
bridgeNets =
lib.lists.unique (
builtins.concatMap ({ interfaces, ... }:
builtins.attrNames (
lib.filterAttrs (_: { type, ... }: type == "veth") interfaces
)) (builtins.attrValues containers)
);
# Every network (both veth+phys) required by all containers
ctNets =
lib.lists.unique (
builtins.concatMap ({ physicalInterfaces, ... }:
builtins.attrNames physicalInterfaces
) (builtins.attrValues containers)
);
in
{
networking.firewall = {
enable = true;
allowedTCPPorts = [
# SSH
22
];
};
systemd.network = {
enable = true;
netdevs = {
bond0.netdevConfig = {
Kind = "bond";
Name = "bond0";
};
# LACP
bond0.bondConfig.Mode = "802.3ad";
} // (
builtins.foldl' (result: net: result // {
# Bridges are named just like the corresponding net.
"${net}" = {
netdevConfig = {
Kind = "bridge";
Name = "${net}";
};
extraConfig = ''
[Bridge]
ForwardDelaySec=2
STP=true
'';
};
}) {} bridgeNets
) // (
builtins.foldl' (result: net: result // {
# External VLAN interfaces (to be attached to net bridges) are
# named with an "ext-" prefix.
"ext-${net}" = {
netdevConfig = {
Kind = "vlan";
Name = "ext-${net}";
};
vlanConfig.Id = config.site.net.${net}.vlan;
};
}) {} ctNets
);
networks = {
en = {
# physical ethernet ports
matchConfig.Name = "en*";
networkConfig = {
Bond = "bond0";
LLDP = true;
EmitLLDP = true;
};
};
bond0 = {
DHCP = "no";
matchConfig.Name = "bond0";
networkConfig = {
VLAN = map (net: "ext-${net}") ctNets;
LinkLocalAddressing = "no";
LLDP = true;
EmitLLDP = true;
};
};
} // (builtins.foldl' (result: net: result // {
"${net}" = {
matchConfig.Name = net;
networkConfig = {
# Disable all automatic addressing on bridges. It will delay
# networkd going into operational state.
DHCP = lib.mkDefault "no";
LinkLocalAddressing = lib.mkDefault "no";
LLDP = true;
EmitLLDP = true;
};
};
}) {} bridgeNets) // builtins.foldl' (result: net: result // {
"ext-${net}" = {
matchConfig.Name = "ext-${net}";
# Attach eth*/bond0/VLAN to bridge
networkConfig.Bridge = net;
};
}) {} ctNets;
};
}