diff options
| author | Tim Keller <tjk@tjkeller.xyz> | 2026-01-01 20:38:18 -0600 |
|---|---|---|
| committer | Tim Keller <tjk@tjkeller.xyz> | 2026-01-01 20:38:18 -0600 |
| commit | 8cead66675a61b30a88b02d4c3bd5bfbf2d0afc3 (patch) | |
| tree | 7644517452399ff385868fe0001518410e1c1154 | |
| parent | 91eac5b51bb6b9fa5853753310a3de337d192568 (diff) | |
| download | nixos-8cead66675a61b30a88b02d4c3bd5bfbf2d0afc3.tar.xz nixos-8cead66675a61b30a88b02d4c3bd5bfbf2d0afc3.zip | |
nftables routing module for router
| -rw-r--r-- | archetypes/profiles/router/default.nix | 30 | ||||
| -rw-r--r-- | nixos/default.nix | 1 | ||||
| -rw-r--r-- | nixos/services/router/routing.nix | 69 |
3 files changed, 88 insertions, 12 deletions
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; + }; +} |
