move IP-based DNS connection limits to nftables

This reuses the approach in cd59960e7b for
SSH connection limits with the same rationale.

PowerDNS also lacks a way to allowlist an address and was limiting our
ADoT reverse proxy to only being able to make 16 connections to the
backend. We could have worked around that by proxing every TCP DNS
connection but it makes more sense to switch to doing this via nftables
where new TCP connections can be completely avoided.

TCP DNS will be perfectly fine without window scaling and Selective
Acknowledgements for clients without TCP timestamps enabled.
This commit is contained in:
Daniel Micay 2024-03-28 10:34:59 -04:00
parent 6b573fe227
commit d95752bea6
2 changed files with 38 additions and 8 deletions

View File

@ -21,6 +21,16 @@ table inet filter {
flags dynamic
}
set ip-connlimit-dns {
type ipv4_addr
flags dynamic
}
set ip6-connlimit-dns {
type ipv6_addr
flags dynamic
}
chain prerouting-raw {
type filter hook prerouting priority raw
@ -33,8 +43,8 @@ table inet filter {
fib daddr . iif type != { local, broadcast, multicast } counter drop
udp dport 53 notrack accept
tcp dport { 53, 80, 443, 853 } notrack accept
tcp dport 22 tcp flags syn notrack accept
tcp dport { 80, 443 } notrack accept
tcp dport { 22, 53, 853 } tcp flags syn notrack accept
meta l4proto { icmp, ipv6-icmp } notrack accept
}
@ -43,7 +53,7 @@ table inet filter {
oif lo notrack accept
udp sport 53 notrack accept
tcp sport { 53, 80, 443, 853 } notrack accept
tcp sport { 80, 443 } notrack accept
meta l4proto { icmp, ipv6-icmp } notrack accept
}
@ -53,16 +63,21 @@ table inet filter {
iif lo tcp dport 22 tcp flags syn ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } reject with tcp reset
iif lo 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 } reject with tcp reset
iif lo tcp dport { 53, 853 } tcp flags syn add @ip-connlimit-dns { ip saddr ct count over 16 } reject with tcp reset
iif lo tcp dport { 53, 853 } tcp flags syn add @ip6-connlimit-dns { ip6 saddr ct count over 16 } reject with tcp reset
iif lo accept
udp dport 53 accept
tcp dport { 53, 80, 443, 853 } accept
tcp dport { 80, 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 reject with tcp reset
tcp dport 22 ip6 saddr and ffff:ffff:ffff:ffff:ffff:: @ip6-connlimit-ssh reject with tcp reset
tcp dport 22 synproxy mss 1460 wscale 7 timestamp sack-perm
tcp dport { 53, 853 } ip saddr @ip-connlimit-dns reject with tcp reset
tcp dport { 53, 853 } ip6 saddr @ip6-connlimit-dns reject with tcp reset
tcp dport { 53, 853 } synproxy mss 1460 wscale 7 timestamp sack-perm
}
chain forward {

View File

@ -23,6 +23,16 @@ table inet filter {
flags dynamic
}
set ip-connlimit-dns {
type ipv4_addr
flags dynamic
}
set ip6-connlimit-dns {
type ipv6_addr
flags dynamic
}
chain prerouting-raw {
type filter hook prerouting priority raw
@ -38,8 +48,8 @@ table inet filter {
tcp dport 22 ip daddr 198.251.90.93 reject with tcp reset
udp dport 53 notrack accept
tcp dport { 53, 80, 443, 853 } notrack accept
tcp dport 22 tcp flags syn notrack accept
tcp dport { 80, 443 } notrack accept
tcp dport { 22, 53, 853 } tcp flags syn notrack accept
meta l4proto { icmp, ipv6-icmp } notrack accept
}
@ -48,7 +58,7 @@ table inet filter {
oif lo notrack accept
udp sport 53 notrack accept
tcp sport { 53, 80, 443, 853 } notrack accept
tcp sport { 80, 443 } notrack accept
meta l4proto { icmp, ipv6-icmp } notrack accept
}
@ -58,16 +68,21 @@ table inet filter {
iif lo tcp dport 22 tcp flags syn ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } reject with tcp reset
iif lo 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 } reject with tcp reset
iif lo tcp dport { 53, 853 } tcp flags syn add @ip-connlimit-dns { ip saddr ct count over 16 } reject with tcp reset
iif lo tcp dport { 53, 853 } tcp flags syn add @ip6-connlimit-dns { ip6 saddr ct count over 16 } reject with tcp reset
iif lo accept
udp dport 53 accept
tcp dport { 53, 80, 443, 853 } accept
tcp dport { 80, 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 reject with tcp reset
tcp dport 22 ip6 saddr and ffff:ffff:ffff:ffff:ffff:: @ip6-connlimit-ssh reject with tcp reset
tcp dport 22 synproxy mss 1460 wscale 7 timestamp sack-perm
tcp dport { 53, 853 } ip saddr @ip-connlimit-dns reject with tcp reset
tcp dport { 53, 853 } ip6 saddr @ip6-connlimit-dns reject with tcp reset
tcp dport { 53, 853 } synproxy mss 1460 wscale 7 timestamp sack-perm
}
chain forward {