From c996c9b7e34606168f79d365e0dcad24b4e67e4f Mon Sep 17 00:00:00 2001 From: Ben Vincent Date: Mon, 13 Nov 2023 22:17:59 +1100 Subject: [PATCH] fix: enable dynamic/tsig updates - add eyaml to hiera.yaml - consolidate all paths into single tree - change to new profiles::dns::client wrapper - change to new profiles::dns::record wrapper - change to use concat method to build zone file --- hiera.yaml | 18 ++++++----- hieradata/common.yaml | 2 ++ hieradata/roles/infra/dns/master.eyaml | 3 ++ hieradata/roles/infra/dns/master.yaml | 26 +++++++++++----- site/profiles/manifests/dns/client.pp | 33 ++++++++++----------- site/profiles/manifests/dns/master.pp | 28 ++++++++++++++--- site/profiles/manifests/dns/record.pp | 23 ++++++++++++++ site/profiles/manifests/dns/resolver.pp | 2 ++ site/profiles/manifests/dns/server.pp | 8 +++++ site/profiles/manifests/dns/zone.pp | 27 +++++++++++++++++ site/profiles/templates/dns/zone_header.erb | 16 ++++++++++ 11 files changed, 149 insertions(+), 37 deletions(-) create mode 100644 hieradata/roles/infra/dns/master.eyaml create mode 100644 site/profiles/manifests/dns/record.pp create mode 100644 site/profiles/manifests/dns/zone.pp create mode 100644 site/profiles/templates/dns/zone_header.erb diff --git a/hiera.yaml b/hiera.yaml index 6d1c6c9..3097474 100644 --- a/hiera.yaml +++ b/hiera.yaml @@ -4,18 +4,22 @@ defaults: datadir: "hieradata" data_hash: "yaml_data" hierarchy: - - name: Node-specific data + - name: Consolidated Data paths: - "nodes/%{trusted.certname}.yaml" - - name: Role-specific data - paths: + - "roles/%{::enc_role_tier1}.eyaml" - "roles/%{::enc_role_tier1}.yaml" + - "roles/${::enc_role_tier1}/%{::enc_role_tier2}.eyaml" - "roles/${::enc_role_tier1}/%{::enc_role_tier2}.yaml" + - "roles/${::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.eyaml" - "roles/${::enc_role_tier1}/%{::enc_role_tier2}/%{::enc_role_tier3}.yaml" + - "%{::enc_role_path}.eyaml" - "%{::enc_role_path}.yaml" - - name: "OS Related" - paths: - "os/%{facts.os.name}/%{facts.os.name}%{facts.os.release.major}.yaml" - "os/%{facts.os.name}/all_releases.yaml" - - name: Common data shared across nodes - path: "common.yaml" + - "common.eyaml" + - "common.yaml" + lookup_key: eyaml_lookup_key + options: + pkcs7_private_key: /var/lib/puppet/keys/private_key.pkcs7.pem + pkcs7_public_key: /var/lib/puppet/keys/public_key.pkcs7.pem diff --git a/hieradata/common.yaml b/hieradata/common.yaml index 76fd051..dce34c8 100644 --- a/hieradata/common.yaml +++ b/hieradata/common.yaml @@ -6,6 +6,8 @@ profiles::ntp::client::peers: profiles::base::puppet_servers: - 'prodinf01n01.main.unkin.net' +profiles::dns::master::basedir: '/var/named/sources' + profiles::packages::base: - bash-completion - ccze diff --git a/hieradata/roles/infra/dns/master.eyaml b/hieradata/roles/infra/dns/master.eyaml new file mode 100644 index 0000000..2bdd703 --- /dev/null +++ b/hieradata/roles/infra/dns/master.eyaml @@ -0,0 +1,3 @@ +--- + +profiles::dns::master::secret: ENC[PKCS7,MIIBygYJKoZIhvcNAQcDoIIBuzCCAbcCAQAxggEhMIIBHQIBADAFMAACAQEwDQYJKoZIhvcNAQEBBQAEggEAJSp35spGbW0doI4arooNlpVW8JFlftPttnCE/P9bsmlCiA2DIfqu+ug3ZpHc7ELjA+PLJ7/IwZmpm+pfKpeSfZhw3zxFSpGUAi1q94VUnqLx6AbTgWJKT2ral6ZM/PGQSYaZB22rSvMWN7S7ow57yka3umW1KzUVDvqonJkFV2rrcfMrQU+xUm1BqHYd/zHcX6U5q4zAX3GG66jHYJzhMtzjUCeGaDZoMdw7T0nLGA5JFfVbXml3P/EH3lNMWtKT4LVEuJEier+GQA3y4mAwnKTiOml0DWH5Imbrx5beqEnsnN1AETTM21oq8Iv8kJEQMnxo0xxWj74MLG3/c1oB1zCBjAYJKoZIhvcNAQcBMB0GCWCGSAFlAwQBKgQQMoKOR5PV7MNG9dCAu2sDF4BgCaGIhzEdQIcKBcst+u7vq2pw5vGBeTdz0J+waFyL9IrBmNu9akfIanKauYEU1cPa9KwT5tW2AG4yGpOebW/W+zjlUvupvctWG81zMTrq6So/zSl5dcHU0gX9R8zBb0vF] diff --git a/hieradata/roles/infra/dns/master.yaml b/hieradata/roles/infra/dns/master.yaml index c2a99c1..4f0dcbc 100644 --- a/hieradata/roles/infra/dns/master.yaml +++ b/hieradata/roles/infra/dns/master.yaml @@ -1,28 +1,38 @@ --- +profiles::dns::master::nameservers: + - prodinf01n23.main.unkin.net + - prodinf01n24.main.unkin.net + profiles::dns::master::acls: acl-main.unkin.net: addresses: - 198.18.17.0/24 profiles::dns::master::zones: - main.unkin.net-master: + main.unkin.net: domain: 'main.unkin.net' zone_type: 'master' dynamic: false - 17.18.198.in-addr.arpa-master: + ns_notify: true + source: '/var/named/sources/main.unkin.net.conf' + 17.18.198.in-addr.arpa: domain: '17.18.198.in-addr.arpa' zone_type: 'master' dynamic: false + ns_notify: true + source: '/var/named/sources/17.18.198.in-addr.arpa.conf' profiles::dns::master::views: - authoritive: + master-zones: recursion: false zones: - - main.unkin.net-master - - 17.18.198.in-addr.arpa-master + - main.unkin.net + - 17.18.198.in-addr.arpa match_clients: - acl-main.unkin.net -profiles::dns::master::tags: - ptr: 'master-ptr-records' - a: 'master-a-records' +profiles::dns::master::keys: + rndskey: + secret_bits: 512 + algorithm: hmac-sha256 + secret: "%{lookup('profiles::dns::master::secret')}" diff --git a/site/profiles/manifests/dns/client.pp b/site/profiles/manifests/dns/client.pp index 60abe10..1441299 100644 --- a/site/profiles/manifests/dns/client.pp +++ b/site/profiles/manifests/dns/client.pp @@ -1,34 +1,31 @@ # profiles::dns::client define profiles::dns::client ( - Integer $ttl = 600, - String $intf = $facts['networking']['primary'], - String $addr = $facts['networking']['ip'], - String $fqdn = $facts['networking']['fqdn'], Boolean $forward = true, Boolean $reverse = true, + Integer $order = 10, ){ + $intf = $facts['networking']['primary'] + $fqdn = $facts['networking']['fqdn'] + $last_octet = regsubst($::facts['networking']['ip'], '^.*\.', '') + if $forward { - @@resource_record { "${fqdn}_${intf}-a": - ensure => present, - record => $::facts['networking']['fqdn'], + profiles::dns::record { "${fqdn}_${intf}_A": + value => $::facts['networking']['ip'], type => 'A', - data => [$::facts['networking']['ip']], - ttl => $ttl, - zone => "${::facts['networking']['domain']}-master", - tag => 'master-a-record', + record => $::facts['networking']['hostname'], + zone => $::facts['networking']['domain'], + order => $order, } } if $reverse { - @@resource_record { "${fqdn}_${addr}-ptr": - ensure => present, - record => $::facts['arpa'][$intf]['addr'], + profiles::dns::record { "${fqdn}_${intf}_PTR": + value => "${::facts['networking']['fqdn']}.", type => 'PTR', - data => [$fqdn], - ttl => $ttl, - zone => "${::facts['arpa'][$intf]['zone']}-master", - tag => 'master-ptr-record', + record => $last_octet, + zone => $::facts['arpa'][$intf]['zone'], + order => $order, } } } diff --git a/site/profiles/manifests/dns/master.pp b/site/profiles/manifests/dns/master.pp index 5b0a158..a66b665 100644 --- a/site/profiles/manifests/dns/master.pp +++ b/site/profiles/manifests/dns/master.pp @@ -1,12 +1,17 @@ # profiles::dns::master authoritative service class profiles::dns::master ( + Array[String] $nameservers, + Stdlib::AbsolutePath $basedir, Hash $acls = {}, Hash $zones = {}, Hash $views = {}, + Hash $keys = {}, Hash[ String, String ] $tags = {}, + String $owner = 'root', + String $group = 'named', Boolean $dnssec = false, ){ @@ -14,14 +19,29 @@ class profiles::dns::master ( acls => $acls, zones => $zones, views => $views, + keys => $keys, forwarders => [], dnssec => $dnssec, } - # collect records - $tags.each | String $key, String $tag_value | { - if $tag_value != undef { - Resource_record <<| tag == $tag_value |>> + # ensure the target basedir exists + file { $basedir: + ensure => directory, + owner => $owner, + group => $group, + } + + # create zones + $zones.each | String $name, Hash $data | { + if $data['zone_type'] == 'master' { + profiles::dns::zone { $name: + zone => $data['domain'], + basedir => $basedir, + nameservers => $nameservers, + owner => $owner, + group => $group, + before => Bind::Zone[$name] + } } } } diff --git a/site/profiles/manifests/dns/record.pp b/site/profiles/manifests/dns/record.pp new file mode 100644 index 0000000..53dc887 --- /dev/null +++ b/site/profiles/manifests/dns/record.pp @@ -0,0 +1,23 @@ +# defines the base record that will be exported +define profiles::dns::record ( + String $record, + Enum[ + 'PTR', + 'A', + 'CNAME', + 'MX', + 'NS', + 'SRV', + 'TXT' + ] $type, + String $value, + String $zone, + Integer $order, + Stdlib::AbsolutePath $basedir = lookup('profiles::dns::master::basedir'), +) { + @@concat::fragment { "${zone}_${name}": + target => "${basedir}/${zone}.conf", + content => "${record} IN ${type} ${value}\n", + order => $order, + } +} diff --git a/site/profiles/manifests/dns/resolver.pp b/site/profiles/manifests/dns/resolver.pp index bc95e6d..9024c13 100644 --- a/site/profiles/manifests/dns/resolver.pp +++ b/site/profiles/manifests/dns/resolver.pp @@ -3,6 +3,7 @@ class profiles::dns::resolver ( Hash $acls = {}, Hash $zones = {}, Hash $views = {}, + Hash $keys = {}, Array $forwarders = ['8.8.8.8', '1.1.1.1'], ){ @@ -10,6 +11,7 @@ class profiles::dns::resolver ( acls => $acls, zones => $zones, views => $views, + keys => $keys, forwarders => $forwarders, } diff --git a/site/profiles/manifests/dns/server.pp b/site/profiles/manifests/dns/server.pp index 06a4dba..be403fa 100644 --- a/site/profiles/manifests/dns/server.pp +++ b/site/profiles/manifests/dns/server.pp @@ -3,6 +3,7 @@ class profiles::dns::server ( Hash $acls = {}, Hash $zones = {}, Hash $views = {}, + Hash $keys = {}, Array $forwarders = ['8.8.8.8', '1.1.1.1'], Boolean $dnssec = true, ){ @@ -21,6 +22,13 @@ class profiles::dns::server ( version => 'Controlled by Puppet', } + # if keys, import them + $keys.each | $name, $data | { + bind::key { $name: + * => $data, + } + } + # if acls, import them $acls.each | $name, $data | { bind::acl { $name: diff --git a/site/profiles/manifests/dns/zone.pp b/site/profiles/manifests/dns/zone.pp new file mode 100644 index 0000000..f3de4fd --- /dev/null +++ b/site/profiles/manifests/dns/zone.pp @@ -0,0 +1,27 @@ +# defines a zone +define profiles::dns::zone ( + String $zone, + Array[String] $nameservers, + Stdlib::AbsolutePath $basedir, + String $owner, + String $group, +) { + + # Define the concat resource for the zone file + concat { "${basedir}/${zone}.conf": + ensure => present, + owner => $owner, + group => $group, + mode => '0640', + } + + # Add the header fragment (from the template) + concat::fragment { "${basedir}/${zone}_header": + target => "${basedir}/${zone}.conf", + content => template('profiles/dns/zone_header.erb'), + order => '01', + } + + # Collect exported fragments for this zone + Concat::Fragment <<| target == "${basedir}/${zone}.conf" |>> +} diff --git a/site/profiles/templates/dns/zone_header.erb b/site/profiles/templates/dns/zone_header.erb new file mode 100644 index 0000000..563ccc9 --- /dev/null +++ b/site/profiles/templates/dns/zone_header.erb @@ -0,0 +1,16 @@ +; Managed by Puppet, do not change manually +$ORIGIN <%= @zone %>. +$TTL 600 +@ IN SOA <%= @nameservers[0] %>. hostmaster.<%= @zone %>. ( + 1 ; Serial + 604800 ; Refresh + 86400 ; Retry + 2419200 ; Expire + 600 ) ; Negative Cache TTL + +; Name servers +<% @nameservers.each do |ns| -%> +@ IN NS <%= ns %>. +<% end %> + +; Dynamically generated host records