router0-dmz0: dnssec, local names, code cleanup

This commit is contained in:
steveej 2023-12-28 11:22:39 +01:00
parent 5299051f86
commit ecfe589b60
3 changed files with 114 additions and 43 deletions

View file

@ -5,6 +5,7 @@
config,
nodeFlake,
nodeName,
localDomainName,
system,
...
}: let
@ -32,7 +33,7 @@
[ "192" "168" (toString (vlanid + offset)) "${toString host}${lib.strings.optionalString cidr "/24"}" ];
defaultVlan = {
name = "internal";
name = "${localDomainName}";
packet_priority = 0;
};
@ -55,6 +56,13 @@
"15".name = "iot2";
"15".packet_priority = -10;
};
vlansByName = lib.attrsets.mapAttrs' (vlanid': attrs:
lib.attrsets.nameValuePair
attrs.name
(attrs // { id = lib.strings.toInt vlanid'; id' = vlanid';})
) vlans;
getVlanDomain = { vlanid }:
if vlanid == 0
then
@ -62,6 +70,13 @@
else
vlans."${toString vlanid}".name + "." + defaultVlan.name
;
bridgeInterfaceName = "br-lan";
mkInterfaceName = { vlanid }:
if vlanid == 0
then bridgeInterfaceName
else "${bridgeInterfaceName}.${toString vlanid}"
;
in {
imports = [
repoFlake.inputs.sops-nix.nixosModules.sops
@ -164,13 +179,16 @@ in {
firewall = {
enable = true;
zones = {
lan.interfaces = [ "br-lan" ];
vlan.interfaces = builtins.map (vlanid: "br-lan.${toString vlanid}") vlanRange;
lan.interfaces = [ (mkInterfaceName {vlanid = 0;}) ];
vlan.interfaces = builtins.map (vlanid: (mkInterfaceName {inherit vlanid;})) vlanRange;
# lan.ipv4Addresses = ["192.168.0.0/16"];
wan.interfaces = ["wan" "lan0"];
} //
# TODO: generate a zone for each vlan
{}
# generate a zone for each vlan
lib.attrsets.mapAttrs (key: value: {
interfaces = [ (mkInterfaceName { vlanid = value.id; }) ];
})
vlansByName
;
rules = let
ipv6IcmpTypes = [
@ -194,6 +212,12 @@ in {
verdict = "accept";
};
office-to-dmz = {
from = ["office"];
to = ["dmz"];
verdict = "accept";
};
lan-to-fw = {
from = ["lan"];
to = ["fw" "lan"];
@ -258,10 +282,10 @@ in {
wait-online.anyInterface = true;
netdevs = {
# Create the bridge interface
"20-br-lan" = {
"20-${bridgeInterfaceName}" = {
netdevConfig = {
Kind = "bridge";
Name = "br-lan";
Name = bridgeInterfaceName;
};
extraConfig = ''
@ -280,10 +304,10 @@ in {
{}
(builtins.map
({ vlanid, vlanid' }: {
"20-br-lan.${vlanid'}" = {
"20-${mkInterfaceName { inherit vlanid; }}" = {
netdevConfig = {
Kind = "vlan";
Name = "br-lan.${vlanid'}";
Name = "${mkInterfaceName { inherit vlanid; }}";
};
vlanConfig.Id = vlanid;
};
@ -331,24 +355,45 @@ in {
"30-lan1" = {
matchConfig.Name = "lan1";
networkConfig = {
Bridge = "br-lan";
Bridge = bridgeInterfaceName;
ConfigureWithoutCarrier = true;
};
linkConfig.RequiredForOnline = "enslaved";
bridgeVLANs = [
{
bridgeVLANConfig = {
VLAN = vlansByName.dmz.id;
PVID = vlansByName.dmz.id;
EgressUntagged = vlansByName.dmz.id;
};
}
];
};
"30-lan2" = {
matchConfig.Name = "lan2";
networkConfig = {
Bridge = "br-lan";
Bridge = bridgeInterfaceName;
ConfigureWithoutCarrier = true;
};
linkConfig.RequiredForOnline = "enslaved";
bridgeVLANs = [
{
bridgeVLANConfig = {
VLAN = vlansByName.office.id;
PVID = vlansByName.office.id;
EgressUntagged = vlansByName.office.id;
};
}
];
};
"30-lan3" = {
matchConfig.Name = "lan3";
networkConfig = {
Bridge = "br-lan";
Bridge = bridgeInterfaceName;
ConfigureWithoutCarrier = true;
};
linkConfig.RequiredForOnline = "enslaved";
@ -360,11 +405,10 @@ in {
};
}
];
};
# Configure the bridge for its desired function
"40-br-lan" = {
matchConfig.Name = "br-lan";
"40-${bridgeInterfaceName}" = {
matchConfig.Name = bridgeInterfaceName;
bridgeConfig = {};
address = [
(mkVlanIpv4HostAddr { vlanid = 0; host = 1;})
@ -385,7 +429,7 @@ in {
];
vlan = (builtins.map
(vlanid: "br-lan.${builtins.toString vlanid}")
(vlanid: (mkInterfaceName { inherit vlanid; }))
vlanRange
);
};
@ -404,8 +448,8 @@ in {
# configure the tagged vlan device with an address and vlan filtering.
# dnsmasq is configured to serve the respective /24 range on each tagged device.
# this device only receives traffic for the given vlanid and sends tagged traffic to the bridge.
"41-br-lan.${vlanid'}" = {
matchConfig.Name = "br-lan.${vlanid'}";
"41-${mkInterfaceName { inherit vlanid; }}" = {
matchConfig.Name = "${mkInterfaceName { inherit vlanid; }}";
address = [
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
];
@ -432,7 +476,7 @@ in {
"41-wlan0.${vlanid'}" = {
matchConfig.Name = "wlan0.${vlanid'}";
networkConfig = {
Bridge = "br-lan";
Bridge = bridgeInterfaceName;
ConfigureWithoutCarrier = true;
};
@ -449,8 +493,8 @@ in {
];
};
"50-br-lan.${vlanid'}" = {
matchConfig.Name = "br-lan.${vlanid'}";
"50-${mkInterfaceName { inherit vlanid; }}" = {
matchConfig.Name = "${mkInterfaceName { inherit vlanid; }}";
address = [
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
];
@ -498,15 +542,17 @@ in {
authentication.wpaPskFile = config.sops.secrets."${iface}_wpaPskFile".path;
authentication.saePasswordsFile = config.sops.secrets."${iface}_saePasswordsFile".path;
# see https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf for reference
settings = {
# bridge = "br-lan";
# bridge = bridgeInterfaceName;
# wpa_psk_file = config.sops.secrets.wlan0_wpaPskFile.path;
# not yet supported on hostapd 2.10
# sae_password_file = config.sops.secrets.wlan0_saePasswordsFile.path;
logger_stdout_level= lib.mkForce 0;
logger_syslog_level= lib.mkForce 0;
# enables debug logging
# logger_stdout_level= lib.mkForce 0;
# logger_syslog_level= lib.mkForce 0;
# resources on vlan tagging
# https://wireless.wiki.kernel.org/en/users/Documentation/hostapd#dynamic_vlan_tagging
@ -517,7 +563,7 @@ in {
vlan_no_bridge = 1;
/* not used due to the above vlan_no_bridge setting
vlan_tagged_interface = "br-lan";
vlan_tagged_interface = bridgeInterfaceName;
vlan_naming = 1;
vlan_bridge = "br-${iface}.";
*/
@ -568,7 +614,7 @@ in {
# bssid = mkBssid 1;
# settings = {
# bridge = "br-lan";
# bridge = bridgeInterfaceName;
# };
# };
@ -581,7 +627,7 @@ in {
# managementFrameProtection = "optional";
# bssid = "e6:02:43:07:00:00";
# settings = {
# bridge = "br-lan";
# bridge = bridgeInterfaceName;
# wpa = lib.mkForce 2;
# wpa_key_mgmt = "WPA-PSK";
# wpa_pairwise = "CCMP";
@ -673,7 +719,7 @@ in {
# };
# bssid = "36:b9:02:21:08:a2";
# settings = {
# bridge = "br-lan";
# bridge = bridgeInterfaceName;
# };
# };
# };
@ -683,15 +729,24 @@ in {
services.resolved.enable = false;
services.dnsmasq = let
mkIfName = { vlanid }: if vlanid == 0 then "br-lan" else "br-lan.${toString vlanid}";
in {
services.dnsmasq = {
enable = true;
settings = {
# sensible behaviours
domain-needed = true;
bogus-priv = true;
no-resolv = true;
localise-queries = true;
proxy-dnssec = true;
conntrack = true;
log-debug = true;
log-queries = true;
# disable negative caching
no-negcache = true;
local-ttl = 0;
dhcp-ttl = 0;
dhcp-range = let
mkDhcpRange = { tag, vlanid }: builtins.concatStringsSep "," [
@ -703,12 +758,12 @@ in {
in
builtins.map
(vlanid:
mkDhcpRange { tag = mkIfName {inherit vlanid;}; inherit vlanid; }
mkDhcpRange { tag = mkInterfaceName {inherit vlanid;}; inherit vlanid; }
)
vlanRangeWith0
;
# interface = "br-lan";
# interface = bridgeInterfaceName;
# bind-interfaces = true;
# dhcp-host = "192.168.10.1";
@ -720,12 +775,27 @@ in {
# don't use /etc/hosts as this would advertise ${nodeName} as localhost
no-hosts = true;
# address = "/${nodeName}.lan/${fwLanHostAddr}";
server = [
# upstream DNS servers
"9.9.9.9" "8.8.8.8" "1.1.1.1"
# https://dnsforge.de/
"176.9.93.198"
"176.9.1.117"
"2a01:4f8:151:34aa::198"
"2a01:4f8:141:316d::117"
# cloudflare and google
# "9.9.9.9" "8.8.8.8" "1.1.1.1"
];
domain = [
"/${getVlanDomain {vlanid = 0;}}/,local"
] ++ builtins.map
(vlanid: "/${getVlanDomain {inherit vlanid;}}/")
(vlanid:
"${getVlanDomain {inherit vlanid;}},${mkVlanIpv4HostAddr { inherit vlanid; host = 0; cidr = true; }},local"
)
vlanRangeWith0
;
@ -734,18 +804,17 @@ in {
] ++ builtins.map
(vlanid:
builtins.concatStringsSep "," [
"${nodeName}.${getVlanDomain{inherit vlanid;}}" "0.0.0.1" (mkIfName {inherit vlanid;})
# "${getVlanDomain{inherit vlanid;}}" "0.0.0.1" (mkInterfaceName {inherit vlanid;})
"${nodeName}.${getVlanDomain{inherit vlanid;}}" "0.0.0.1" (mkInterfaceName {inherit vlanid;})
]
)
vlanRangeWith0
;
dhcp-option-force = builtins.map
(vlanid: "${mkIfName {inherit vlanid;}},option:domain-search,${getVlanDomain{inherit vlanid;}}")
(vlanid: "${mkInterfaceName {inherit vlanid;}},option:domain-search,${getVlanDomain{inherit vlanid;}}")
vlanRangeWith0
;
localise-queries = true;
};
};

View file

@ -3,6 +3,7 @@
nodeName,
repoFlake,
nodeFlake,
localDomainName ? "internal",
...
}: {
meta.nodeSpecialArgs.${nodeName} = {
@ -14,6 +15,8 @@
(nodeFlake.inputs.bpir3.packages.${system})
armTrustedFirmwareMT7986
;
inherit localDomainName;
};
meta.nodeNixpkgs.${nodeName} =
@ -23,7 +26,7 @@
};
${nodeName} = {
deployment.targetHost = "router0.dmz0.noosphere.life";
deployment.targetHost = "${nodeName}.${localDomainName}";
deployment.replaceUnknownProfiles = true;
# nixpkgs.pkgs = nodeFlake.inputs.nixpkgs.legacyPackages.${system};

View file

@ -60,7 +60,6 @@
nixpkgs.lib.attrsets.recursiveUpdate
attrs
{
# TODO: it would be nice if this were the same as meta.nodeSpecialArgs.${nodeName} as in the default.nix
specialArgs = (import ./default.nix {
system = nativeSystem;
inherit nodeName;