use nftables on all haproxy host for better blacklisting

This commit is contained in:
goeranh 2026-05-02 00:29:06 +02:00
parent d0a8fb0c09
commit 66d6857710
No known key found for this signature in database
2 changed files with 157 additions and 23 deletions

View file

@ -20,22 +20,49 @@
} }
]; ];
defaultGateway.address = "141.56.51.254"; defaultGateway.address = "141.56.51.254";
firewall = { firewall.enable = false;
allowedTCPPorts = [
22
53 # DNS
80
443
1005
2142
];
allowedUDPPorts = [
53 # DNS
123 # NTP
];
};
nftables = { nftables = {
enable = true; 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" ]; stura.monitoring.extraLogInputs = [ "haproxy_geoip" ];
users.users.root.packages = [
(pkgs.writeShellScriptBin "nft-blacklist" ''
set -euo pipefail
usage() {
echo "Usage: nft-blacklist <add|del> <ip-or-cidr>"
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; [ environment.systemPackages = with pkgs; [
]; ];

View file

@ -38,16 +38,44 @@
"9.9.9.9" "9.9.9.9"
"1.1.1.1" "1.1.1.1"
]; ];
firewall = { firewall.enable = false;
enable = true;
allowedTCPPorts = [
22
80
443
];
};
nftables = { nftables = {
enable = true; 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 <add|del> <ip-or-cidr>"
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"; system.stateVersion = "25.11";