Last active 1 month ago

thayen's Avatar thayen revised this gist 1 month ago. Go to revision

No changes

thayen's Avatar thayen revised this gist 1 month ago. Go to revision

1 file changed, 187 insertions

nftables.conf(file created)

@@ -0,0 +1,187 @@
1 + #!/usr/sbin/nft -f
2 +
3 + flush ruleset
4 +
5 + define ip6_mask = ffff:ffff:ffff:ffff::
6 + define public_http = 8080
7 + define public_https = 8443
8 + define public_ssh = 3222
9 + define system_ssh = 49152
10 +
11 + table inet nat {
12 + chain prerouting {
13 + type nat hook prerouting priority dstnat; policy accept;
14 +
15 + tcp dport 80 redirect to :$public_http
16 + tcp dport 443 redirect to :$public_https
17 + tcp dport 22 redirect to :$public_ssh
18 + }
19 + }
20 +
21 +
22 + table inet firewall {
23 + set ssh_ratelimit_v4 {
24 + type ipv4_addr
25 + size 65535
26 + flags dynamic,timeout
27 + timeout 60m
28 + }
29 +
30 + set ssh_ratelimit_v6 {
31 + type ipv6_addr
32 + size 65535
33 + flags dynamic,timeout
34 + timeout 60m
35 + }
36 +
37 + set blackhole_v4 {
38 + type ipv4_addr
39 + size 65535
40 + flags dynamic,timeout
41 + timeout 24h
42 + }
43 +
44 + set blackhole_v6 {
45 + type ipv6_addr
46 + size 65535
47 + flags dynamic,timeout
48 + timeout 24h
49 + }
50 +
51 + set public_ssh_ratelimit_v4 {
52 + type ipv4_addr
53 + size 65535
54 + flags dynamic,timeout
55 + timeout 10m
56 + }
57 +
58 + set public_ssh_ratelimit_v6 {
59 + type ipv6_addr
60 + size 65535
61 + flags dynamic,timeout
62 + timeout 10m
63 + }
64 +
65 + set public_ssh_connections_v4 {
66 + type ipv4_addr
67 + size 65535
68 + flags dynamic
69 + }
70 +
71 + set public_ssh_connections_v6 {
72 + type ipv6_addr
73 + size 65535
74 + flags dynamic
75 + }
76 +
77 + chain inbound_rules_v4 {
78 + icmp type echo-request limit rate 15/second accept
79 + }
80 +
81 + chain inbound_rules_v6 {
82 + icmpv6 type { nd-router-advert, nd-neighbor-solicit, nd-neighbor-advert } accept
83 + icmpv6 type echo-request limit rate 15/second accept
84 + }
85 +
86 + chain inbound_system_ssh_v4 {
87 + ct state new tcp dport $system_ssh add @ssh_ratelimit_v4 \
88 + { ip saddr limit rate 1/hour burst 1 packets } counter accept
89 +
90 + counter drop
91 + }
92 +
93 + chain inbound_system_ssh_v6 {
94 + ct state new tcp dport $system_ssh add @ssh_ratelimit_v6 \
95 + { ip6 saddr & ffff:ffff:ffff:ffff:: limit rate 1/hour burst 1 packets } counter accept
96 +
97 + counter drop
98 + }
99 +
100 + chain inbound_public_ssh_v4 {
101 + # Set a concurrent cap for each ip
102 + tcp dport $public_ssh ct state new add @public_ssh_connections_v4 { ip saddr ct count over 4 } counter reject with tcp reset
103 +
104 + # Set a per ip connection ratelimit
105 + tcp dport $public_ssh ct state new update @public_ssh_ratelimit_v4 { ip saddr limit rate over 20/minute burst 5 packets } counter reject with tcp reset
106 +
107 + tcp dport $public_ssh accept
108 + counter drop
109 + }
110 +
111 + chain inbound_public_ssh_v6 {
112 + # Set a concurrent cap for each ip
113 + tcp dport $public_ssh ct state new add @public_ssh_connections_v6 { ip6 saddr & $ip6_mask ct count over 4 } counter reject with tcp reset
114 +
115 + # Set a per ip connection ratelimit
116 + tcp dport $public_ssh ct state new update @public_ssh_ratelimit_v6 { ip6 saddr & $ip6_mask limit rate over 20/minute burst 5 packets } counter reject with tcp reset
117 +
118 + tcp dport $public_ssh accept
119 + counter drop
120 + }
121 +
122 + chain inbound_blackhole_v4 {
123 + # blacklist tcp traffic for 24h
124 + ct state new tcp flags & (fin | syn | rst | ack) == syn update @blackhole_v4 \
125 + { ip saddr timeout 24h } counter drop
126 +
127 + # blacklist udp traffic
128 + ct state new meta l4proto udp update @blackhole_v4 \
129 + { ip saddr timeout 24h } counter drop
130 +
131 + counter drop
132 + }
133 +
134 + chain inbound_blackhole_v6 {
135 + # TCP SYN to any unauthorized port: blacklist the /64 for 24h.
136 + ct state new tcp flags & (fin | syn | rst | ack) == syn update @blackhole_v6 \
137 + { ip6 saddr & $ip6_mask timeout 24h } counter drop
138 +
139 + # UDP to any unauthorized port: blacklist the /64 for 24h.
140 + ct state new meta l4proto udp update @blackhole_v6 \
141 + { ip6 saddr & $ip6_mask timeout 24h } counter drop
142 +
143 + counter drop
144 + }
145 +
146 + chain inbound {
147 + type filter hook input priority filter; policy drop;
148 +
149 + # Allow specific networks to go unblocked
150 + iifname "lo" accept
151 + iifname "tailscale0" accept
152 +
153 + # Allow replies
154 + ct state vmap { invalid : drop, established : accept, related : accept }
155 +
156 + # Basic ping allowances
157 + meta nfproto ipv4 jump inbound_rules_v4
158 + meta nfproto ipv6 jump inbound_rules_v6
159 +
160 + # Allow service ports
161 + tcp dport { $public_http , $public_https } counter accept
162 +
163 + # Ratelimit service ssh port (3222)
164 + # Global ssh connection rate limiter
165 + tcp dport $public_ssh ct state new limit rate over 120/minute burst 30 packets counter reject with tcp reset
166 + meta nfproto ipv4 tcp dport $public_ssh goto inbound_public_ssh_v4
167 + meta nfproto ipv6 tcp dport $public_ssh goto inbound_public_ssh_v6
168 +
169 + # Block likely bots
170 + ip saddr @blackhole_v4 counter drop
171 + ip6 saddr & $ip6_mask @blackhole_v6 counter drop
172 +
173 + # Fail2unban on vps' own ssh port
174 + meta nfproto ipv4 tcp dport $system_ssh goto inbound_system_ssh_v4
175 + meta nfproto ipv6 tcp dport $system_ssh goto inbound_system_ssh_v6
176 +
177 + # Decide to add ip to blackhole list (incase of bot)
178 + meta nfproto ipv4 goto inbound_blackhole_v4
179 + meta nfproto ipv6 goto inbound_blackhole_v6
180 +
181 + # Block other traffic (default to chain)
182 + }
183 +
184 + chain forward {
185 + type filter hook forward priority filter; policy drop;
186 + }
187 + }
Newer Older