feat(router0-dmz0): AP with dynamic vlan filtering on central bridge
This commit is contained in:
parent
8bcb433257
commit
c0a8792af7
5 changed files with 189 additions and 126 deletions
|
@ -1,7 +1,5 @@
|
|||
{
|
||||
modulesPath,
|
||||
repoFlake,
|
||||
packages',
|
||||
pkgs,
|
||||
lib,
|
||||
config,
|
||||
|
@ -154,7 +152,7 @@ in {
|
|||
useNetworkd = true;
|
||||
useDHCP = false;
|
||||
|
||||
# No local firewall.
|
||||
# these will be configured via nftables
|
||||
nat.enable = lib.mkForce false;
|
||||
firewall.enable = lib.mkForce false;
|
||||
|
||||
|
@ -278,15 +276,27 @@ in {
|
|||
'';
|
||||
};
|
||||
|
||||
# TODO: generate one of these for each vlanid
|
||||
"20-br-lan.15" = {
|
||||
netdevConfig = {
|
||||
Kind = "vlan";
|
||||
Name = "br-lan.15";
|
||||
};
|
||||
vlanConfig.Id = 15;
|
||||
};
|
||||
};
|
||||
}
|
||||
# generate the vlan devices. these will be tagged on the main bridge
|
||||
// builtins.foldl'
|
||||
(acc: cur: acc // cur)
|
||||
{}
|
||||
(builtins.map
|
||||
({ vlanid, vlanid' }: {
|
||||
"20-br-lan.${vlanid'}" = {
|
||||
netdevConfig = {
|
||||
Kind = "vlan";
|
||||
Name = "br-lan.${vlanid'}";
|
||||
};
|
||||
vlanConfig.Id = vlanid;
|
||||
};
|
||||
})
|
||||
(builtins.map
|
||||
(vlanid: { inherit vlanid; vlanid' = builtins.toString vlanid; })
|
||||
vlanRange
|
||||
)
|
||||
)
|
||||
;
|
||||
networks = {
|
||||
# use lan0 as secondary WAN interface
|
||||
"10-lan0-wan" = {
|
||||
|
@ -377,16 +387,28 @@ in {
|
|||
}
|
||||
];
|
||||
|
||||
vlan = [
|
||||
"br-lan.15"
|
||||
];
|
||||
vlan = (builtins.map
|
||||
(vlanid: "br-lan.${builtins.toString vlanid}")
|
||||
vlanRange
|
||||
);
|
||||
};
|
||||
|
||||
# TODO: generate one of these for each vlanid
|
||||
"41-br-lan.15" = let
|
||||
vlanid = 15;
|
||||
in {
|
||||
matchConfig.Name = "br-lan.15";
|
||||
}
|
||||
|
||||
# configuration for the hostapd dynamic interfaces
|
||||
# TODO: refactor this to configure the following per vlanid
|
||||
# * netdev type vlan
|
||||
# * host address for vlan
|
||||
# * vlan config for wlan interface
|
||||
//
|
||||
builtins.foldl'
|
||||
(acc: cur: acc // cur)
|
||||
{}
|
||||
(builtins.map ({ vlanid, vlanid' }: {
|
||||
# set an address on the tagged br-lan device.
|
||||
# this address will be picked up by dnsmasq.
|
||||
"41-br-lan.${vlanid'}" = {
|
||||
matchConfig.Name = "br-lan.${vlanid'}";
|
||||
address = [
|
||||
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
|
||||
];
|
||||
|
@ -407,15 +429,12 @@ in {
|
|||
];
|
||||
};
|
||||
|
||||
# TODO: generate one of these for each vlanid
|
||||
# configure the wlan interface as a bridge member that
|
||||
# * only gets traffic for vid 15
|
||||
# * untags traffic after receiving it
|
||||
# * tags traffic that comes out of it
|
||||
"41-wlan0.15" = let
|
||||
vlanid = 15;
|
||||
in {
|
||||
matchConfig.Name = "wlan0.15";
|
||||
"41-wlan0.${vlanid'}" = {
|
||||
matchConfig.Name = "wlan0.${vlanid'}";
|
||||
networkConfig = {
|
||||
Bridge = "br-lan";
|
||||
ConfigureWithoutCarrier = true;
|
||||
|
@ -435,51 +454,38 @@ in {
|
|||
];
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
# configuration for the hostapd dynamic interfaces
|
||||
# TODO: refactor this to configure the following per vlanid
|
||||
# * netdev type vlan
|
||||
# * host address for vlan
|
||||
# * vlan config for wlan interface
|
||||
//
|
||||
builtins.foldl'
|
||||
(acc: cur: acc // cur)
|
||||
{}
|
||||
(builtins.map
|
||||
({ vlanid, vlanid' }: {
|
||||
"50-br-lan.${vlanid'}" = {
|
||||
matchConfig.Name = "br-lan.${vlanid'}";
|
||||
address = [
|
||||
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
|
||||
];
|
||||
networkConfig = {
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
linkConfig.RequiredForOnline = "no";
|
||||
|
||||
bridgeVLANs = [
|
||||
{
|
||||
bridgeVLANConfig = {
|
||||
# TODO debug this: each vlanid is native to each port
|
||||
VLAN = vlanid;
|
||||
PVID = vlanid;
|
||||
};
|
||||
}
|
||||
];
|
||||
"50-br-lan.${vlanid'}" = {
|
||||
matchConfig.Name = "br-lan.${vlanid'}";
|
||||
address = [
|
||||
(mkVlanIpv4HostAddr { inherit vlanid; host = 1; })
|
||||
];
|
||||
networkConfig = {
|
||||
ConfigureWithoutCarrier = true;
|
||||
};
|
||||
})
|
||||
(builtins.map
|
||||
(vlanid: { inherit vlanid; vlanid' = builtins.toString vlanid; })
|
||||
vlanRange
|
||||
)
|
||||
);
|
||||
linkConfig.RequiredForOnline = "no";
|
||||
|
||||
bridgeVLANs = [
|
||||
{
|
||||
bridgeVLANConfig = {
|
||||
# TODO debug this: each vlanid is native to each port
|
||||
VLAN = vlanid;
|
||||
PVID = vlanid;
|
||||
};
|
||||
}
|
||||
];
|
||||
};
|
||||
})
|
||||
(builtins.map
|
||||
(vlanid: { inherit vlanid; vlanid' = builtins.toString vlanid; })
|
||||
vlanRange
|
||||
))
|
||||
;
|
||||
};
|
||||
|
||||
# wireless access point
|
||||
services.hostapd = {
|
||||
enable = true;
|
||||
package = nodeFlake.packages.hostapd_main;
|
||||
package = nodeFlake.packages.${system}.hostapd_patched;
|
||||
radios = let
|
||||
# generated with https://miniwebtool.com/mac-address-generator/
|
||||
mkBssid = i: "34:56:ce:0f:ed:4${toString i}";
|
||||
|
@ -521,19 +527,34 @@ in {
|
|||
# https://wireless.wiki.kernel.org/en/users/Documentation/hostapd#dynamic_vlan_tagging
|
||||
# https://forum.openwrt.org/t/individual-per-passphrase-wifi-vlans-using-wpa-psk-file-no-radius-required/161696/4
|
||||
|
||||
dynamic_vlan = 1;
|
||||
|
||||
vlan_no_bridge = 1;
|
||||
|
||||
/* not used due to the above vlan_no_bridge setting
|
||||
vlan_tagged_interface = "br-lan";
|
||||
vlan_naming = 1;
|
||||
vlan_bridge = "br-${iface}.";
|
||||
dynamic_vlan = 1;
|
||||
vlan_file = toString (pkgs.writeText "hostapd.vlan" ''
|
||||
*/
|
||||
|
||||
vlan_file = let
|
||||
generated = builtins.map (vlanid:
|
||||
"${builtins.toString vlanid} ${iface}.${builtins.toString vlanid}"
|
||||
) vlanRange
|
||||
;
|
||||
|
||||
wildcard = [
|
||||
# Optional wildcard entry matching all VLAN IDs. The first # in the interface
|
||||
# name will be replaced with the VLAN ID. The network interfaces are created
|
||||
# (and removed) dynamically based on the use.
|
||||
# see https://w1.fi/cgit/hostap/tree/hostapd/hostapd.vlan
|
||||
* ${iface}.#
|
||||
'');
|
||||
"* ${iface}.#"
|
||||
];
|
||||
|
||||
vlan_no_bridge = 1;
|
||||
file = pkgs.writeText "hostapd.vlan"
|
||||
(builtins.concatStringsSep "\n" (generated ++ wildcard));
|
||||
filePath = toString file;
|
||||
in filePath;
|
||||
|
||||
wpa_key_mgmt = lib.mkForce (builtins.concatStringsSep " " [
|
||||
"WPA-PSK"
|
||||
|
@ -692,7 +713,7 @@ in {
|
|||
tag
|
||||
(mkVlanIpv4HostAddr { inherit vlanid; host = 100; cidr = false; })
|
||||
(mkVlanIpv4HostAddr { inherit vlanid; host = 199; cidr = false; })
|
||||
"5m"
|
||||
"30m"
|
||||
];
|
||||
in
|
||||
builtins.map
|
||||
|
@ -748,7 +769,7 @@ in {
|
|||
|
||||
system.stateVersion = "23.05";
|
||||
|
||||
boot.kernelPackages = pkgs.linuxPackages_bpir3;
|
||||
boot.kernelPackages = pkgs.linuxPackages_bpir3_latest;
|
||||
# We exclude a number of modules included in the default list. A non-insignificant amount do
|
||||
# not apply to embedded hardware like this, so simply skip the defaults.
|
||||
#
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue