router0-dmz0: dnssec, local names, code cleanup
This commit is contained in:
parent
5299051f86
commit
ecfe589b60
3 changed files with 114 additions and 43 deletions
|
@ -5,6 +5,7 @@
|
||||||
config,
|
config,
|
||||||
nodeFlake,
|
nodeFlake,
|
||||||
nodeName,
|
nodeName,
|
||||||
|
localDomainName,
|
||||||
system,
|
system,
|
||||||
...
|
...
|
||||||
}: let
|
}: let
|
||||||
|
@ -32,7 +33,7 @@
|
||||||
[ "192" "168" (toString (vlanid + offset)) "${toString host}${lib.strings.optionalString cidr "/24"}" ];
|
[ "192" "168" (toString (vlanid + offset)) "${toString host}${lib.strings.optionalString cidr "/24"}" ];
|
||||||
|
|
||||||
defaultVlan = {
|
defaultVlan = {
|
||||||
name = "internal";
|
name = "${localDomainName}";
|
||||||
packet_priority = 0;
|
packet_priority = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -55,6 +56,13 @@
|
||||||
"15".name = "iot2";
|
"15".name = "iot2";
|
||||||
"15".packet_priority = -10;
|
"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 }:
|
getVlanDomain = { vlanid }:
|
||||||
if vlanid == 0
|
if vlanid == 0
|
||||||
then
|
then
|
||||||
|
@ -62,6 +70,13 @@
|
||||||
else
|
else
|
||||||
vlans."${toString vlanid}".name + "." + defaultVlan.name
|
vlans."${toString vlanid}".name + "." + defaultVlan.name
|
||||||
;
|
;
|
||||||
|
|
||||||
|
bridgeInterfaceName = "br-lan";
|
||||||
|
mkInterfaceName = { vlanid }:
|
||||||
|
if vlanid == 0
|
||||||
|
then bridgeInterfaceName
|
||||||
|
else "${bridgeInterfaceName}.${toString vlanid}"
|
||||||
|
;
|
||||||
in {
|
in {
|
||||||
imports = [
|
imports = [
|
||||||
repoFlake.inputs.sops-nix.nixosModules.sops
|
repoFlake.inputs.sops-nix.nixosModules.sops
|
||||||
|
@ -164,13 +179,16 @@ in {
|
||||||
firewall = {
|
firewall = {
|
||||||
enable = true;
|
enable = true;
|
||||||
zones = {
|
zones = {
|
||||||
lan.interfaces = [ "br-lan" ];
|
lan.interfaces = [ (mkInterfaceName {vlanid = 0;}) ];
|
||||||
vlan.interfaces = builtins.map (vlanid: "br-lan.${toString vlanid}") vlanRange;
|
vlan.interfaces = builtins.map (vlanid: (mkInterfaceName {inherit vlanid;})) vlanRange;
|
||||||
# lan.ipv4Addresses = ["192.168.0.0/16"];
|
# lan.ipv4Addresses = ["192.168.0.0/16"];
|
||||||
wan.interfaces = ["wan" "lan0"];
|
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
|
rules = let
|
||||||
ipv6IcmpTypes = [
|
ipv6IcmpTypes = [
|
||||||
|
@ -194,6 +212,12 @@ in {
|
||||||
verdict = "accept";
|
verdict = "accept";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
office-to-dmz = {
|
||||||
|
from = ["office"];
|
||||||
|
to = ["dmz"];
|
||||||
|
verdict = "accept";
|
||||||
|
};
|
||||||
|
|
||||||
lan-to-fw = {
|
lan-to-fw = {
|
||||||
from = ["lan"];
|
from = ["lan"];
|
||||||
to = ["fw" "lan"];
|
to = ["fw" "lan"];
|
||||||
|
@ -258,10 +282,10 @@ in {
|
||||||
wait-online.anyInterface = true;
|
wait-online.anyInterface = true;
|
||||||
netdevs = {
|
netdevs = {
|
||||||
# Create the bridge interface
|
# Create the bridge interface
|
||||||
"20-br-lan" = {
|
"20-${bridgeInterfaceName}" = {
|
||||||
netdevConfig = {
|
netdevConfig = {
|
||||||
Kind = "bridge";
|
Kind = "bridge";
|
||||||
Name = "br-lan";
|
Name = bridgeInterfaceName;
|
||||||
};
|
};
|
||||||
|
|
||||||
extraConfig = ''
|
extraConfig = ''
|
||||||
|
@ -280,10 +304,10 @@ in {
|
||||||
{}
|
{}
|
||||||
(builtins.map
|
(builtins.map
|
||||||
({ vlanid, vlanid' }: {
|
({ vlanid, vlanid' }: {
|
||||||
"20-br-lan.${vlanid'}" = {
|
"20-${mkInterfaceName { inherit vlanid; }}" = {
|
||||||
netdevConfig = {
|
netdevConfig = {
|
||||||
Kind = "vlan";
|
Kind = "vlan";
|
||||||
Name = "br-lan.${vlanid'}";
|
Name = "${mkInterfaceName { inherit vlanid; }}";
|
||||||
};
|
};
|
||||||
vlanConfig.Id = vlanid;
|
vlanConfig.Id = vlanid;
|
||||||
};
|
};
|
||||||
|
@ -331,24 +355,45 @@ in {
|
||||||
"30-lan1" = {
|
"30-lan1" = {
|
||||||
matchConfig.Name = "lan1";
|
matchConfig.Name = "lan1";
|
||||||
networkConfig = {
|
networkConfig = {
|
||||||
Bridge = "br-lan";
|
Bridge = bridgeInterfaceName;
|
||||||
ConfigureWithoutCarrier = true;
|
ConfigureWithoutCarrier = true;
|
||||||
};
|
};
|
||||||
linkConfig.RequiredForOnline = "enslaved";
|
linkConfig.RequiredForOnline = "enslaved";
|
||||||
|
|
||||||
|
bridgeVLANs = [
|
||||||
|
{
|
||||||
|
bridgeVLANConfig = {
|
||||||
|
VLAN = vlansByName.dmz.id;
|
||||||
|
PVID = vlansByName.dmz.id;
|
||||||
|
EgressUntagged = vlansByName.dmz.id;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
"30-lan2" = {
|
"30-lan2" = {
|
||||||
matchConfig.Name = "lan2";
|
matchConfig.Name = "lan2";
|
||||||
networkConfig = {
|
networkConfig = {
|
||||||
Bridge = "br-lan";
|
Bridge = bridgeInterfaceName;
|
||||||
ConfigureWithoutCarrier = true;
|
ConfigureWithoutCarrier = true;
|
||||||
};
|
};
|
||||||
linkConfig.RequiredForOnline = "enslaved";
|
linkConfig.RequiredForOnline = "enslaved";
|
||||||
|
|
||||||
|
bridgeVLANs = [
|
||||||
|
{
|
||||||
|
bridgeVLANConfig = {
|
||||||
|
VLAN = vlansByName.office.id;
|
||||||
|
PVID = vlansByName.office.id;
|
||||||
|
EgressUntagged = vlansByName.office.id;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
"30-lan3" = {
|
"30-lan3" = {
|
||||||
matchConfig.Name = "lan3";
|
matchConfig.Name = "lan3";
|
||||||
networkConfig = {
|
networkConfig = {
|
||||||
Bridge = "br-lan";
|
Bridge = bridgeInterfaceName;
|
||||||
ConfigureWithoutCarrier = true;
|
ConfigureWithoutCarrier = true;
|
||||||
};
|
};
|
||||||
linkConfig.RequiredForOnline = "enslaved";
|
linkConfig.RequiredForOnline = "enslaved";
|
||||||
|
@ -360,11 +405,10 @@ in {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
};
|
};
|
||||||
# Configure the bridge for its desired function
|
# Configure the bridge for its desired function
|
||||||
"40-br-lan" = {
|
"40-${bridgeInterfaceName}" = {
|
||||||
matchConfig.Name = "br-lan";
|
matchConfig.Name = bridgeInterfaceName;
|
||||||
bridgeConfig = {};
|
bridgeConfig = {};
|
||||||
address = [
|
address = [
|
||||||
(mkVlanIpv4HostAddr { vlanid = 0; host = 1;})
|
(mkVlanIpv4HostAddr { vlanid = 0; host = 1;})
|
||||||
|
@ -385,7 +429,7 @@ in {
|
||||||
];
|
];
|
||||||
|
|
||||||
vlan = (builtins.map
|
vlan = (builtins.map
|
||||||
(vlanid: "br-lan.${builtins.toString vlanid}")
|
(vlanid: (mkInterfaceName { inherit vlanid; }))
|
||||||
vlanRange
|
vlanRange
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -404,8 +448,8 @@ in {
|
||||||
# configure the tagged vlan device with an address and vlan filtering.
|
# configure the tagged vlan device with an address and vlan filtering.
|
||||||
# dnsmasq is configured to serve the respective /24 range on each tagged device.
|
# 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.
|
# this device only receives traffic for the given vlanid and sends tagged traffic to the bridge.
|
||||||
"41-br-lan.${vlanid'}" = {
|
"41-${mkInterfaceName { inherit vlanid; }}" = {
|
||||||
matchConfig.Name = "br-lan.${vlanid'}";
|
matchConfig.Name = "${mkInterfaceName { inherit vlanid; }}";
|
||||||
address = [
|
address = [
|
||||||
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
|
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
|
||||||
];
|
];
|
||||||
|
@ -432,7 +476,7 @@ in {
|
||||||
"41-wlan0.${vlanid'}" = {
|
"41-wlan0.${vlanid'}" = {
|
||||||
matchConfig.Name = "wlan0.${vlanid'}";
|
matchConfig.Name = "wlan0.${vlanid'}";
|
||||||
networkConfig = {
|
networkConfig = {
|
||||||
Bridge = "br-lan";
|
Bridge = bridgeInterfaceName;
|
||||||
ConfigureWithoutCarrier = true;
|
ConfigureWithoutCarrier = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -449,8 +493,8 @@ in {
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
"50-br-lan.${vlanid'}" = {
|
"50-${mkInterfaceName { inherit vlanid; }}" = {
|
||||||
matchConfig.Name = "br-lan.${vlanid'}";
|
matchConfig.Name = "${mkInterfaceName { inherit vlanid; }}";
|
||||||
address = [
|
address = [
|
||||||
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
|
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
|
||||||
];
|
];
|
||||||
|
@ -498,15 +542,17 @@ in {
|
||||||
authentication.wpaPskFile = config.sops.secrets."${iface}_wpaPskFile".path;
|
authentication.wpaPskFile = config.sops.secrets."${iface}_wpaPskFile".path;
|
||||||
authentication.saePasswordsFile = config.sops.secrets."${iface}_saePasswordsFile".path;
|
authentication.saePasswordsFile = config.sops.secrets."${iface}_saePasswordsFile".path;
|
||||||
|
|
||||||
|
# see https://w1.fi/cgit/hostap/plain/hostapd/hostapd.conf for reference
|
||||||
settings = {
|
settings = {
|
||||||
# bridge = "br-lan";
|
# bridge = bridgeInterfaceName;
|
||||||
|
|
||||||
# wpa_psk_file = config.sops.secrets.wlan0_wpaPskFile.path;
|
# wpa_psk_file = config.sops.secrets.wlan0_wpaPskFile.path;
|
||||||
# not yet supported on hostapd 2.10
|
# not yet supported on hostapd 2.10
|
||||||
# sae_password_file = config.sops.secrets.wlan0_saePasswordsFile.path;
|
# sae_password_file = config.sops.secrets.wlan0_saePasswordsFile.path;
|
||||||
|
|
||||||
logger_stdout_level= lib.mkForce 0;
|
# enables debug logging
|
||||||
logger_syslog_level= lib.mkForce 0;
|
# logger_stdout_level= lib.mkForce 0;
|
||||||
|
# logger_syslog_level= lib.mkForce 0;
|
||||||
|
|
||||||
# resources on vlan tagging
|
# resources on vlan tagging
|
||||||
# https://wireless.wiki.kernel.org/en/users/Documentation/hostapd#dynamic_vlan_tagging
|
# https://wireless.wiki.kernel.org/en/users/Documentation/hostapd#dynamic_vlan_tagging
|
||||||
|
@ -517,7 +563,7 @@ in {
|
||||||
vlan_no_bridge = 1;
|
vlan_no_bridge = 1;
|
||||||
|
|
||||||
/* not used due to the above vlan_no_bridge setting
|
/* not used due to the above vlan_no_bridge setting
|
||||||
vlan_tagged_interface = "br-lan";
|
vlan_tagged_interface = bridgeInterfaceName;
|
||||||
vlan_naming = 1;
|
vlan_naming = 1;
|
||||||
vlan_bridge = "br-${iface}.";
|
vlan_bridge = "br-${iface}.";
|
||||||
*/
|
*/
|
||||||
|
@ -568,7 +614,7 @@ in {
|
||||||
|
|
||||||
# bssid = mkBssid 1;
|
# bssid = mkBssid 1;
|
||||||
# settings = {
|
# settings = {
|
||||||
# bridge = "br-lan";
|
# bridge = bridgeInterfaceName;
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
|
|
||||||
|
@ -581,7 +627,7 @@ in {
|
||||||
# managementFrameProtection = "optional";
|
# managementFrameProtection = "optional";
|
||||||
# bssid = "e6:02:43:07:00:00";
|
# bssid = "e6:02:43:07:00:00";
|
||||||
# settings = {
|
# settings = {
|
||||||
# bridge = "br-lan";
|
# bridge = bridgeInterfaceName;
|
||||||
# wpa = lib.mkForce 2;
|
# wpa = lib.mkForce 2;
|
||||||
# wpa_key_mgmt = "WPA-PSK";
|
# wpa_key_mgmt = "WPA-PSK";
|
||||||
# wpa_pairwise = "CCMP";
|
# wpa_pairwise = "CCMP";
|
||||||
|
@ -673,7 +719,7 @@ in {
|
||||||
# };
|
# };
|
||||||
# bssid = "36:b9:02:21:08:a2";
|
# bssid = "36:b9:02:21:08:a2";
|
||||||
# settings = {
|
# settings = {
|
||||||
# bridge = "br-lan";
|
# bridge = bridgeInterfaceName;
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
# };
|
# };
|
||||||
|
@ -683,15 +729,24 @@ in {
|
||||||
|
|
||||||
services.resolved.enable = false;
|
services.resolved.enable = false;
|
||||||
|
|
||||||
services.dnsmasq = let
|
services.dnsmasq = {
|
||||||
mkIfName = { vlanid }: if vlanid == 0 then "br-lan" else "br-lan.${toString vlanid}";
|
|
||||||
in {
|
|
||||||
enable = true;
|
enable = true;
|
||||||
settings = {
|
settings = {
|
||||||
# sensible behaviours
|
|
||||||
domain-needed = true;
|
domain-needed = true;
|
||||||
bogus-priv = true;
|
bogus-priv = true;
|
||||||
no-resolv = 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
|
dhcp-range = let
|
||||||
mkDhcpRange = { tag, vlanid }: builtins.concatStringsSep "," [
|
mkDhcpRange = { tag, vlanid }: builtins.concatStringsSep "," [
|
||||||
|
@ -703,12 +758,12 @@ in {
|
||||||
in
|
in
|
||||||
builtins.map
|
builtins.map
|
||||||
(vlanid:
|
(vlanid:
|
||||||
mkDhcpRange { tag = mkIfName {inherit vlanid;}; inherit vlanid; }
|
mkDhcpRange { tag = mkInterfaceName {inherit vlanid;}; inherit vlanid; }
|
||||||
)
|
)
|
||||||
vlanRangeWith0
|
vlanRangeWith0
|
||||||
;
|
;
|
||||||
|
|
||||||
# interface = "br-lan";
|
# interface = bridgeInterfaceName;
|
||||||
# bind-interfaces = true;
|
# bind-interfaces = true;
|
||||||
# dhcp-host = "192.168.10.1";
|
# dhcp-host = "192.168.10.1";
|
||||||
|
|
||||||
|
@ -720,12 +775,27 @@ in {
|
||||||
# don't use /etc/hosts as this would advertise ${nodeName} as localhost
|
# don't use /etc/hosts as this would advertise ${nodeName} as localhost
|
||||||
no-hosts = true;
|
no-hosts = true;
|
||||||
|
|
||||||
|
|
||||||
# address = "/${nodeName}.lan/${fwLanHostAddr}";
|
# address = "/${nodeName}.lan/${fwLanHostAddr}";
|
||||||
server = [
|
server = [
|
||||||
# upstream DNS servers
|
# 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
|
] ++ builtins.map
|
||||||
(vlanid: "/${getVlanDomain {inherit vlanid;}}/")
|
(vlanid:
|
||||||
|
"${getVlanDomain {inherit vlanid;}},${mkVlanIpv4HostAddr { inherit vlanid; host = 0; cidr = true; }},local"
|
||||||
|
)
|
||||||
vlanRangeWith0
|
vlanRangeWith0
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -734,18 +804,17 @@ in {
|
||||||
] ++ builtins.map
|
] ++ builtins.map
|
||||||
(vlanid:
|
(vlanid:
|
||||||
builtins.concatStringsSep "," [
|
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
|
vlanRangeWith0
|
||||||
;
|
;
|
||||||
|
|
||||||
dhcp-option-force = builtins.map
|
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
|
vlanRangeWith0
|
||||||
;
|
;
|
||||||
|
|
||||||
localise-queries = true;
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
nodeName,
|
nodeName,
|
||||||
repoFlake,
|
repoFlake,
|
||||||
nodeFlake,
|
nodeFlake,
|
||||||
|
localDomainName ? "internal",
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
meta.nodeSpecialArgs.${nodeName} = {
|
meta.nodeSpecialArgs.${nodeName} = {
|
||||||
|
@ -14,6 +15,8 @@
|
||||||
(nodeFlake.inputs.bpir3.packages.${system})
|
(nodeFlake.inputs.bpir3.packages.${system})
|
||||||
armTrustedFirmwareMT7986
|
armTrustedFirmwareMT7986
|
||||||
;
|
;
|
||||||
|
|
||||||
|
inherit localDomainName;
|
||||||
};
|
};
|
||||||
|
|
||||||
meta.nodeNixpkgs.${nodeName} =
|
meta.nodeNixpkgs.${nodeName} =
|
||||||
|
@ -23,7 +26,7 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
${nodeName} = {
|
${nodeName} = {
|
||||||
deployment.targetHost = "router0.dmz0.noosphere.life";
|
deployment.targetHost = "${nodeName}.${localDomainName}";
|
||||||
deployment.replaceUnknownProfiles = true;
|
deployment.replaceUnknownProfiles = true;
|
||||||
|
|
||||||
# nixpkgs.pkgs = nodeFlake.inputs.nixpkgs.legacyPackages.${system};
|
# nixpkgs.pkgs = nodeFlake.inputs.nixpkgs.legacyPackages.${system};
|
||||||
|
|
|
@ -60,7 +60,6 @@
|
||||||
nixpkgs.lib.attrsets.recursiveUpdate
|
nixpkgs.lib.attrsets.recursiveUpdate
|
||||||
attrs
|
attrs
|
||||||
{
|
{
|
||||||
# TODO: it would be nice if this were the same as meta.nodeSpecialArgs.${nodeName} as in the default.nix
|
|
||||||
specialArgs = (import ./default.nix {
|
specialArgs = (import ./default.nix {
|
||||||
system = nativeSystem;
|
system = nativeSystem;
|
||||||
inherit nodeName;
|
inherit nodeName;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue