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