mirror of
https://github.com/GrapheneOS/infrastructure.git
synced 2024-09-27 19:15:43 +00:00
b38736ca74
Now that the usage of synproxy is gated behind a SYN packet rate limit, we can expand this to all our TCP services to have always enabled DDoS protection instead of needing to deploy a stricter set of rules when the servers are under attack. This is far better because there isn't always a system administrator available to handle an ongoing attack. We already used per-IP connection limits in nginx across the board but those limits are applied far too late after a TLS connection has been established and headers are sent rather than before. Using IPv6 /64 blocks means this is much more aggressive for IPv6, but many clients will fall back to IPv4 due to the happy eyeballs approach. The nginx limits are still useful due to HTTP/2 multiplexing and we'll need to think over how to address IPv6 there.
125 lines
4.5 KiB
Plaintext
125 lines
4.5 KiB
Plaintext
#!/usr/bin/nft -f
|
|
|
|
flush ruleset
|
|
|
|
table inet filter {
|
|
define ip-allowlist-ssh = {
|
|
127.0.0.1,
|
|
}
|
|
|
|
define ip6-allowlist-ssh = {
|
|
::1,
|
|
}
|
|
|
|
set ip-connlimit-ssh {
|
|
type ipv4_addr
|
|
flags dynamic
|
|
}
|
|
|
|
set ip6-connlimit-ssh {
|
|
type ipv6_addr
|
|
flags dynamic
|
|
}
|
|
|
|
set ip-connlimit-main {
|
|
type ipv4_addr
|
|
flags dynamic
|
|
}
|
|
|
|
set ip6-connlimit-main {
|
|
type ipv6_addr
|
|
flags dynamic
|
|
}
|
|
|
|
chain prerouting-raw {
|
|
type filter hook prerouting priority raw
|
|
|
|
# drop packets without a reverse path (strict reverse path filtering)
|
|
fib saddr . iif oif missing counter drop
|
|
|
|
iif lo notrack accept
|
|
|
|
# drop packets to address not configured on incoming interface (strong host model)
|
|
fib daddr . iif type != { local, broadcast, multicast } counter drop
|
|
|
|
tcp dport { 22, 80, 443 } tcp flags syn limit rate 1024/second accept
|
|
tcp dport { 22, 80, 443 } tcp flags syn counter notrack accept
|
|
meta l4proto { icmp, ipv6-icmp } notrack accept
|
|
}
|
|
|
|
chain input {
|
|
type filter hook input priority filter
|
|
policy drop
|
|
|
|
iif lo goto input-loopback
|
|
meta l4proto { icmp, ipv6-icmp } accept
|
|
ct state vmap { new : goto input-new, established : goto input-established, related : accept }
|
|
|
|
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 { 80, 443 } ip saddr @ip-connlimit-main counter reject with tcp reset
|
|
tcp dport { 80, 443 } ip6 saddr and ffff:ffff:ffff:ffff:: @ip6-connlimit-main counter reject with tcp reset
|
|
tcp dport { 22, 80, 443 } synproxy mss 1460 wscale 7 timestamp sack-perm
|
|
}
|
|
|
|
chain input-new {
|
|
tcp dport != { 22, 80, 443 } 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 { 80, 443 } ip saddr @ip-connlimit-main counter reject with tcp reset
|
|
tcp dport { 80, 443 } ip6 saddr and ffff:ffff:ffff:ffff:: @ip6-connlimit-main counter reject with tcp reset
|
|
accept
|
|
}
|
|
|
|
chain input-established {
|
|
ct mark 0x1 accept
|
|
tcp dport 22 ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } counter reject with tcp reset
|
|
tcp dport 22 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, 443 } add @ip-connlimit-main { ip saddr ct count over 32 } counter reject with tcp reset
|
|
tcp dport { 80, 443 } add @ip6-connlimit-main { ip6 saddr and ffff:ffff:ffff:ffff:: ct count over 32 } counter reject with tcp reset
|
|
ct mark set 0x1 accept
|
|
}
|
|
|
|
chain input-loopback {
|
|
tcp flags != syn accept
|
|
tcp dport 22 ip saddr != $ip-allowlist-ssh add @ip-connlimit-ssh { ip saddr ct count over 1 } counter reject with tcp reset
|
|
tcp dport 22 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, 443 } add @ip-connlimit-main { ip saddr ct count over 32 } counter reject with tcp reset
|
|
tcp dport { 80, 443 } add @ip6-connlimit-main { ip6 saddr and ffff:ffff:ffff:ffff:: ct count over 32 } counter reject with tcp reset
|
|
ct mark set 0x1 accept
|
|
}
|
|
|
|
chain forward {
|
|
type filter hook forward priority filter
|
|
policy drop
|
|
}
|
|
|
|
chain output-raw {
|
|
type filter hook output priority raw
|
|
|
|
oif lo notrack accept
|
|
meta l4proto { icmp, ipv6-icmp } notrack accept
|
|
}
|
|
|
|
chain output {
|
|
type filter hook output priority filter
|
|
|
|
oif lo goto output-loopback
|
|
skuid != { root, systemd-network, unbound, chrony, http, flarum, flarum-admin, geoipupdate } counter goto graceful-reject
|
|
}
|
|
|
|
chain output-loopback {
|
|
skuid unbound meta l4proto { tcp, udp } th sport 53 th dport >= 1024 accept
|
|
skuid { chrony, http, flarum, flarum-admin, geoipupdate } meta l4proto { tcp, udp } th sport >= 1024 th dport 53 accept
|
|
|
|
skuid != root counter goto graceful-reject
|
|
accept
|
|
}
|
|
|
|
chain graceful-reject {
|
|
meta l4proto udp reject
|
|
meta l4proto tcp reject with tcp reset
|
|
reject
|
|
}
|
|
}
|