diff --git a/Gemfile b/Gemfile index b0ebba2..6f6be9a 100644 --- a/Gemfile +++ b/Gemfile @@ -9,6 +9,7 @@ group :test do gem "rspec", '> 3.4.0' gem "rspec-puppet" gem "rspec-puppet-facts" + gem "rspec-command" gem 'rubocop', '> 0.47.0', '< 0.49.0' gem 'simplecov', '>= 0.11.0' gem 'simplecov-console' diff --git a/README.md b/README.md index ee505b2..bfc1045 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,21 @@ bind::zone { 'example.com-external': } ``` +Set parameter `dnssec_ksk_only => true` if a DNSSEC zone should only be signed with a key signing key and no zone signing key should be created. + +The DNSSEC key algorithm can be configured by `dnssec_key_algorithm` which can be one of (defaults to `RSASHA256`): +* RSASHA256 +* RSASHA512 +* ECCGOST +* ECDSAP256SHA256 +* ECDSAP384SHA384 +* ED25519 +* ED448 + +For algorithms `RSASHA256` and `RSASHA512` key length can be configured by: +* `dnssec_ksk_size` for the key signing key (default 2048) +* `dnssec_ksk_size` for the zone signing key (default 1024) + A master zone which is initialized with a pre-existing zone file (for example, to migrate an existing zone to a bind-module controlled server or to recover from a backup): diff --git a/files/dnssec-init b/files/dnssec-init index 73da6b1..62f7188 100644 --- a/files/dnssec-init +++ b/files/dnssec-init @@ -7,13 +7,27 @@ KEY_DIRECTORY="${4:-${CACHEDIR}/${NAME}}" RANDOM_DEVICE="$5" NSEC3_SALT="$6" ZONE_FILE="$7" +DNSSEC_KSK_ONLY="$8" +DNSSEC_KEY_ALGO="$9" +DNSSEC_KSK_SIZE="${10}" +DNSSEC_ZSK_SIZE="${11}" PATH=/bin:/sbin:/usr/bin:/usr/sbin -dnssec-keygen -a RSASHA256 -b 1024 -r "${RANDOM_DEVICE}" -K "${KEY_DIRECTORY}" "${DOMAIN}" -dnssec-keygen -a RSASHA256 -b 2048 -r "${RANDOM_DEVICE}" -f KSK -K "${KEY_DIRECTORY}" "${DOMAIN}" +if [ "$DNSSEC_KEY_ALGO" = "RSASHA256" -o "$DNSSEC_KEY_ALGO" = "RSASHA512" ]; then + DNSSEC_KSK_OPTIONS="-b ${DNSSEC_KSK_SIZE}" + DNSSEC_ZSK_OPTIONS="-b ${DNSSEC_ZSK_SIZE}" +fi + +if [ "$DNSSEC_KSK_ONLY" != "true" ]; then + dnssec-keygen -a "${DNSSEC_KEY_ALGO}" ${DNSSEC_ZSK_OPTIONS} -r "${RANDOM_DEVICE}" -K "${KEY_DIRECTORY}" "${DOMAIN}" +fi +dnssec-keygen -a "${DNSSEC_KEY_ALGO}" ${DNSSEC_KSK_OPTIONS} -r "${RANDOM_DEVICE}" -f KSK -K "${KEY_DIRECTORY}" "${DOMAIN}" +if [ "$DNSSEC_KSK_ONLY" ]; then + DNSSEC_KSK_ONLY_SIGN_OPTIONS="-z" +fi if [ "$NSEC3_SALT" != '' ]; then - dnssec-signzone -S -u -3 "${NSEC3_SALT}" -d "${CACHEDIR}" -K "${KEY_DIRECTORY}" -o "${DOMAIN}" "${CACHEDIR}/${NAME}/${ZONE_FILE}" + dnssec-signzone -S ${DNSSEC_KSK_ONLY_SIGN_OPTIONS} -u -3 "${NSEC3_SALT}" -d "${CACHEDIR}" -K "${KEY_DIRECTORY}" -o "${DOMAIN}" "${CACHEDIR}/${NAME}/${ZONE_FILE}" else - dnssec-signzone -S -d "${CACHEDIR}" -K "${KEY_DIRECTORY}" -o "${DOMAIN}" "${CACHEDIR}/${NAME}/${ZONE_FILE}" + dnssec-signzone -S ${DNSSEC_KSK_ONLY_SIGN_OPTIONS} -d "${CACHEDIR}" -K "${KEY_DIRECTORY}" -o "${DOMAIN}" "${CACHEDIR}/${NAME}/${ZONE_FILE}" fi diff --git a/manifests/zone.pp b/manifests/zone.pp index dd51ecf..7cb0efb 100644 --- a/manifests/zone.pp +++ b/manifests/zone.pp @@ -11,6 +11,10 @@ $update_policies = '', $allow_transfers = '', $dnssec = false, + Boolean $dnssec_ksk_only = false, + Enum['RSASHA256', 'RSASHA512', 'ECCGOST', 'ECDSAP256SHA256', 'ECDSAP384SHA384', 'ED25519', 'ED448'] $dnssec_key_algorithm = 'RSASHA256', + Integer $dnssec_ksk_size = 2048, + Integer $dnssec_zsk_size = 1024, $nsec3_salt = '', $key_directory = '', $ns_notify = true, @@ -131,7 +135,8 @@ exec { "dnssec-keygen-${name}": command => "/usr/local/bin/dnssec-init '${cachedir}' '${name}'\ '${_domain}' '${key_directory}' '${random_device}' '${nsec3_salt}'\ - '${zone_file}'", + '${zone_file}' '${dnssec_ksk_only}' '${dnssec_key_algorithm}'\ + '${dnssec_ksk_size}' '${dnssec_zsk_size}'", cwd => $cachedir, user => $bind_user, creates => "${cachedir}/${name}/${zone_file}.signed", diff --git a/spec/fixtures/files/zones/example.com/example.com.zone b/spec/fixtures/files/zones/example.com/example.com.zone new file mode 100644 index 0000000..4c318fe --- /dev/null +++ b/spec/fixtures/files/zones/example.com/example.com.zone @@ -0,0 +1,9 @@ +$TTL 86400 +@ IN SOA localhost. root.localhost. ( + 1 ; Serial + 60 ; Refresh + 30 ; Retry + 300 ; Expire + 10 ) ; Negative Cache TTL +; +@ IN NS example.com. diff --git a/spec/integration/dnssec-init_spec.rb b/spec/integration/dnssec-init_spec.rb new file mode 100644 index 0000000..d8cc2a9 --- /dev/null +++ b/spec/integration/dnssec-init_spec.rb @@ -0,0 +1,30 @@ +# ex: syntax=ruby ts=2 sw=2 si et +require 'spec_helper' + +describe 'dnssec-init should create RSASHA256 KSK(2048) and ZSK(1024)' do + fixture_file '../../files/dnssec-init' + fixture_file 'files/zones' + command '/bin/sh dnssec-init . example.com example.com . /dev/urandom 12345678 example.com.zone false RSASHA256 2048 1024' + its(:stdout) { is_expected.to match(/^Kexample\.com\.\+008\+[0-9]+\nKexample\.com\.\+008\+[0-9]+\n\.\/example\.com\/example\.com\.zone\.signed$/m) } +end + +describe 'dnssec-init should create RSASHA256 KSK(2048) only' do + fixture_file '../../files/dnssec-init' + fixture_file 'files/zones' + command '/bin/sh dnssec-init . example.com example.com . /dev/urandom 12345678 example.com.zone true RSASHA256 2048 1024' + its(:stdout) { is_expected.to match(/^Kexample\.com\.\+008\+[0-9]+\n\.\/example\.com\/example\.com\.zone\.signed$/m) } +end + +describe 'dnssec-init should create RSASHA256 KSK(4096) and ZSK(2048)' do + fixture_file '../../files/dnssec-init' + fixture_file 'files/zones' + command '/bin/sh dnssec-init . example.com example.com . /dev/urandom 12345678 example.com.zone false RSASHA256 4096 2048' + its(:stdout) { is_expected.to match(/^Kexample\.com\.\+008\+[0-9]+\n\.\/example\.com\/example\.com\.zone\.signed$/m) } +end + +describe 'dnssec-init should create ECDSAP256SHA256 KSK and ZSK' do + fixture_file '../../files/dnssec-init' + fixture_file 'files/zones' + command '/bin/sh dnssec-init . example.com example.com . /dev/urandom 12345678 example.com.zone false ECDSAP256SHA256' + its(:stdout) { is_expected.to match(/^Kexample\.com\.\+013\+[0-9]+\nKexample\.com\.\+013\+[0-9]+\n\.\/example\.com\/example\.com\.zone\.signed$/m) } +end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 74dac10..b75ffce 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,10 +1,12 @@ require 'puppetlabs_spec_helper/module_spec_helper' require 'rspec-puppet-facts' require 'rspec-puppet' +require 'rspec_command' include RspecPuppetFacts RSpec.configure do |c| + c.include RSpecCommand c.hiera_config = File.expand_path(File.join(__FILE__, '../fixtures/hiera.yaml')) c.after(:suite) do RSpec::Puppet::Coverage.report! diff --git a/templates/zone.conf.erb b/templates/zone.conf.erb index 8a36dd7..f7c63d4 100644 --- a/templates/zone.conf.erb +++ b/templates/zone.conf.erb @@ -4,6 +4,9 @@ zone "<%= @_domain %>" { type <%= @zone_type %>; <%- if @dnssec -%> auto-dnssec maintain; +<%- if @dnssec_ksk_only -%> + update-check-ksk no; +<%- end -%> <%- if @key_directory and @key_directory != '' -%> key-directory "<%= @key_directory %>"; <%- else -%>