From 925fc182e5ea9b87c3a62e80f5a20be4e827cd3b Mon Sep 17 00:00:00 2001 From: "quentin@aristote.fr" Date: Thu, 18 May 2023 13:39:06 +0200 Subject: config: networking: hostapd: disable low-level bridging --- config/networking/services/ap.nix | 23 ++-- config/networking/services/default.nix | 2 +- config/networking/services/firewall.nix | 165 ------------------------ config/networking/services/firewall/default.nix | 31 +++++ config/networking/services/firewall/ruleset.nix | 160 +++++++++++++++++++++++ 5 files changed, 206 insertions(+), 175 deletions(-) delete mode 100644 config/networking/services/firewall.nix create mode 100644 config/networking/services/firewall/default.nix create mode 100644 config/networking/services/firewall/ruleset.nix (limited to 'config/networking/services') diff --git a/config/networking/services/ap.nix b/config/networking/services/ap.nix index 202cff5..d93e053 100644 --- a/config/networking/services/ap.nix +++ b/config/networking/services/ap.nix @@ -2,12 +2,12 @@ let cfg = config.services.hostapd; - makeHostapdConf = { name, interface ? cfg.interface, driver ? cfg.driver, ssid + makeHostapdConf = { name, device, interface, driver ? cfg.driver, ssid , hwMode ? cfg.hwMode, channel ? cfg.channel, countryCode ? cfg.countryCode , passphrase ? secrets.wifi."${name}".passphrase, logLevel ? cfg.logLevel , extraConfig ? "" }: builtins.toFile "hostapd.${name}.conf" ('' - interface=${interface} + interface=${device} driver=${driver} # IEEE 802.11 @@ -23,6 +23,9 @@ let ieee80211d=1 country_code=${countryCode} + # disable low-level bridging of frames + ap_isolate=1 + bridge=${interface} # WPA/IEEE 802.11i wpa=2 @@ -80,7 +83,7 @@ let '' + extraConfig); hostapdIotConf = makeHostapdConf { name = "iot"; - interface = config.personal.networking.networks.iot.interface; + inherit (config.personal.networking.networks.iot) device interface; ssid = "Quentinternet of Things"; hwMode = "g"; channel = 0; @@ -93,7 +96,7 @@ let }; hostapdWanConf = makeHostapdConf { name = "wan"; - interface = config.personal.networking.networks.wan.interface; + inherit (config.personal.networking.networks.wan) device interface; ssid = "Quentintranet"; hwMode = "a"; channel = 36; @@ -119,15 +122,17 @@ in { }; systemd.services.hostapd = let - interfaces = with config.personal.networking.networks; [ + devices = with config.personal.networking.networks; [ + wan.device wan.interface + iot.device iot.interface ]; - netDevices = builtins.map (interface: - "sys-subsystem-net-devices-${utils.escapeSystemdPath interface}.device") - interfaces; + netDevices = builtins.map (device: + "sys-subsystem-net-devices-${utils.escapeSystemdPath device}.device") + devices; networkLinkServices = - builtins.map (interface: "network-link-${interface}.service") interfaces; + builtins.map (device: "network-link-${device}.service") devices; in { serviceConfig.ExecStart = lib.mkForce "${pkgs.hostapd}/bin/hostapd ${hostapdIotConf} ${hostapdWanConf}"; diff --git a/config/networking/services/default.nix b/config/networking/services/default.nix index e51aa5a..454a9e1 100644 --- a/config/networking/services/default.nix +++ b/config/networking/services/default.nix @@ -1,5 +1,5 @@ { ... }: { - imports = [ ./ap.nix ./dhcp.nix ./dns.nix ./firewall.nix ]; + imports = [ ./ap.nix ./dhcp.nix ./dns.nix ./firewall ]; } diff --git a/config/networking/services/firewall.nix b/config/networking/services/firewall.nix deleted file mode 100644 index a0aa281..0000000 --- a/config/networking/services/firewall.nix +++ /dev/null @@ -1,165 +0,0 @@ -{ config, lib, ... }: - -let nets = config.personal.networking.networks; -in { - boot.kernel.sysctl = { "net.ipv4.conf.all.forwarding" = true; }; - - networking = { - nftables = { - enable = true; - ruleset = with nets; '' - table ip filter { - chain conntrack { - ct state vmap { established : accept \ - , related : accept \ - , invalid : drop } - } - chain dhcp { - # https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#Operation - ip protocol udp \ - udp sport 68 \ - udp dport 67 \ - accept comment "dhcp" - } - chain dns { - # https://en.wikipedia.org/wiki/Domain_Name_System#Transport_protocols - ip protocol { tcp, udp } \ - th sport 53 \ - th dport 53 \ - accept comment "dns" - } - chain kdeconnect { - # https://userbase.kde.org/KDEConnect#I_have_two_devices_running_KDE_Connect_on_the_same_network,_but_they_can't_see_each_other - ip protocol { tcp, udp } \ - th sport 1714-1764 \ - th dport 1714-1764 \ - accept comment "kdeconnect" - } - chain sonos_app { - # https://support.sonos.com/en-us/article/configure-your-firewall-to-work-with-sonos - # https://en.community.sonos.com/advanced-setups-229000/changed-udp-tcp-ports-for-sonos-app-needed-after-update-to-s2-6842454 - ip protocol tcp \ - tcp sport { 1400, 3400, 3401, 3500 } \ - tcp dport { 1400, 3400, 3401, 3500 } \ - accept comment "sonos: app control" - ip protocol udp \ - udp sport 1900-1901 \ - udp dport 1900-1901 \ - accept comment "sonos: app control" - } - chain sonos { - # https://support.sonos.com/en-us/article/configure-your-firewall-to-work-with-sonos - # https://en.community.sonos.com/advanced-setups-229000/changed-udp-tcp-ports-for-sonos-app-needed-after-update-to-s2-6842454 - ip protocol tcp \ - tcp sport 4444 \ - tcp dport 4444 \ - accept comment "sonos: system updates" - ip protocol udp \ - udp sport 6969 \ - udp dport 6969 \ - accept comment "sonos: setup" - ip protocol udp \ - udp sport { 32413, 32414 } \ - udp dport { 32412, 32414 } \ - accept comment "sonos" - } - chain ssh { - ip protocol tcp \ - tcp dport 22 \ - accept comment "ssh" - } - chain steam { - # https://help.steampowered.com/en/faqs/view/2EA8-4D75-DA21-31EB - ip protocol { udp, tcp } \ - th dport 27015-27050 \ - accept comment "steam: login, download" - ip protocol udp \ - udp dport 27000-27100 \ - accept comment "steam: client: game traffic" - ip protocol . th sport \ - { udp . 27031-27036, tcp . 27036 } \ - accept comment "steam: client: remote play" - ip protocol udp \ - udp dport 4380 \ - accept comment "steam: client" - ip protocol tcp \ - tcp sport 27015 \ - accept comment "steam: servers: SRCDS Rcon port" - ip protocol udp \ - udp sport 27015 \ - accept comment "steam: servers: gameplay traffic" - ip protocol udp \ - udp dport { 3478, 4379, 4380, 27014-27030 } \ - accept comment "steam: p2p, voice chat" - } - chain syncthing { - # https://docs.syncthing.net/users/firewall.html - ip protocol { tcp, udp } \ - th sport 22000 \ - th dport 22000 \ - accept comment "syncthing" - ip protocol udp \ - udp sport 21027 \ - udp dport 21027 \ - accept comment "syncthing: discovery broadcasts" - } - - chain in_wan { - jump dns - jump dhcp - jump ssh - } - chain in_iot { - jump dns - jump dhcp - } - chain inbound { - type filter hook input priority 0; policy drop; - icmp type echo-request limit rate 5/second accept - jump conntrack - meta iifname vmap \ - { lo : accept \ - , ${lan.interface} : drop \ - , ${wan.interface} : goto in_wan \ - , ${iot.interface} : goto in_iot } - } - - chain wan_wan { - jump kdeconnect - jump syncthing - } - chain iot_wan { - jump sonos_app - } - chain forward { - type filter hook forward priority 0; policy drop; - jump conntrack - meta oifname ${lan.interface} accept - meta iifname ${wan.interface} meta oifname ${wan.interface} \ - goto wan_wan - meta iifname ${iot.interface} meta oifname ${wan.interface} \ - goto iot_wan - } - } - - table ip nat { - chain postrouting { - type nat hook postrouting priority 100; policy accept; - meta oifname ${lan.interface} snat to ${lan.machines.self.address} - } - } - - table ip6 global6 { - chain input { - type filter hook input priority 0; policy drop; - } - chain forward { - type filter hook forward priority 0; policy drop; - } - } - ''; - }; - - firewall.enable = lib.mkForce false; - }; -} diff --git a/config/networking/services/firewall/default.nix b/config/networking/services/firewall/default.nix new file mode 100644 index 0000000..878e7cc --- /dev/null +++ b/config/networking/services/firewall/default.nix @@ -0,0 +1,31 @@ +{ config, lib, ... }: + +let + # { any } -> (string -> any -> [ string ]) -> string + mapAttrsStrings = attrs: f: lib.concatStrings (lib.mapAttrsToList f attrs); + bracket = title: content: + '' + ${title} { + '' + content + '' + } + ''; +in { + boot.kernel.sysctl = { "net.ipv4.conf.all.forwarding" = true; }; + + networking = { + nftables = { + enable = true; + ruleset = mapAttrsStrings + (import ./ruleset.nix config.personal.networking.networks) + (family: tables: + mapAttrsStrings tables (tableName: chains: + bracket "table ${family} ${tableName}" (mapAttrsStrings chains + (chainName: chain: + bracket "chain ${chainName}" (lib.optionalString (chain ? base) + (with chain.base; '' + type ${type} hook ${hook} priority ${priority}; policy ${policy}; + '') + chain.rules))))); + }; + firewall.enable = lib.mkForce false; + }; +} diff --git a/config/networking/services/firewall/ruleset.nix b/config/networking/services/firewall/ruleset.nix new file mode 100644 index 0000000..b3e75c7 --- /dev/null +++ b/config/networking/services/firewall/ruleset.nix @@ -0,0 +1,160 @@ +{ lan, wan, iot, ... }: + +let + makeBaseChain = type: hook: + { priority ? type, policy ? "drop", rules ? "" }: { + base = { inherit type hook priority policy; }; + inherit rules; + }; + rulesCommon = { + conntrack = '' + ct state vmap { established : accept \ + , related : accept \ + , invalid : drop } + ''; + # https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol#Operation + dhcp = '' + ip protocol udp \ + udp sport 68 \ + udp dport 67 \ + accept comment dhcp + ''; + # https://en.wikipedia.org/wiki/Domain_Name_System#Transport_protocols + dns = '' + ip protocol { tcp, udp } \ + th sport 53 \ + th dport 53 \ + accept comment dns + ''; + # https://userbase.kde.org/KDEConnect#I_have_two_devices_running_KDE_Connect_on_the_same_network,_but_they_can't_see_each_other + kdeconnect = '' + ip protocol { tcp, udp } \ + th dport 1714-1764 \ + accept comment kdeconnect + ''; + ping = '' + icmp type echo-request limit rate 5/second accept + ''; + ssh = '' + ip protocol tcp \ + tcp dport 22 \ + accept comment ssh + ''; + # # https://docs.syncthing.net/users/firewall.html + syncthing = '' + ip protocol tcp \ + tcp sport 22000 \ + tcp dport 22000 \ + accept comment syncthing + ip protocol udp \ + udp dport 21027 \ + accept comment "syncthing: discovery broadcast" + ''; + }; +in { + ip = { + filter = { + wan_in.rules = with rulesCommon; dns + dhcp + ssh; + iot_in.rules = with rulesCommon; dns + dhcp; + input = makeBaseChain "filter" "input" { + rules = with rulesCommon; + conntrack + ping + '' + meta iifname vmap { lo : accept \ + , ${lan.interface} : drop \ + , ${wan.interface} : goto wan_in \ + , ${iot.interface} : goto iot_in } + ''; + }; + forward = makeBaseChain "filter" "forward" { + rules = with rulesCommon; + conntrack + '' + meta oifname ${lan.interface} accept + ''; + }; + }; + nat = { + postrouting = makeBaseChain "nat" "postrouting" { + priority = "srcnat"; + policy = "accept"; + rules = '' + meta oifname ${lan.interface} snat to ${lan.machines.self.address} + ''; + }; + }; + }; + + ip6 = { + global6 = { + input = makeBaseChain "filter" "input" { }; + forward = makeBaseChain "filter" "forward" { }; + }; + }; + + bridge = { + filter = { + wan_wan.rules = with rulesCommon; syncthing + kdeconnect; + forward = makeBaseChain "filter" "forward" { + rules = with rulesCommon; + conntrack + '' + ether type vmap { ip6 : drop, arp : accept } + '' + ping + '' + meta ibrname . meta obrname vmap \ + { ${wan.interface} . ${wan.interface} : goto wan_wan } + ''; + }; + }; + }; +} + +# chain sonos_app { +# # https://support.sonos.com/en-us/article/configure-your-firewall-to-work-with-sonos +# # https://en.community.sonos.com/advanced-setups-229000/changed-udp-tcp-ports-for-sonos-app-needed-after-update-to-s2-6842454 +# ip protocol tcp \ +# tcp sport { 1400, 3400, 3401, 3500 } \ +# tcp dport { 1400, 3400, 3401, 3500 } \ +# accept comment "sonos: app control" +# ip protocol udp \ +# udp sport 1900-1901 \ +# udp dport 1900-1901 \ +# accept comment "sonos: app control" +# } +# chain sonos { +# # https://support.sonos.com/en-us/article/configure-your-firewall-to-work-with-sonos +# # https://en.community.sonos.com/advanced-setups-229000/changed-udp-tcp-ports-for-sonos-app-needed-after-update-to-s2-6842454 +# ip protocol tcp \ +# tcp sport 4444 \ +# tcp dport 4444 \ +# accept comment "sonos: system updates" +# ip protocol udp \ +# udp sport 6969 \ +# udp dport 6969 \ +# accept comment "sonos: setup" +# ip protocol udp \ +# udp sport { 32413, 32414 } \ +# udp dport { 32412, 32414 } \ +# accept comment "sonos" +# } +# chain steam { +# # https://help.steampowered.com/en/faqs/view/2EA8-4D75-DA21-31EB +# ip protocol { udp, tcp } \ +# th dport 27015-27050 \ +# accept comment "steam: login, download" +# ip protocol udp \ +# udp dport 27000-27100 \ +# accept comment "steam: client: game traffic" +# ip protocol . th sport \ +# { udp . 27031-27036, tcp . 27036 } \ +# accept comment "steam: client: remote play" +# ip protocol udp \ +# udp dport 4380 \ +# accept comment "steam: client" +# ip protocol tcp \ +# tcp sport 27015 \ +# accept comment "steam: servers: SRCDS Rcon port" +# ip protocol udp \ +# udp sport 27015 \ +# accept comment "steam: servers: gameplay traffic" +# ip protocol udp \ +# udp dport { 3478, 4379, 4380, 27014-27030 } \ +# accept comment "steam: p2p, voice chat" +# } -- cgit v1.2.3