From 66d68577101ed1deae245de93775f5b03440ebb0 Mon Sep 17 00:00:00 2001 From: goeranh Date: Sat, 2 May 2026 00:29:06 +0200 Subject: [PATCH] use nftables on all haproxy host for better blacklisting --- hosts/proxy/default.nix | 96 +++++++++++++++++++++++++++++++++------ hosts/v6proxy/default.nix | 84 ++++++++++++++++++++++++++++++---- 2 files changed, 157 insertions(+), 23 deletions(-) diff --git a/hosts/proxy/default.nix b/hosts/proxy/default.nix index 8bba097..7fa2238 100644 --- a/hosts/proxy/default.nix +++ b/hosts/proxy/default.nix @@ -20,22 +20,49 @@ } ]; defaultGateway.address = "141.56.51.254"; - firewall = { - allowedTCPPorts = [ - 22 - 53 # DNS - 80 - 443 - 1005 - 2142 - ]; - allowedUDPPorts = [ - 53 # DNS - 123 # NTP - ]; - }; + firewall.enable = false; nftables = { enable = true; + ruleset = '' + table inet filter { + set blacklist4 { + type ipv4_addr + flags interval + # manage: nft add element inet filter blacklist4 { 1.2.3.0/24 } + } + + set blacklist6 { + type ipv6_addr + flags interval + # manage: nft add element inet filter blacklist6 { 2001:db8::/32 } + } + + chain input { + type filter hook input priority filter; policy drop; + + iif "lo" accept + ct state established,related accept + + ip saddr @blacklist4 drop + ip6 saddr @blacklist6 drop + + # public ports + tcp dport { 80, 443, 1005, 2142 } accept + + # lan-only: dns and ntp + ip saddr 141.56.51.0/24 tcp dport 53 accept + ip saddr 141.56.51.0/24 udp dport { 53, 123 } accept + } + + chain forward { + type filter hook forward priority filter; policy drop; + } + + chain output { + type filter hook output priority filter; policy accept; + } + } + ''; }; }; @@ -611,6 +638,47 @@ stura.monitoring.extraLogInputs = [ "haproxy_geoip" ]; + users.users.root.packages = [ + (pkgs.writeShellScriptBin "nft-blacklist" '' + set -euo pipefail + + usage() { + echo "Usage: nft-blacklist " + echo " add - add entry to blacklist set" + echo " del - remove entry from blacklist set" + exit 1 + } + + [[ $# -ne 2 ]] && usage + + ACTION="$1" + ADDR="$2" + + if [[ "$ADDR" == *:* ]]; then + SET="blacklist6" + elif [[ "$ADDR" == *.* ]]; then + SET="blacklist4" + else + echo "Error: cannot determine address family for '$ADDR'" >&2 + exit 1 + fi + + case "$ACTION" in + add) + ${pkgs.nftables}/bin/nft add element inet filter "$SET" "{ $ADDR }" + echo "Added $ADDR to $SET" + ;; + del) + ${pkgs.nftables}/bin/nft delete element inet filter "$SET" "{ $ADDR }" + echo "Removed $ADDR from $SET" + ;; + *) + usage + ;; + esac + '') + ]; + environment.systemPackages = with pkgs; [ ]; diff --git a/hosts/v6proxy/default.nix b/hosts/v6proxy/default.nix index 270ef2c..39e2521 100644 --- a/hosts/v6proxy/default.nix +++ b/hosts/v6proxy/default.nix @@ -38,16 +38,44 @@ "9.9.9.9" "1.1.1.1" ]; - firewall = { - enable = true; - allowedTCPPorts = [ - 22 - 80 - 443 - ]; - }; + firewall.enable = false; nftables = { enable = true; + ruleset = '' + table inet filter { + set blacklist4 { + type ipv4_addr + flags interval + # manage at runtime: nft add element inet filter blacklist4 { 1.2.3.0/24 } + } + + set blacklist6 { + type ipv6_addr + flags interval + # manage at runtime: nft add element inet filter blacklist6 { 2001:db8::/32 } + } + + chain input { + type filter hook input priority filter; policy drop; + + iif "lo" accept + ct state established,related accept + + ip saddr @blacklist4 drop + ip6 saddr @blacklist6 drop + + tcp dport { 22, 80, 443 } accept + } + + chain forward { + type filter hook forward priority filter; policy drop; + } + + chain output { + type filter hook output priority filter; policy accept; + } + } + ''; }; }; @@ -102,7 +130,45 @@ }; }; - environment.systemPackages = with pkgs; [ + users.users.root.packages = [ + (pkgs.writeShellScriptBin "nft-blacklist" '' + set -euo pipefail + + usage() { + echo "Usage: nft-blacklist " + echo " add - add entry to blacklist set" + echo " del - remove entry from blacklist set" + exit 1 + } + + [[ $# -ne 2 ]] && usage + + ACTION="$1" + ADDR="$2" + + if [[ "$ADDR" == *:* ]]; then + SET="blacklist6" + elif [[ "$ADDR" == *.* ]]; then + SET="blacklist4" + else + echo "Error: cannot determine address family for '$ADDR'" >&2 + exit 1 + fi + + case "$ACTION" in + add) + ${pkgs.nftables}/bin/nft add element inet filter "$SET" "{ $ADDR }" + echo "Added $ADDR to $SET" + ;; + del) + ${pkgs.nftables}/bin/nft delete element inet filter "$SET" "{ $ADDR }" + echo "Removed $ADDR from $SET" + ;; + *) + usage + ;; + esac + '') ]; system.stateVersion = "25.11";