From c1756f5809264355d3d3ee4fb4700cf41a866759 Mon Sep 17 00:00:00 2001 From: Daniel Micay Date: Wed, 3 Apr 2024 13:13:52 -0400 Subject: [PATCH] add synproxy/connlimit for ACME/redirect use of HTTP This makes it easier to maintain and deploy more aggressive DDoS mitigation when our main HTTPS services are under attack. Network servers use HTTP for connectivity checks which do not use keepalive and should also be a good use case for --- nftables-attestation.conf | 24 +++++++++++++++++++----- nftables-discuss.conf | 24 +++++++++++++++++++----- nftables-matrix.conf | 24 +++++++++++++++++++----- nftables-social.conf | 24 +++++++++++++++++++----- nftables-web.conf | 24 +++++++++++++++++++----- 5 files changed, 95 insertions(+), 25 deletions(-) diff --git a/nftables-attestation.conf b/nftables-attestation.conf index 70aab4a..8e808bc 100644 --- a/nftables-attestation.conf +++ b/nftables-attestation.conf @@ -21,6 +21,16 @@ table inet filter { flags dynamic } + set ip-connlimit-http { + type ipv4_addr + flags dynamic + } + + set ip6-connlimit-http { + type ipv6_addr + flags dynamic + } + chain prerouting-raw { type filter hook prerouting priority raw @@ -32,8 +42,8 @@ table inet filter { # drop packets to address not configured on incoming interface (strong host model) fib daddr . iif type != { local, broadcast, multicast } counter drop - tcp dport { 80, 443 } notrack accept - tcp dport 22 tcp flags syn notrack accept + tcp dport 443 notrack accept + tcp dport { 22, 80 } tcp flags syn notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -41,7 +51,7 @@ table inet filter { type filter hook output priority raw oif lo notrack accept - tcp sport { 80, 443 } notrack accept + tcp sport 443 notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -50,18 +60,22 @@ table inet filter { policy drop iif lo goto input-loopback - tcp dport { 80, 443 } accept + tcp dport 443 accept meta l4proto { icmp, ipv6-icmp } accept ct state vmap { established : accept, related : accept, new : goto graceful-reject } tcp dport 22 ip saddr @ip-connlimit-ssh counter reject with tcp reset tcp dport 22 ip6 saddr and ffff:ffff:ffff:ffff:ffff:: @ip6-connlimit-ssh counter reject with tcp reset - tcp dport 22 synproxy mss 1460 wscale 7 timestamp sack-perm + tcp dport 80 ip saddr @ip-connlimit-http counter reject with tcp reset + tcp dport 80 ip6 saddr and ffff:ffff:ffff:ffff:: @ip6-connlimit-http counter reject with tcp reset + tcp dport { 22, 80 } synproxy mss 1460 wscale 7 timestamp sack-perm } chain input-loopback { tcp dport 22 tcp flags syn ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } counter reject with tcp reset tcp dport 22 tcp flags syn ip6 saddr != $ip6-allowlist-ssh add @ip6-connlimit-ssh { ip6 saddr and ffff:ffff:ffff:ffff:ffff:: ct count over 1 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip-connlimit-http { ip saddr ct count over 32 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip6-connlimit-http { ip6 saddr and ffff:ffff:ffff:ffff:: ct count over 32 } counter reject with tcp reset accept } diff --git a/nftables-discuss.conf b/nftables-discuss.conf index 575797f..de36be9 100644 --- a/nftables-discuss.conf +++ b/nftables-discuss.conf @@ -21,6 +21,16 @@ table inet filter { flags dynamic } + set ip-connlimit-http { + type ipv4_addr + flags dynamic + } + + set ip6-connlimit-http { + type ipv6_addr + flags dynamic + } + chain prerouting-raw { type filter hook prerouting priority raw @@ -35,8 +45,8 @@ table inet filter { # IPv6 interacts badly with IP-based spam filtering meta nfproto ipv6 tcp dport { 80, 443 } reject with tcp reset - tcp dport { 80, 443 } notrack accept - tcp dport 22 tcp flags syn notrack accept + tcp dport 443 notrack accept + tcp dport { 22, 80 } tcp flags syn notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -44,7 +54,7 @@ table inet filter { type filter hook output priority raw oif lo notrack accept - tcp sport { 80, 443 } notrack accept + tcp sport 443 notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -53,18 +63,22 @@ table inet filter { policy drop iif lo goto input-loopback - tcp dport { 80, 443 } accept + tcp dport 443 accept meta l4proto { icmp, ipv6-icmp } accept ct state vmap { established : accept, related : accept, new : goto graceful-reject } tcp dport 22 ip saddr @ip-connlimit-ssh counter reject with tcp reset tcp dport 22 ip6 saddr and ffff:ffff:ffff:ffff:ffff:: @ip6-connlimit-ssh counter reject with tcp reset - tcp dport 22 synproxy mss 1460 wscale 7 timestamp sack-perm + tcp dport 80 ip saddr @ip-connlimit-http counter reject with tcp reset + tcp dport 80 ip6 saddr and ffff:ffff:ffff:ffff:: @ip6-connlimit-http counter reject with tcp reset + tcp dport { 22, 80 } synproxy mss 1460 wscale 7 timestamp sack-perm } chain input-loopback { tcp dport 22 tcp flags syn ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } counter reject with tcp reset tcp dport 22 tcp flags syn ip6 saddr != $ip6-allowlist-ssh add @ip6-connlimit-ssh { ip6 saddr and ffff:ffff:ffff:ffff:ffff:: ct count over 1 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip-connlimit-http { ip saddr ct count over 32 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip6-connlimit-http { ip6 saddr and ffff:ffff:ffff:ffff:: ct count over 32 } counter reject with tcp reset accept } diff --git a/nftables-matrix.conf b/nftables-matrix.conf index 9724f16..2034397 100644 --- a/nftables-matrix.conf +++ b/nftables-matrix.conf @@ -21,6 +21,16 @@ table inet filter { flags dynamic } + set ip-connlimit-http { + type ipv4_addr + flags dynamic + } + + set ip6-connlimit-http { + type ipv6_addr + flags dynamic + } + chain prerouting-raw { type filter hook prerouting priority raw @@ -32,8 +42,8 @@ table inet filter { # drop packets to address not configured on incoming interface (strong host model) fib daddr . iif type != { local, broadcast, multicast } counter drop - tcp dport { 80, 443 } notrack accept - tcp dport 22 tcp flags syn notrack accept + tcp dport 443 notrack accept + tcp dport { 22, 80 } tcp flags syn notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -41,7 +51,7 @@ table inet filter { type filter hook output priority raw oif lo notrack accept - tcp sport { 80, 443 } notrack accept + tcp sport 443 notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -50,18 +60,22 @@ table inet filter { policy drop iif lo goto input-loopback - tcp dport { 80, 443 } accept + tcp dport 443 accept meta l4proto { icmp, ipv6-icmp } accept ct state vmap { established : accept, related : accept, new : goto graceful-reject } tcp dport 22 ip saddr @ip-connlimit-ssh counter reject with tcp reset tcp dport 22 ip6 saddr and ffff:ffff:ffff:ffff:ffff:: @ip6-connlimit-ssh counter reject with tcp reset - tcp dport 22 synproxy mss 1460 wscale 7 timestamp sack-perm + tcp dport 80 ip saddr @ip-connlimit-http counter reject with tcp reset + tcp dport 80 ip6 saddr and ffff:ffff:ffff:ffff:: @ip6-connlimit-http counter reject with tcp reset + tcp dport { 22, 80 } synproxy mss 1460 wscale 7 timestamp sack-perm } chain input-loopback { tcp dport 22 tcp flags syn ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } counter reject with tcp reset tcp dport 22 tcp flags syn ip6 saddr != $ip6-allowlist-ssh add @ip6-connlimit-ssh { ip6 saddr and ffff:ffff:ffff:ffff:ffff:: ct count over 1 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip-connlimit-http { ip saddr ct count over 32 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip6-connlimit-http { ip6 saddr and ffff:ffff:ffff:ffff:: ct count over 32 } counter reject with tcp reset accept } diff --git a/nftables-social.conf b/nftables-social.conf index 927ddef..abe5388 100644 --- a/nftables-social.conf +++ b/nftables-social.conf @@ -21,6 +21,16 @@ table inet filter { flags dynamic } + set ip-connlimit-http { + type ipv4_addr + flags dynamic + } + + set ip6-connlimit-http { + type ipv6_addr + flags dynamic + } + chain prerouting-raw { type filter hook prerouting priority raw @@ -32,8 +42,8 @@ table inet filter { # drop packets to address not configured on incoming interface (strong host model) fib daddr . iif type != { local, broadcast, multicast } counter drop - tcp dport { 80, 443 } notrack accept - tcp dport 22 tcp flags syn notrack accept + tcp dport 443 notrack accept + tcp dport { 22, 80 } tcp flags syn notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -41,7 +51,7 @@ table inet filter { type filter hook output priority raw oif lo notrack accept - tcp sport { 80, 443 } notrack accept + tcp sport 443 notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -50,18 +60,22 @@ table inet filter { policy drop iif lo goto input-loopback - tcp dport { 80, 443 } accept + tcp dport 443 accept meta l4proto { icmp, ipv6-icmp } accept ct state vmap { established : accept, related : accept, new : goto graceful-reject } tcp dport 22 ip saddr @ip-connlimit-ssh counter reject with tcp reset tcp dport 22 ip6 saddr and ffff:ffff:ffff:ffff:ffff:: @ip6-connlimit-ssh counter reject with tcp reset - tcp dport 22 synproxy mss 1460 wscale 7 timestamp sack-perm + tcp dport 80 ip saddr @ip-connlimit-http counter reject with tcp reset + tcp dport 80 ip6 saddr and ffff:ffff:ffff:ffff:: @ip6-connlimit-http counter reject with tcp reset + tcp dport { 22, 80 } synproxy mss 1460 wscale 7 timestamp sack-perm } chain input-loopback { tcp dport 22 tcp flags syn ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } counter reject with tcp reset tcp dport 22 tcp flags syn ip6 saddr != $ip6-allowlist-ssh add @ip6-connlimit-ssh { ip6 saddr and ffff:ffff:ffff:ffff:ffff:: ct count over 1 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip-connlimit-http { ip saddr ct count over 32 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip6-connlimit-http { ip6 saddr and ffff:ffff:ffff:ffff:: ct count over 32 } counter reject with tcp reset accept } diff --git a/nftables-web.conf b/nftables-web.conf index fe280c2..199af88 100644 --- a/nftables-web.conf +++ b/nftables-web.conf @@ -25,6 +25,16 @@ table inet filter { flags dynamic } + set ip-connlimit-http { + type ipv4_addr + flags dynamic + } + + set ip6-connlimit-http { + type ipv6_addr + flags dynamic + } + chain prerouting-raw { type filter hook prerouting priority raw @@ -36,8 +46,8 @@ table inet filter { # drop packets to address not configured on incoming interface (strong host model) fib daddr . iif type != { local, broadcast, multicast } counter drop - tcp dport { 80, 443 } notrack accept - tcp dport 22 tcp flags syn notrack accept + tcp dport 443 notrack accept + tcp dport { 22, 80 } tcp flags syn notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -45,7 +55,7 @@ table inet filter { type filter hook output priority raw oif lo notrack accept - tcp sport { 80, 443 } notrack accept + tcp sport 443 notrack accept meta l4proto { icmp, ipv6-icmp } notrack accept } @@ -54,18 +64,22 @@ table inet filter { policy drop iif lo goto input-loopback - tcp dport { 80, 443 } accept + tcp dport 443 accept meta l4proto { icmp, ipv6-icmp } accept ct state vmap { established : accept, related : accept, new : goto graceful-reject } tcp dport 22 ip saddr @ip-connlimit-ssh counter reject with tcp reset tcp dport 22 ip6 saddr and ffff:ffff:ffff:ffff:ffff:: @ip6-connlimit-ssh counter reject with tcp reset - tcp dport 22 synproxy mss 1460 wscale 7 timestamp sack-perm + tcp dport 80 ip saddr @ip-connlimit-http counter reject with tcp reset + tcp dport 80 ip6 saddr and ffff:ffff:ffff:ffff:: @ip6-connlimit-http counter reject with tcp reset + tcp dport { 22, 80 } synproxy mss 1460 wscale 7 timestamp sack-perm } chain input-loopback { tcp dport 22 tcp flags syn ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } counter reject with tcp reset tcp dport 22 tcp flags syn ip6 saddr != $ip6-allowlist-ssh add @ip6-connlimit-ssh { ip6 saddr and ffff:ffff:ffff:ffff:ffff:: ct count over 1 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip-connlimit-http { ip saddr ct count over 32 } counter reject with tcp reset + tcp dport 80 tcp flags syn add @ip6-connlimit-http { ip6 saddr and ffff:ffff:ffff:ffff:: ct count over 32 } counter reject with tcp reset accept }