From cfc3e73665e3218dd19186354447b27e45962350 Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Tue, 20 Aug 2013 18:40:43 +0200 Subject: [PATCH 01/10] Start adding explicit reverse zones. These should make it possible to define extra things for reverse zones. For example the autodomain will work differently for reverse-zones. --- recipes/default.rb | 2 +- recipes/reverse_zones.rb | 72 ++++++++++++++++++++++++++ templates/default/reverse_zonefile.erb | 21 ++++++++ 3 files changed, 94 insertions(+), 1 deletion(-) create mode 100644 recipes/reverse_zones.rb create mode 100644 templates/default/reverse_zonefile.erb diff --git a/recipes/default.rb b/recipes/default.rb index c617d41..10c5f57 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -94,7 +94,7 @@ class Chef::Recipe::NameServer group node[:bind9][:user] mode 0644 variables({ - :zonefiles => search(:zones) + :zonefiles => search(:zones) + search(:reversezones) }) notifies :restart, "service[bind9]" end diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb new file mode 100644 index 0000000..e686104 --- /dev/null +++ b/recipes/reverse_zones.rb @@ -0,0 +1,72 @@ +# Cookbook Name:: bind9-reversezones +# Recipe:: reversezones +# +# Copyright 2013, Arnold Krille +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +directory node[:bind9][:zones_path] do + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0744 + recursive true + not_if { ::File.directory?(node[:bind9][:zones_path]) or ::File.symlink?(node[:bind9][:zones_path]) } +end + +search(:reversezones).each do |zone| + unless zone['autodomain'].nil? || zone['autodomain'] == '' + search(:node, "domain:#{zone['autodomain']}").each do |host| + next if host['ipaddress'] == '' || host['ipaddress'].nil? + zone['zone_info']['records'].push( { + "name" => host['hostname'], + "type" => "PTR", + "ip" => host['ipaddress'] + }) + end + end + if not zone['domain'].end_with?('.IN-ADDR.ARPA') + zone['domain'] += '.IN-ADDR.ARPA' + end + + template File.join(node[:bind9][:zones_path], zone['domain']) do + source File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") + local true + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + notifies :restart, "service[bind9]" + variables({ + :serial => zone['zone_info']['serial'] || Time.new.strftime("%Y%m%d%H%M%S") + }) + action :nothing + end + + template File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") do + source "reverse_zonefile.erb" + owner node[:bind9][:user] + group node[:bind9][:user] + mode 0644 + variables({ + :domain => zone['domain'], + :soa => zone['zone_info']['soa'], + :contact => zone['zone_info']['contact'], + :global_ttl => zone['zone_info']['global_ttl'], + :nameserver => zone['zone_info']['nameserver'], + :mail_exchange => zone['zone_info']['mail_exchange'], + :records => zone['zone_info']['records'] + }) + notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately + end +end diff --git a/templates/default/reverse_zonefile.erb b/templates/default/reverse_zonefile.erb new file mode 100644 index 0000000..ce44bc5 --- /dev/null +++ b/templates/default/reverse_zonefile.erb @@ -0,0 +1,21 @@ +$TTL <%= @global_ttl %> +@ IN SOA <%= @soa %> <%= @contact %> ( + <%%= @serial %> ; serial [yyyyMMddNN] + 4H ; refresh + 30M ; retry + 1W ; expiry + 1D ; minimum +) + + IN NS <%= @soa %> +<% @nameserver.each do |ns| -%> + IN NS <%= ns %> +<% end %> + +<% @mail_exchange.each do |mx| -%> + IN MX <%= mx['priority'] %> <%= mx['host'] %> +<% end %> + +<% @records.each do |record| -%> +<%= "%-20s %5s IN %5s %s" % [record['ip'],record['ttl'],record['type'],record['name']] %> +<% end %> From 9ece2a9a3ec798c4d0f11b54d53726c9d783f0c3 Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Wed, 21 Aug 2013 14:03:06 +0200 Subject: [PATCH 02/10] Have automatic reverse domains Grab the ipaddresses from the given autodomain and add them to the ips. The autodomain can be a different match then the whole domain (for example autodomain=10.110.30 while domain is 10.110). --- recipes/reverse_zones.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb index e686104..907db84 100644 --- a/recipes/reverse_zones.rb +++ b/recipes/reverse_zones.rb @@ -27,12 +27,13 @@ search(:reversezones).each do |zone| unless zone['autodomain'].nil? || zone['autodomain'] == '' - search(:node, "domain:#{zone['autodomain']}").each do |host| + zoneip = zone['domain'].scan(/[0-9]+/).join('.') + search(:node, "ipaddress:#{zone['autodomain']}*").each do |host| next if host['ipaddress'] == '' || host['ipaddress'].nil? zone['zone_info']['records'].push( { "name" => host['hostname'], "type" => "PTR", - "ip" => host['ipaddress'] + "ip" => host['ipaddress'].scan(/[0-9]{1,3}/).reverse().join('.').sub!(/\.#{zoneip}$/, '') }) end end From b15a57d46cb7ed331fa330940658b26b2006bf43 Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Wed, 21 Aug 2013 14:20:08 +0200 Subject: [PATCH 03/10] Add the reverse_zone recipe by default. --- recipes/default.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/default.rb b/recipes/default.rb index 10c5f57..d0dbb3a 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -71,6 +71,7 @@ class Chef::Recipe::NameServer # end end +include_recipe('bind9::reverse_zones') template File.join(node[:bind9][:config_path], node[:bind9][:options_file]) do source "named.conf.options.erb" From 063605e5144e79068ff2b48eb710eb33ff54b411 Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Wed, 21 Aug 2013 14:26:40 +0200 Subject: [PATCH 04/10] Actually include the correct recipe. --- recipes/default.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/default.rb b/recipes/default.rb index d0dbb3a..45d2cd6 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -71,7 +71,7 @@ class Chef::Recipe::NameServer # end end -include_recipe('bind9::reverse_zones') +include_recipe('bind9-reversezones::reverse_zones') template File.join(node[:bind9][:config_path], node[:bind9][:options_file]) do source "named.conf.options.erb" From a32c2dd338b2c71e0528451e460cb86f2b5df36e Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Fri, 6 Sep 2013 14:24:22 +0200 Subject: [PATCH 05/10] Fix the machine names in the reversezone. --- recipes/reverse_zones.rb | 2 +- templates/default/reverse_zonefile.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb index 907db84..4fb8d35 100644 --- a/recipes/reverse_zones.rb +++ b/recipes/reverse_zones.rb @@ -31,7 +31,7 @@ search(:node, "ipaddress:#{zone['autodomain']}*").each do |host| next if host['ipaddress'] == '' || host['ipaddress'].nil? zone['zone_info']['records'].push( { - "name" => host['hostname'], + "name" => host['fqdn'] or "#{host['name']}.#{host['domain']}", "type" => "PTR", "ip" => host['ipaddress'].scan(/[0-9]{1,3}/).reverse().join('.').sub!(/\.#{zoneip}$/, '') }) diff --git a/templates/default/reverse_zonefile.erb b/templates/default/reverse_zonefile.erb index ce44bc5..3e8cb99 100644 --- a/templates/default/reverse_zonefile.erb +++ b/templates/default/reverse_zonefile.erb @@ -17,5 +17,5 @@ $TTL <%= @global_ttl %> <% end %> <% @records.each do |record| -%> -<%= "%-20s %5s IN %5s %s" % [record['ip'],record['ttl'],record['type'],record['name']] %> +<%= "%-20s %5s IN %5s %s." % [record['ip'],record['ttl'],record['type'],record['name']] %> <% end %> From 58a8227fce7cc41cf70feb645d0b372b5f7cbacd Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Fri, 6 Sep 2013 14:28:47 +0200 Subject: [PATCH 06/10] fix the fix --- recipes/reverse_zones.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb index 4fb8d35..33bb7ca 100644 --- a/recipes/reverse_zones.rb +++ b/recipes/reverse_zones.rb @@ -31,7 +31,7 @@ search(:node, "ipaddress:#{zone['autodomain']}*").each do |host| next if host['ipaddress'] == '' || host['ipaddress'].nil? zone['zone_info']['records'].push( { - "name" => host['fqdn'] or "#{host['name']}.#{host['domain']}", + "name" => host['fqdn'] || "#{host['name']}.#{host['domain']}", "type" => "PTR", "ip" => host['ipaddress'].scan(/[0-9]{1,3}/).reverse().join('.').sub!(/\.#{zoneip}$/, '') }) From f640972e5950872f261ed7105da1d8b38921da42 Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Thu, 5 Dec 2013 09:54:32 +0100 Subject: [PATCH 07/10] fix the sorting for the results --- recipes/default.rb | 2 +- recipes/reverse_zones.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/recipes/default.rb b/recipes/default.rb index 45d2cd6..16aa03b 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -156,7 +156,7 @@ class Chef::Recipe::NameServer :global_ttl => zone['zone_info']['global_ttl'], :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], - :records => zone['zone_info']['records'] + :records => zone['zone_info']['records'].sort{ |a, b| a['name'] <=> b['name'] } }) notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately end diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb index 33bb7ca..76d9ad4 100644 --- a/recipes/reverse_zones.rb +++ b/recipes/reverse_zones.rb @@ -66,7 +66,7 @@ :global_ttl => zone['zone_info']['global_ttl'], :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], - :records => zone['zone_info']['records'] + :records => zone['zone_info']['records'].sort{ |a, b| a['ip'] <=> b['ip'] } }) notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately end From 3fe1745b3fa861aa43301f83b68dfa1c4ab4326f Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Tue, 28 Jan 2014 09:40:01 +0100 Subject: [PATCH 08/10] Add a second stage for the sorting. This should stabilize the zone-files when one name has several ips or one ip has several names. --- recipes/default.rb | 6 ++++-- recipes/reverse_zones.rb | 4 +++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/recipes/default.rb b/recipes/default.rb index 16aa03b..c43f422 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -156,9 +156,11 @@ class Chef::Recipe::NameServer :global_ttl => zone['zone_info']['global_ttl'], :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], - :records => zone['zone_info']['records'].sort{ |a, b| a['name'] <=> b['name'] } + :records => zone['zone_info']['records'].sort do |a, b| + a[:name] == b[:name] ? a[:ip] <=> b[:ip] : a[:name] <=> b[:name] + end }) - notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately + notifies :create, resources(template: File.join(node[:bind9][:zones_path], zone[:domain])), :immediately end end diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb index 76d9ad4..0e273ae 100644 --- a/recipes/reverse_zones.rb +++ b/recipes/reverse_zones.rb @@ -66,7 +66,9 @@ :global_ttl => zone['zone_info']['global_ttl'], :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], - :records => zone['zone_info']['records'].sort{ |a, b| a['ip'] <=> b['ip'] } + :records => zone['zone_info']['records'].sort do |a, b| + a[:ip] == b[:ip] ? a[:name] <=> b[:name] : a[:ip] <=> b[:ip] + end }) notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately end From d1bd366f9902a39702637a73014da57224be366a Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Tue, 28 Jan 2014 10:21:46 +0100 Subject: [PATCH 09/10] Commit after testing... Previous commit is bad. This should fix it... --- recipes/default.rb | 3 ++- recipes/reverse_zones.rb | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/recipes/default.rb b/recipes/default.rb index c43f422..fba7fb5 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -157,7 +157,8 @@ class Chef::Recipe::NameServer :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], :records => zone['zone_info']['records'].sort do |a, b| - a[:name] == b[:name] ? a[:ip] <=> b[:ip] : a[:name] <=> b[:name] + return a['ip'] <=> b['ip'] if a['name'] == b['name'] + return a['name'] <=> b['name'] end }) notifies :create, resources(template: File.join(node[:bind9][:zones_path], zone[:domain])), :immediately diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb index 0e273ae..fbedd28 100644 --- a/recipes/reverse_zones.rb +++ b/recipes/reverse_zones.rb @@ -67,7 +67,8 @@ :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], :records => zone['zone_info']['records'].sort do |a, b| - a[:ip] == b[:ip] ? a[:name] <=> b[:name] : a[:ip] <=> b[:ip] + return a['name'] <=> b['name'] if a['ip'] == b['ip'] + return a['ip'] <=> b['ip'] end }) notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately From 2240b3a5668d438ecc0026398e1b5971a47ba514 Mon Sep 17 00:00:00 2001 From: Arnold Krille Date: Mon, 3 Feb 2014 10:26:51 +0100 Subject: [PATCH 10/10] Actually fix it. --- recipes/default.rb | 25 +++++++++++++------------ recipes/reverse_zones.rb | 5 +++-- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/recipes/default.rb b/recipes/default.rb index fba7fb5..5e1ddc8 100644 --- a/recipes/default.rb +++ b/recipes/default.rb @@ -120,16 +120,17 @@ class Chef::Recipe::NameServer end search(:zones).each do |zone| - #unless zone['autodomain'].nil? || zone['autodomain'] == '' - # search(:node, "domain:#{zone['autodomain']}").each do |host| - # next if host['ipaddress'] == '' || host['ipaddress'].nil? - # zone['zone_info']['records'].push( { - # "name" => host['hostname'], - # "type" => "A", - # "ip" => host['ipaddress'] - # }) - # end - #end + Chef::Log.info("Got zone #{zone[:domain]}") + unless zone['autodomain'].nil? || zone['autodomain'] == '' + search(:node, "domain:#{zone['autodomain']}").each do |host| + next if host['ipaddress'] == '' || host['ipaddress'].nil? + zone['zone_info']['records'].push( { + "name" => host['hostname'], + "type" => "A", + "ip" => host['ipaddress'] + }) + end + end template File.join(node[:bind9][:zones_path], zone['domain']) do source File.join(node[:bind9][:zones_path], "#{zone['domain']}.erb") @@ -157,8 +158,8 @@ class Chef::Recipe::NameServer :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], :records => zone['zone_info']['records'].sort do |a, b| - return a['ip'] <=> b['ip'] if a['name'] == b['name'] - return a['name'] <=> b['name'] + a['ip'] <=> b['ip'] if a['name'] == b['name'] + a['name'] <=> b['name'] end }) notifies :create, resources(template: File.join(node[:bind9][:zones_path], zone[:domain])), :immediately diff --git a/recipes/reverse_zones.rb b/recipes/reverse_zones.rb index fbedd28..17df031 100644 --- a/recipes/reverse_zones.rb +++ b/recipes/reverse_zones.rb @@ -26,6 +26,7 @@ end search(:reversezones).each do |zone| + Chef::Log.info("Got reverse-zone #{zone[:domain]}") unless zone['autodomain'].nil? || zone['autodomain'] == '' zoneip = zone['domain'].scan(/[0-9]+/).join('.') search(:node, "ipaddress:#{zone['autodomain']}*").each do |host| @@ -67,8 +68,8 @@ :nameserver => zone['zone_info']['nameserver'], :mail_exchange => zone['zone_info']['mail_exchange'], :records => zone['zone_info']['records'].sort do |a, b| - return a['name'] <=> b['name'] if a['ip'] == b['ip'] - return a['ip'] <=> b['ip'] + a['name'] <=> b['name'] if a['ip'] == b['ip'] + a['ip'] <=> b['ip'] end }) notifies :create, resources(:template => File.join(node[:bind9][:zones_path], zone['domain'])), :immediately