]> git.openstreetmap.org Git - chef.git/blob - cookbooks/networking/templates/default/nftables.conf.erb
Expire rate limit sets
[chef.git] / cookbooks / networking / templates / default / nftables.conf.erb
1 #!/usr/sbin/nft -f
2
3 <%- unless @interfaces.empty? %>
4 define external-interfaces = { <%= @interfaces.sort.uniq.join(", ") %> }
5 <%- end %>
6
7 define ip-private-addresses = { 0.0.0.0, 10.0.0.0/8, 127.0.0.0/8, 169.254.0.0/16, 172.16.0.0/12, 192.0.2.0/24, 192.168.0.0/16, 224.0.0.0/4 }
8 define ip6-private-addresses = { 2001:db8::/32, fc00::/7, ff00::/8 }
9
10 table inet filter {
11   set ip-osm-addresses {
12     type ipv4_addr
13 <%- unless Array(@hosts["inet"]).empty? %>
14     elements = { <%= Array(@hosts["inet"]).sort.join(", ") %> }
15 <%- end %>
16   }
17
18   set ip6-osm-addresses {
19     type ipv6_addr
20 <%- unless Array(@hosts["inet"]).empty? %>
21     elements = { <%= Array(@hosts["inet6"]).sort.join(", ") %> }
22 <%- end %>
23   }
24
25   set ip-blacklist {
26     type ipv4_addr
27     flags dynamic
28   }
29
30   set ip6-blacklist {
31     type ipv6_addr
32     flags dynamic
33   }
34
35   set ratelimit-icmp-echo-ip {
36     type ipv4_addr
37     flags dynamic
38     timeout 120s
39   }
40
41   set ratelimit-icmp-echo-ip6 {
42     type ipv6_addr
43     flags dynamic
44     timeout 120s
45   }
46
47 <%- node[:networking][:firewall][:sets].each do |set| %>
48   set <%= set %> {
49 <%- if set.end_with?("-ip") %>
50     type ipv4_addr
51 <%- elsif set.end_with?("-ip6") %>
52     type ipv6_addr
53 <%- end %>
54     flags dynamic
55     timeout 120s
56   }
57
58 <%- end %>
59   chain log-and-drop {
60     limit rate 1/second log
61     drop
62   }
63
64   chain log-and-reject {
65     limit rate 1/second log
66     reject
67   }
68
69   chain incoming {
70 <%- if node[:networking][:firewall][:whitelist].empty? %>
71     ip saddr { $ip-private-addresses } jump log-and-drop
72 <%- else %>
73     ip saddr { $ip-private-addresses } ip saddr != { <%= node[:networking][:firewall][:whitelist].sort.join(", ") %> } jump log-and-drop
74 <%- end %>
75     ip6 saddr { $ip6-private-addresses } jump log-and-drop
76
77     ip saddr @ip-blacklist jump log-and-drop
78     ip6 saddr @ip6-blacklist jump log-and-drop
79
80     ct state { established, related } accept
81
82     icmp type { destination-unreachable } accept
83     icmp type { echo-request } update @ratelimit-icmp-echo-ip { ip saddr limit rate 1/second } accept
84     icmp type { echo-request } drop
85
86     icmpv6 type { nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert } accept
87     icmpv6 type { echo-request } update @ratelimit-icmp-echo-ip6 { ip6 saddr limit rate 1/second } accept
88     icmpv6 type { echo-request } drop
89
90     meta l4proto { icmp, icmpv6 } jump log-and-drop
91
92     tcp flags & (fin|syn|rst|psh|ack|urg) == fin|psh|urg jump log-and-drop
93     tcp flags & (fin|syn|rst|psh|ack|urg) == 0x0 jump log-and-drop
94     tcp flags & (syn|rst) == syn|rst jump log-and-drop
95     tcp flags & (fin|rst) == fin|rst jump log-and-drop
96     tcp flags & (fin|syn) == fin|syn jump log-and-drop
97     tcp flags & (fin|psh|ack) == fin|psh jump log-and-drop
98     tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn jump log-and-drop
99
100 <%- node[:networking][:firewall][:incoming].uniq.each do |rule| %>
101     <%= rule %>
102 <%- end %>
103
104     jump log-and-drop
105   }
106
107   chain outgoing {
108 <%- if node[:networking][:firewall][:whitelist].empty? %>
109     ip daddr { $ip-private-addresses } jump log-and-drop
110 <%- else %>
111     ip daddr { $ip-private-addresses } ip daddr != { <%= node[:networking][:firewall][:whitelist].sort.join(", ") %> } jump log-and-drop
112 <%- end %>
113     ip6 daddr { $ip6-private-addresses } jump log-and-drop
114
115 <%- node[:networking][:firewall][:outgoing].each do |rule| %>
116     <%= rule %>
117 <%- end %>
118
119     accept
120   }
121
122   chain input {
123     type filter hook input priority filter;
124
125 <%- unless @interfaces.empty? %>
126     iifname { $external-interfaces } jump incoming
127 <%- end %>
128
129     accept
130   }
131
132   chain forward {
133     type filter hook forward priority filter;
134
135 <%- unless @interfaces.empty? %>
136     iifname { $external-interfaces } jump incoming
137     oifname { $external-interfaces } jump outgoing
138 <%- end %>
139
140     accept
141   }
142
143   chain output {
144     type filter hook output priority filter;
145
146 <%- unless @interfaces.empty? %>
147     oifname { $external-interfaces } jump outgoing
148 <%- end %>
149
150     accept
151   }
152 }
153 <%- if node[:roles].include?("gateway") %>
154
155 table ip nat {
156   chain postrouting {
157     type nat hook postrouting priority srcnat;
158
159 <%- node.interfaces(:role => :external, :family => :inet).each do |external| %>
160 <%- node.interfaces(:role => :internal, :family => :inet).each do |internal| %>
161     oifname { <%= external[:interface] %> } ip saddr { <%= internal[:network] %>/<%= internal[:prefix] %> } snat <%= external[:address] %>
162 <%- end %>
163 <%- end %>
164   }
165 }
166 <%- end %>