]> git.openstreetmap.org Git - chef.git/blob - cookbooks/networking/recipes/default.rb
f6015a17eb6d692d460236569b68441edf3ca55f
[chef.git] / cookbooks / networking / recipes / default.rb
1 #
2 # Cookbook Name:: networking
3 # Recipe:: default
4 #
5 # Copyright 2010, OpenStreetMap Foundation.
6 # Copyright 2009, Opscode, Inc.
7 #
8 # Licensed under the Apache License, Version 2.0 (the "License");
9 # you may not use this file except in compliance with the License.
10 # You may obtain a copy of the License at
11 #
12 #     https://www.apache.org/licenses/LICENSE-2.0
13 #
14 # Unless required by applicable law or agreed to in writing, software
15 # distributed under the License is distributed on an "AS IS" BASIS,
16 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 # See the License for the specific language governing permissions and
18 # limitations under the License.
19 #
20 # = Requires
21 # * node[:networking][:nameservers]
22
23 require "ipaddr"
24 require "yaml"
25
26 netplan = {
27   "network" => {
28     "version" => 2,
29     "renderer" => "networkd",
30     "ethernets" => {},
31     "bonds" => {},
32     "vlans" => {}
33   }
34 }
35
36 node[:networking][:interfaces].each do |name, interface|
37   if interface[:interface]
38     if interface[:role] && (role = node[:networking][:roles][interface[:role]])
39       if role[interface[:family]]
40         node.normal[:networking][:interfaces][name][:prefix] = role[interface[:family]][:prefix]
41         node.normal[:networking][:interfaces][name][:gateway] = role[interface[:family]][:gateway]
42       end
43
44       node.normal[:networking][:interfaces][name][:metric] = role[:metric]
45       node.normal[:networking][:interfaces][name][:zone] = role[:zone]
46     end
47
48     prefix = node[:networking][:interfaces][name][:prefix]
49
50     node.normal[:networking][:interfaces][name][:netmask] = (~IPAddr.new(interface[:address]).mask(0)).mask(prefix)
51     node.normal[:networking][:interfaces][name][:network] = IPAddr.new(interface[:address]).mask(prefix)
52
53     interface = node[:networking][:interfaces][name]
54
55     deviceplan = if interface[:interface] =~ /^(.*)\.(\d+)$/
56                    netplan["network"]["vlans"][interface[:interface]] ||= {
57                      "id" => Regexp.last_match(2).to_i,
58                      "link" => Regexp.last_match(1),
59                      "accept-ra" => false,
60                      "addresses" => [],
61                      "routes" => []
62                    }
63                  elsif interface[:interface] =~ /^bond\d+$/
64                    netplan["network"]["bonds"][interface[:interface]] ||= {
65                      "accept-ra" => false,
66                      "addresses" => [],
67                      "routes" => []
68                    }
69                  else
70                    netplan["network"]["ethernets"][interface[:interface]] ||= {
71                      "accept-ra" => false,
72                      "addresses" => [],
73                      "routes" => []
74                    }
75                  end
76
77     deviceplan["addresses"].push("#{interface[:address]}/#{prefix}")
78
79     if interface[:bond]
80       deviceplan["interfaces"] = interface[:bond][:slaves].to_a
81
82       deviceplan["parameters"] = {
83         "mode" => interface[:bond][:mode] || "active-backup",
84         "primary" => interface[:bond][:slaves].first,
85         "mii-monitor-interval" => interface[:bond][:miimon] || 100,
86         "down-delay" => interface[:bond][:downdelay] || 200,
87         "up-delay" => interface[:bond][:updelay] || 200
88       }
89
90       deviceplan["parameters"]["transmit-hash-policy"] = interface[:bond][:xmithashpolicy] if interface[:bond][:xmithashpolicy]
91       deviceplan["parameters"]["lacp-rate"] = interface[:bond][:lacprate] if interface[:bond][:lacprate]
92     end
93
94     if interface[:gateway]
95       if interface[:family] == "inet"
96         default_route = "0.0.0.0/0"
97       elsif interface[:family] == "inet6"
98         default_route = "::/0"
99       end
100
101       deviceplan["routes"].push(
102         "to" => default_route,
103         "via" => interface[:gateway],
104         "metric" => interface[:metric],
105         "on-link" => true
106       )
107
108       # This ordering relies on systemd-networkd adding routes
109       # in reverse order and will need moving before the previous
110       # route once that is fixed:
111       #
112       # https://github.com/systemd/systemd/issues/5430
113       # https://github.com/systemd/systemd/pull/10938
114       if interface[:family] == "inet6" &&
115          !interface[:network].include?(interface[:gateway]) &&
116          !IPAddr.new("fe80::/64").include?(interface[:gateway])
117         deviceplan["routes"].push(
118           "to" => interface[:gateway],
119           "scope" => "link"
120         )
121       end
122     end
123   else
124     node.rm(:networking, :interfaces, name)
125   end
126 end
127
128 netplan["network"]["bonds"].each_value do |bond|
129   bond["interfaces"].each do |interface|
130     netplan["network"]["ethernets"][interface] ||= { "accept-ra" => false }
131   end
132 end
133
134 netplan["network"]["vlans"].each_value do |vlan|
135   unless vlan["link"] =~ /^bond\d+$/
136     netplan["network"]["ethernets"][vlan["link"]] ||= { "accept-ra" => false }
137   end
138 end
139
140 file "/etc/netplan/01-netcfg.yaml" do
141   action :delete
142 end
143
144 file "/etc/netplan/50-cloud-init.yaml" do
145   action :delete
146 end
147
148 file "/etc/netplan/99-chef.yaml" do
149   owner "root"
150   group "root"
151   mode 0o644
152   content YAML.dump(netplan)
153 end
154
155 package "cloud-init" do
156   action :purge
157 end
158
159 execute "hostname" do
160   action :nothing
161   command "/bin/hostname -F /etc/hostname"
162 end
163
164 template "/etc/hostname" do
165   source "hostname.erb"
166   owner "root"
167   group "root"
168   mode 0o644
169   notifies :run, "execute[hostname]"
170 end
171
172 template "/etc/hosts" do
173   source "hosts.erb"
174   owner "root"
175   group "root"
176   mode 0o644
177 end
178
179 service "systemd-resolved" do
180   action [:enable, :start]
181 end
182
183 directory "/etc/systemd/resolved.conf.d" do
184   owner "root"
185   group "root"
186   mode 0o755
187 end
188
189 template "/etc/systemd/resolved.conf.d/99-chef.conf" do
190   source "resolved.conf.erb"
191   owner "root"
192   group "root"
193   mode 0o644
194   notifies :restart, "service[systemd-resolved]"
195 end
196
197 node.interfaces(:role => :internal) do |interface|
198   if interface[:gateway] && interface[:gateway] != interface[:address]
199     search(:node, "networking_interfaces*address:#{interface[:gateway]}") do |gateway|
200       next unless gateway[:openvpn]
201
202       gateway[:openvpn][:tunnels].each_value do |tunnel|
203         if tunnel[:peer][:address] # ~FC023
204           route tunnel[:peer][:address] do
205             netmask "255.255.255.255"
206             gateway interface[:gateway]
207             device interface[:interface]
208           end
209         end
210
211         next unless tunnel[:peer][:networks]
212
213         tunnel[:peer][:networks].each do |network|
214           route network[:address] do
215             netmask network[:netmask]
216             gateway interface[:gateway]
217             device interface[:interface]
218           end
219         end
220       end
221     end
222   end
223 end
224
225 zones = {}
226
227 search(:node, "networking:interfaces").collect do |n|
228   next if n[:fqdn] == node[:fqdn]
229
230   n.interfaces.each do |interface|
231     next unless interface[:role] == "external" && interface[:zone]
232
233     zones[interface[:zone]] ||= {}
234     zones[interface[:zone]][interface[:family]] ||= []
235     zones[interface[:zone]][interface[:family]] << interface[:address]
236   end
237 end
238
239 package "shorewall"
240
241 template "/etc/default/shorewall" do
242   source "shorewall-default.erb"
243   owner "root"
244   group "root"
245   mode 0o644
246   notifies :restart, "service[shorewall]"
247 end
248
249 template "/etc/shorewall/shorewall.conf" do
250   source "shorewall.conf.erb"
251   owner "root"
252   group "root"
253   mode 0o644
254   notifies :restart, "service[shorewall]"
255 end
256
257 template "/etc/shorewall/zones" do
258   source "shorewall-zones.erb"
259   owner "root"
260   group "root"
261   mode 0o644
262   variables :type => "ipv4"
263   notifies :restart, "service[shorewall]"
264 end
265
266 template "/etc/shorewall/interfaces" do
267   source "shorewall-interfaces.erb"
268   owner "root"
269   group "root"
270   mode 0o644
271   notifies :restart, "service[shorewall]"
272 end
273
274 template "/etc/shorewall/hosts" do
275   source "shorewall-hosts.erb"
276   owner "root"
277   group "root"
278   mode 0o644
279   variables :zones => zones
280   notifies :restart, "service[shorewall]"
281 end
282
283 template "/etc/shorewall/conntrack" do
284   source "shorewall-conntrack.erb"
285   owner "root"
286   group "root"
287   mode 0o644
288   notifies :restart, "service[shorewall]"
289   only_if { node[:networking][:firewall][:raw] }
290 end
291
292 template "/etc/shorewall/policy" do
293   source "shorewall-policy.erb"
294   owner "root"
295   group "root"
296   mode 0o644
297   notifies :restart, "service[shorewall]"
298 end
299
300 template "/etc/shorewall/rules" do
301   source "shorewall-rules.erb"
302   owner "root"
303   group "root"
304   mode 0o644
305   variables :family => "inet"
306   notifies :restart, "service[shorewall]"
307 end
308
309 service "shorewall" do
310   action [:enable, :start]
311   supports :restart => true
312   status_command "shorewall status"
313 end
314
315 template "/etc/logrotate.d/shorewall" do
316   source "logrotate.shorewall.erb"
317   owner "root"
318   group "root"
319   mode 0o644
320   variables :name => "shorewall"
321 end
322
323 firewall_rule "limit-icmp-echo" do
324   action :accept
325   family :inet
326   source "net"
327   dest "fw"
328   proto "icmp"
329   dest_ports "echo-request"
330   rate_limit "s:1/sec:5"
331 end
332
333 %w[ucl ams bm].each do |zone|
334   firewall_rule "accept-openvpn-#{zone}" do
335     action :accept
336     source zone
337     dest "fw"
338     proto "udp"
339     dest_ports "1194:1197"
340     source_ports "1194:1197"
341   end
342 end
343
344 if node[:roles].include?("gateway")
345   template "/etc/shorewall/masq" do
346     source "shorewall-masq.erb"
347     owner "root"
348     group "root"
349     mode 0o644
350     notifies :restart, "service[shorewall]"
351   end
352 else
353   file "/etc/shorewall/masq" do
354     action :delete
355     notifies :restart, "service[shorewall]"
356   end
357 end
358
359 unless node.interfaces(:family => :inet6).empty?
360   package "shorewall6"
361
362   template "/etc/default/shorewall6" do
363     source "shorewall-default.erb"
364     owner "root"
365     group "root"
366     mode 0o644
367     notifies :restart, "service[shorewall6]"
368   end
369
370   template "/etc/shorewall6/shorewall6.conf" do
371     source "shorewall6.conf.erb"
372     owner "root"
373     group "root"
374     mode 0o644
375     notifies :restart, "service[shorewall6]"
376   end
377
378   template "/etc/shorewall6/zones" do
379     source "shorewall-zones.erb"
380     owner "root"
381     group "root"
382     mode 0o644
383     variables :type => "ipv6"
384     notifies :restart, "service[shorewall6]"
385   end
386
387   template "/etc/shorewall6/interfaces" do
388     source "shorewall6-interfaces.erb"
389     owner "root"
390     group "root"
391     mode 0o644
392     notifies :restart, "service[shorewall6]"
393   end
394
395   template "/etc/shorewall6/hosts" do
396     source "shorewall6-hosts.erb"
397     owner "root"
398     group "root"
399     mode 0o644
400     variables :zones => zones
401     notifies :restart, "service[shorewall6]"
402   end
403
404   template "/etc/shorewall6/conntrack" do
405     source "shorewall-conntrack.erb"
406     owner "root"
407     group "root"
408     mode 0o644
409     notifies :restart, "service[shorewall6]"
410     only_if { node[:networking][:firewall][:raw] }
411   end
412
413   template "/etc/shorewall6/policy" do
414     source "shorewall-policy.erb"
415     owner "root"
416     group "root"
417     mode 0o644
418     notifies :restart, "service[shorewall6]"
419   end
420
421   template "/etc/shorewall6/rules" do
422     source "shorewall-rules.erb"
423     owner "root"
424     group "root"
425     mode 0o644
426     variables :family => "inet6"
427     notifies :restart, "service[shorewall6]"
428   end
429
430   service "shorewall6" do
431     action [:enable, :start]
432     supports :restart => true
433     status_command "shorewall6 status"
434   end
435
436   template "/etc/logrotate.d/shorewall6" do
437     source "logrotate.shorewall.erb"
438     owner "root"
439     group "root"
440     mode 0o644
441     variables :name => "shorewall6"
442   end
443
444   firewall_rule "limit-icmp6-echo" do
445     action :accept
446     family :inet6
447     source "net"
448     dest "fw"
449     proto "ipv6-icmp"
450     dest_ports "echo-request"
451     rate_limit "s:1/sec:5"
452   end
453 end
454
455 firewall_rule "accept-http" do
456   action :accept
457   source "net"
458   dest "fw"
459   proto "tcp:syn"
460   dest_ports "http"
461   rate_limit node[:networking][:firewall][:http_rate_limit]
462   connection_limit node[:networking][:firewall][:http_connection_limit]
463 end
464
465 firewall_rule "accept-https" do
466   action :accept
467   source "net"
468   dest "fw"
469   proto "tcp:syn"
470   dest_ports "https"
471   rate_limit node[:networking][:firewall][:http_rate_limit]
472   connection_limit node[:networking][:firewall][:http_connection_limit]
473 end