feat: switch to new VLAN setup

This commit is contained in:
oddlama 2025-01-20 03:46:16 +01:00
parent 181819d2e6
commit 0f45dfcc1c
No known key found for this signature in database
GPG key ID: 14EFE510775FE39A
8 changed files with 171 additions and 115 deletions

View file

@ -32,8 +32,8 @@ in
vlans = { vlans = {
services = { services = {
id = 5; id = 5;
cidrv4 = "192.168.20.0/24"; cidrv4 = "192.168.5.0/24";
cidrv6 = "fd20::/64"; cidrv6 = "fd05::/64";
hosts.ward.id = 1; hosts.ward.id = 1;
hosts.sire.id = 2; hosts.sire.id = 2;
hosts.ward-adguardhome = { hosts.ward-adguardhome = {
@ -54,14 +54,14 @@ in
cidrv4 = "192.168.10.0/24"; cidrv4 = "192.168.10.0/24";
cidrv6 = "fd10::/64"; cidrv6 = "fd10::/64";
hosts.ward.id = 1; hosts.ward.id = 1;
hosts.ward-adguardhome.id = 3; hosts.sire.id = 2;
}; };
devices = { devices = {
id = 20; id = 20;
cidrv4 = "192.168.30.0/24"; cidrv4 = "192.168.20.0/24";
cidrv6 = "fd30::/64"; cidrv6 = "fd20::/64";
hosts.ward.id = 1; hosts.ward.id = 1;
hosts.ward-adguardhome.id = 3; hosts.sire.id = 2;
hosts.wallbox = { hosts.wallbox = {
id = 40; id = 40;
mac = globals.macs.wallbox; mac = globals.macs.wallbox;
@ -73,17 +73,15 @@ in
}; };
iot = { iot = {
id = 30; id = 30;
cidrv4 = "192.168.40.0/24"; cidrv4 = "192.168.30.0/24";
cidrv6 = "fd40::/64"; cidrv6 = "fd30::/64";
hosts.ward.id = 1; hosts.ward.id = 1;
hosts.ward-adguardhome.id = 3;
}; };
guests = { guests = {
id = 40; id = 50;
cidrv4 = "192.168.50.0/24"; cidrv4 = "192.168.50.0/24";
cidrv6 = "fd50::/64"; cidrv6 = "fd50::/64";
hosts.ward.id = 1; hosts.ward.id = 1;
hosts.ward-adguardhome.id = 3;
}; };
}; };
}; };

View file

@ -32,7 +32,6 @@
}; };
boot.initrd.availableKernelModules = [ boot.initrd.availableKernelModules = [
"r8169" "r8169"
"tpm_crb"
]; ];
security.tpm2 = { security.tpm2 = {
enable = true; enable = true;

View file

@ -109,7 +109,7 @@
microvm = { microvm = {
system = "x86_64-linux"; system = "x86_64-linux";
baseMac = config.repo.secrets.local.networking.interfaces.lan.mac; baseMac = config.repo.secrets.local.networking.interfaces.lan.mac;
interfaces.lan = { }; interfaces.vlan-services = { };
}; };
extraSpecialArgs = { extraSpecialArgs = {
inherit (inputs.self) nodes globals; inherit (inputs.self) nodes globals;

View file

@ -4,6 +4,9 @@
lib, lib,
... ...
}: }:
let
localVlans = lib.genAttrs [ "services" "home" "devices" ] (x: globals.net.home-lan.vlans.${x});
in
{ {
networking.hostId = config.repo.secrets.local.networking.hostId; networking.hostId = config.repo.secrets.local.networking.hostId;
@ -15,64 +18,108 @@
boot.initrd.systemd.network = { boot.initrd.systemd.network = {
enable = true; enable = true;
networks."10-lan" = { netdevs."30-vlan-home" = {
address = [ globals.net.home-lan.vlans.services.hosts.sire.cidrv4 ]; netdevConfig = {
gateway = [ globals.net.home-lan.vlans.services.hosts.ward.ipv4 ]; Kind = "vlan";
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac; Name = "vlan-home";
networkConfig = { };
IPv6PrivacyExtensions = "yes"; vlanConfig.Id = globals.net.home-lan.vlans.home.id;
MulticastDNS = true; };
networks = {
"10-lan" = {
matchConfig.Name = "lan";
networkConfig.LinkLocalAddressing = "no";
linkConfig.RequiredForOnline = "carrier";
vlan = [ "vlan-home" ];
};
"30-vlan-home" = {
address = [
globals.net.home-lan.vlans.home.hosts.sire.cidrv4
globals.net.home-lan.vlans.home.hosts.sire.cidrv6
];
gateway = [ globals.net.home-lan.vlans.home.hosts.ward.ipv4 ];
matchConfig.Name = "vlan-home";
networkConfig = {
IPv6PrivacyExtensions = "yes";
MulticastDNS = true;
};
linkConfig.RequiredForOnline = "routable";
}; };
linkConfig.RequiredForOnline = "routable";
}; };
}; };
# Create a MACVTAP for ourselves too, so that we can communicate with systemd.network.netdevs = lib.flip lib.concatMapAttrs localVlans (
# our guests on the same interface. vlanName: vlanCfg: {
systemd.network.netdevs."10-lan-self" = { # Add an interface for each VLAN
netdevConfig = { "30-vlan-${vlanName}" = {
Name = "lan-self"; netdevConfig = {
Kind = "macvlan"; Kind = "vlan";
}; Name = "vlan-${vlanName}";
extraConfig = '' };
[MACVLAN] vlanConfig.Id = vlanCfg.id;
Mode=bridge
'';
};
systemd.network.networks = {
"10-lan" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac;
# This interface should only be used from attached macvtaps.
# So don't acquire a link local address and only wait for
# this interface to gain a carrier.
networkConfig.LinkLocalAddressing = "no";
linkConfig.RequiredForOnline = "carrier";
extraConfig = ''
[Network]
MACVLAN=lan-self
'';
};
"20-lan-self" = {
address = [ globals.net.home-lan.vlans.services.hosts.sire.cidrv4 ];
gateway = [ globals.net.home-lan.vlans.services.hosts.ward.ipv4 ];
matchConfig.Name = "lan-self";
networkConfig = {
IPv6PrivacyExtensions = "yes";
MulticastDNS = true;
}; };
linkConfig.RequiredForOnline = "routable"; # Create a MACVTAP for ourselves too, so that we can communicate with
}; # our guests on the same interface.
# Remaining macvtap interfaces should not be touched. "40-me-${vlanName}" = {
"90-macvtap-ignore" = { netdevConfig = {
matchConfig.Kind = "macvtap"; Name = "me-${vlanName}";
linkConfig.ActivationPolicy = "manual"; Kind = "macvlan";
linkConfig.Unmanaged = "yes"; };
}; extraConfig = ''
}; [MACVLAN]
Mode=bridge
'';
};
}
);
systemd.network.networks =
{
"10-lan" = {
matchConfig.Name = "lan";
# This interface should only be used from attached vlans.
# So don't acquire a link local address and only wait for
# this interface to gain a carrier.
networkConfig.LinkLocalAddressing = "no";
linkConfig.RequiredForOnline = "carrier";
vlan = map (name: "vlan-${name}") (builtins.attrNames localVlans);
};
# Remaining macvtap interfaces should not be touched.
"90-macvtap-ignore" = {
matchConfig.Kind = "macvtap";
linkConfig.ActivationPolicy = "manual";
linkConfig.Unmanaged = "yes";
};
}
// lib.flip lib.concatMapAttrs localVlans (
vlanName: vlanCfg: {
"30-vlan-${vlanName}" = {
matchConfig.Name = "vlan-${vlanName}";
# This interface should only be used from attached macvlans.
# So don't acquire a link local address and only wait for
# this interface to gain a carrier.
networkConfig.LinkLocalAddressing = "no";
networkConfig.MACVLAN = "me-${vlanName}";
linkConfig.RequiredForOnline = "carrier";
};
"40-me-${vlanName}" = {
address = [
vlanCfg.hosts.sire.cidrv4
vlanCfg.hosts.sire.cidrv6
];
gateway = [ vlanCfg.hosts.ward.ipv4 ];
matchConfig.Name = "me-${vlanName}";
networkConfig = {
IPv6PrivacyExtensions = "yes";
MulticastDNS = true;
};
linkConfig.RequiredForOnline = "routable";
};
}
);
networking.nftables.firewall = { networking.nftables.firewall = {
zones.untrusted.interfaces = [ "lan-self" ]; zones.untrusted.interfaces = [ "me-services" ];
}; };
# Allow accessing influx # Allow accessing influx

View file

@ -2,7 +2,6 @@
config, config,
globals, globals,
lib, lib,
pkgs,
... ...
}: }:
let let
@ -68,6 +67,7 @@ in
port = 3000; port = 3000;
settings = { settings = {
dns = { dns = {
bind_hosts = [ globals.net.home-lan.vlans.services.hosts.ward-adguardhome.ipv4 ];
# allowed_clients = [ # allowed_clients = [
# ]; # ];
#trusted_proxies = []; #trusted_proxies = [];
@ -131,12 +131,5 @@ in
}; };
}; };
systemd.services.adguardhome = { systemd.services.adguardhome.serviceConfig.RestartSec = lib.mkForce "60"; # Retry every minute
preStart = lib.mkAfter ''
INTERFACE_ADDR=$(${pkgs.iproute2}/bin/ip -family inet -brief addr show lan | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+") \
${lib.getExe pkgs.yq-go} -i '.dns.bind_hosts = [strenv(INTERFACE_ADDR)]' \
"$STATE_DIRECTORY/AdGuardHome.yaml"
'';
serviceConfig.RestartSec = lib.mkForce "60"; # Retry every minute
};
} }

View file

@ -115,6 +115,7 @@ in
services.forgejo = { services.forgejo = {
enable = true; enable = true;
package = pkgs.forgejo;
# TODO db backups # TODO db backups
# dump.enable = true; # dump.enable = true;
user = "git"; user = "git";

View file

@ -1,7 +1,6 @@
{ {
lib, lib,
globals, globals,
utils,
... ...
}: }:
let let
@ -37,42 +36,46 @@ in
service-sockets-max-retries = -1; service-sockets-max-retries = -1;
}; };
subnet4 = flip mapAttrsToList globals.net.home-lan.vlans ( subnet4 = flip mapAttrsToList globals.net.home-lan.vlans (
vlanName: vlanCfg: [ vlanName: vlanCfg: {
{ inherit (vlanCfg) id;
inherit (vlanCfg) id; interface = "me-${vlanName}";
interface = "me-${vlanName}"; subnet = vlanCfg.cidrv4;
subnet = vlanCfg.cidrv4; pools = [
pools = [ {
{ pool = "${net.cidr.host 20 vlanCfg.cidrv4} - ${net.cidr.host (-6) vlanCfg.cidrv4}";
pool = "${net.cidr.host 20 vlanCfg.cidrv4} - ${net.cidr.host (-6) vlanCfg.cidrv4}"; }
} ];
]; option-data =
option-data = [ [
{ {
name = "routers"; name = "routers";
data = vlanCfg.hosts.ward.ipv4; # FIXME: how to advertise v6 address also? data = vlanCfg.hosts.ward.ipv4; # FIXME: how to advertise v6 address also?
} }
{ ]
name = "domain-name-servers"; # Advertise DNS server for VLANS that have internet access
data = vlanCfg.hosts.ward-adguardhome.ipv4; ++
lib.optional
(lib.elem vlanName [
"services"
"home"
"devices"
"guests"
])
{
name = "domain-name-servers";
data = globals.net.home-lan.vlans.services.hosts.ward-adguardhome.ipv4;
};
reservations = lib.concatLists (
lib.forEach (builtins.attrValues vlanCfg.hosts) (
hostCfg:
lib.optional (hostCfg.mac != null) {
hw-address = hostCfg.mac;
ip-address = hostCfg.ipv4;
} }
]; )
reservations = lib.concatLists ( );
lib.forEach (builtins.attrValues vlanCfg.hosts) ( }
hostCfg:
lib.optional (hostCfg.mac != null) {
hw-address = hostCfg.mac;
ip-address = hostCfg.ipv4;
}
)
);
}
]
); );
}; };
}; };
systemd.services.kea-dhcp4-server.after = [
"sys-subsystem-net-devices-${utils.escapeSystemdPath "lan-self"}.device"
];
} }

View file

@ -28,12 +28,12 @@
"10-wan" = { "10-wan" = {
address = [ globals.net.home-wan.hosts.ward.cidrv4 ]; address = [ globals.net.home-wan.hosts.ward.cidrv4 ];
gateway = [ globals.net.home-wan.hosts.fritzbox.ipv4 ]; gateway = [ globals.net.home-wan.hosts.fritzbox.ipv4 ];
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wan.mac; matchConfig.Name = "wan";
networkConfig.IPv6PrivacyExtensions = "yes"; networkConfig.IPv6PrivacyExtensions = "yes";
linkConfig.RequiredForOnline = "routable"; linkConfig.RequiredForOnline = "routable";
}; };
"10-lan" = { "10-lan" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac; matchConfig.Name = "lan";
# This interface should only be used from attached vlans. # This interface should only be used from attached vlans.
# So don't acquire a link local address and only wait for # So don't acquire a link local address and only wait for
# this interface to gain a carrier. # this interface to gain a carrier.
@ -57,10 +57,9 @@
}; };
}; };
# Create a MACVTAP for ourselves too, so that we can communicate with
# our guests on the same interface.
systemd.network.netdevs = lib.flip lib.concatMapAttrs globals.net.home-lan.vlans ( systemd.network.netdevs = lib.flip lib.concatMapAttrs globals.net.home-lan.vlans (
vlanName: vlanCfg: { vlanName: vlanCfg: {
# Add an interface for each VLAN
"30-vlan-${vlanName}" = { "30-vlan-${vlanName}" = {
netdevConfig = { netdevConfig = {
Kind = "vlan"; Kind = "vlan";
@ -68,6 +67,8 @@
}; };
vlanConfig.Id = vlanCfg.id; vlanConfig.Id = vlanCfg.id;
}; };
# Create a MACVTAP for ourselves too, so that we can communicate with
# our guests on the same interface.
"40-me-${vlanName}" = { "40-me-${vlanName}" = {
netdevConfig = { netdevConfig = {
Name = "me-${vlanName}"; Name = "me-${vlanName}";
@ -84,7 +85,7 @@
systemd.network.networks = systemd.network.networks =
{ {
"10-lan" = { "10-lan" = {
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.lan.mac; matchConfig.Name = "lan";
# This interface should only be used from attached vlans. # This interface should only be used from attached vlans.
# So don't acquire a link local address and only wait for # So don't acquire a link local address and only wait for
# this interface to gain a carrier. # this interface to gain a carrier.
@ -99,7 +100,7 @@
#ipv6AcceptRAConfig.UseDNS = false; #ipv6AcceptRAConfig.UseDNS = false;
address = [ globals.net.home-wan.hosts.ward.cidrv4 ]; address = [ globals.net.home-wan.hosts.ward.cidrv4 ];
gateway = [ globals.net.home-wan.hosts.fritzbox.ipv4 ]; gateway = [ globals.net.home-wan.hosts.fritzbox.ipv4 ];
matchConfig.MACAddress = config.repo.secrets.local.networking.interfaces.wan.mac; matchConfig.Name = "wan";
networkConfig.IPv6PrivacyExtensions = "yes"; networkConfig.IPv6PrivacyExtensions = "yes";
# dhcpV6Config.PrefixDelegationHint = "::/64"; # dhcpV6Config.PrefixDelegationHint = "::/64";
# FIXME: This should not be needed, but for some reason part of networkd # FIXME: This should not be needed, but for some reason part of networkd
@ -123,11 +124,8 @@
# So don't acquire a link local address and only wait for # So don't acquire a link local address and only wait for
# this interface to gain a carrier. # this interface to gain a carrier.
networkConfig.LinkLocalAddressing = "no"; networkConfig.LinkLocalAddressing = "no";
networkConfig.MACVLAN = "me-${vlanName}";
linkConfig.RequiredForOnline = "carrier"; linkConfig.RequiredForOnline = "carrier";
extraConfig = ''
[Network]
MACVLAN=me-${vlanName}
'';
}; };
"40-me-${vlanName}" = { "40-me-${vlanName}" = {
address = [ address = [
@ -175,6 +173,12 @@
{ {
untrusted.interfaces = [ "wan" ]; untrusted.interfaces = [ "wan" ];
proxy-home.interfaces = [ "proxy-home" ]; proxy-home.interfaces = [ "proxy-home" ];
adguardhome.ipv4Addresses = [
globals.net.home-lan.vlans.services.hosts.ward-adguardhome.ipv4
];
adguardhome.ipv6Addresses = [
globals.net.home-lan.vlans.services.hosts.ward-adguardhome.ipv6
];
} }
// lib.flip lib.concatMapAttrs globals.net.home-lan.vlans ( // lib.flip lib.concatMapAttrs globals.net.home-lan.vlans (
vlanName: _: { vlanName: _: {
@ -198,10 +202,21 @@
verdict = "accept"; verdict = "accept";
}; };
# Allow access to the AdGuardHome DNS server from any VLAN that has internet access
access-adguardhome-dns = {
from = [
"vlan-services"
"vlan-home"
"vlan-devices"
"vlan-guests"
];
to = [ "adguardhome" ];
verdict = "accept";
};
services-to-local = { services-to-local = {
from = [ "vlan-services" ]; from = [ "vlan-services" ];
to = [ "local" ]; to = [ "local" ];
allowedUDPPorts = [ config.wireguard.proxy-home.server.port ]; allowedUDPPorts = [ config.wireguard.proxy-home.server.port ];
}; };