From 8cead66675a61b30a88b02d4c3bd5bfbf2d0afc3 Mon Sep 17 00:00:00 2001 From: Tim Keller Date: Thu, 1 Jan 2026 20:38:18 -0600 Subject: nftables routing module for router --- archetypes/profiles/router/default.nix | 30 +++++++++------ nixos/default.nix | 1 + nixos/services/router/routing.nix | 69 ++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 nixos/services/router/routing.nix diff --git a/archetypes/profiles/router/default.nix b/archetypes/profiles/router/default.nix index 646982b..58e3407 100644 --- a/archetypes/profiles/router/default.nix +++ b/archetypes/profiles/router/default.nix @@ -1,26 +1,32 @@ { lib, pkgs, ... }: let mkRouter = lib.mkOverride 800; + # https://wiki.nixos.org/wiki/Networking nixosConfig = { services.unbound = { _blocklists = { enable = true; - blocklists = { - hageziNSFW = [ - "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/rpz/nsfw.txt" - "https://gitlab.com/hagezi/mirror/-/raw/main/dns-blocklists/rpz/nsfw.txt" - "https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/rpz/nsfw.txt" - ]; - hageziPro = [ - "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/rpz/pro.txt" - "https://gitlab.com/hagezi/mirror/-/raw/main/dns-blocklists/rpz/pro.txt" - "https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/rpz/pro.txt" + blocklists = let + hageziList = list: [ + "https://cdn.jsdelivr.net/gh/hagezi/dns-blocklists@latest/rpz/${list}.txt" + "https://gitlab.com/hagezi/mirror/-/raw/main/dns-blocklists/rpz/${list}.txt" + "https://codeberg.org/hagezi/mirror2/raw/branch/main/dns-blocklists/rpz/${list}.txt" ]; + in { + hageziNSFW = hageziList "nsfw"; + hageziPro = hageziList "pro"; }; }; }; - services._router.dnsDhcpConfig = { - enable = mkRouter true; + services._router = { + dnsDhcpConfig.enable = mkRouter true; + routing = { + enable = mkRouter true; + interfaces = { + lan = mkRouter "lan0"; + wan = mkRouter "wan0"; + }; + }; }; }; diff --git a/nixos/default.nix b/nixos/default.nix index 5ba5f5b..ce04eac 100644 --- a/nixos/default.nix +++ b/nixos/default.nix @@ -8,6 +8,7 @@ ./services/gitea.nix ./services/searxng.nix ./services/router/dns-dhcp.nix + ./services/router/routing.nix ./services/router/unbound-blocklist.nix ./bootloader.nix diff --git a/nixos/services/router/routing.nix b/nixos/services/router/routing.nix new file mode 100644 index 0000000..324e1a9 --- /dev/null +++ b/nixos/services/router/routing.nix @@ -0,0 +1,69 @@ +{ config, lib, ... }: let + cfg = config.services._router.routing; +in { + options.services._router.routing = { + enable = lib.mkEnableOption "enable nftables routing"; + interfaces.wan = lib.mkOption = { + type = lib.types.str; + default = ""; + description = "wan interface"; + }; + interfaces.lan = lib.mkOption = { + type = lib.types.str; + default = ""; + description = "lan interface"; + }; + }; + + config = lib.mkIf cfg.enable { + networking.nftables = { + enable = true; + table = { + filter = { + family = "ip"; + # https://hackers-arise.com/linux-basics-for-hackers-building-a-router-with-nftables/ + content = '' + chain input { + type filter hook input priority 0; policy drop; + + # Allow established/related connections + ct state established,related accept + + # Allow loopback + iifname "lo" accept + + # Allow LAN to access router + iifname ${cfg.interfaces.lan} accept + + # Allow ICMP from WAN (for ping) + iifname ${cfg.interfaces.wan} icmp type echo-request accept + + # Drop invalid connections + ct state invalid drop + } + + chain forward { + type filter hook forward priority 0; policy drop; + + # Allow established/related connections + ct state established,related accept + + # Allow LAN to WAN + iifname ${cfg.interfaces.lan} oifname ${cfg.interfaces.wan} accept + + # Drop invalid connections + ct state invalid drop + } + + chain output { + type filter hook output priority 0; policy accept; + } + ''; + + } + }; + }; + networking.nat.enable = true; + networking.firewall.enable = true; + }; +} -- cgit v1.2.3