Below are a few examples of configurations you can use during the workshop. Note that they may not be suitable for production zones.
trusted-keys { "." 257 3 5 "AwEAAefwq///dxpJmppvNLLH/2RNST0Lcka2WHr6sd3N3nH4gzHg7qFM 267FGNwoX8VEqgLvlszaAHUY5bRrNFF00xsHkWFHfYvm5pufZdfNgGLU olOHsHU6jCLQR/PIQm3tuX4NHOD9sYfjmUVAsGlqFuwO9zYnt6L1k6/n 04eKWqa4yLspups4MYlxKMs328D3SojZCMAmea+RXZknJKVRZJ83daup 9LBft/hgEZIG/h5VT/ZK1rwJBMe67EOR94uNgNUGjvOP2iowaU9Czoq3 +Na6yAuCibksQvEp2bZjbutC2zTxHAXNIr3AQwLk4BqA9+PfBZWUUEnp 8i0lZfQiVJU=" };This trust-anchor is extracted from the KSK from the root:
. IN DNSKEY 257 3 5 AwEAAefwq///dxpJmppvNLLH/2RNST0Lcka2WHr6sd3N3nH4gzHg7qFM 267FGNwoX8VEqgLvlszaAHUY5bRrNFF00xsHkWFHfYvm5pufZdfNgGLU olOHsHU6jCLQR/PIQm3tuX4NHOD9sYfjmUVAsGlqFuwO9zYnt6L1k6/n 04eKWqa4yLspups4MYlxKMs328D3SojZCMAmea+RXZknJKVRZJ83daup 9LBft/hgEZIG/h5VT/ZK1rwJBMe67EOR94uNgNUGjvOP2iowaU9Czoq3 +Na6yAuCibksQvEp2bZjbutC2zTxHAXNIr3AQwLk4BqA9+PfBZWUUEnp 8i0lZfQiVJU=
// example configuration for a recursive server options { pid-file "named.pid"; dnssec-enable yes; dnssec-validation yes; listen-on {127.0.0.1;}; recursion yes; }; /// Beter uses $include and prevent reading this secret. // There is also a tool to generate this. // man 8 rndc-confgen key "rndc-key" { algorithm hmac-md5; secret "upDNkmX9suVSLvf32mnbCw=="; }; controls { inet 127.0.0.1 port 953 allow { 127.0.0.1;} keys { "rndc-key"; }; }; zone "." { type hint; file "root.hints"; }; logging { channel syslog_channel { syslog daemon; // end to syslog's daemon severity debug 6; print-severity yes; print-category yes; }; channel query_channel { file "/usr/local/workshop/log/querylog" size 5m ; print-time yes; }; channel update_channel { file "/usr/local/workshop/log/notify+update.log" size 5m; print-time yes; severity debug 5; }; channel notify_channel { file "/usr/local/workshop/log/notify+update.log" size 5m; severity debug 6; print-time yes; }; channel everything_else { file "/usr/local/workshop/log/runlog" size 5m; print-time yes; severity debug 6; print-severity yes; print-category yes; }; channel dnssec_log { // a DNSSEC log channel file "/usr/local/workshop/log/dnsseclog" size 20m; print-time yes; // timestamp the entries print-category yes; // add category name to entries print-severity yes; // add severity level to entries severity debug 6; // print debug message <= 3 t }; category dnssec { dnssec_log; }; category security { dnssec_log; }; category queries { query_channel; }; category update { update_channel; syslog_channel; }; category notify { notify_channel; syslog_channel; }; category default { everything_else; }; };
; demonstration zone l ; $TTL 100 @ 100 IN SOA ns ( zonemaster ; assuming zonemaster@orignin 2007082200 100 ; These values 200 ; are to unrealistic for 604800 ; production zones 100 ) NS ns ns A 193.0.24.<YOUR NUMBER> demo A 10.0.0.1 $include K<your keysigning>.key $include K<your zonesigning>.key
; Workshop root hints ; DO NEVER USE IN PRODUCTION . 400 IN NS A.root-servers.work. A.root-servers.work. 400 IN A 193.0.24.110
drill -k keyfile.pub -r root.hints -S www.infra.work A [Example to be constructed]
#!/usr/bin/perl # Demonstration script that tests the availability of self-signed # key-sets. # # Not suitable for production. To little error checking use strict; use Net::DNS::Resolver; my $domain_to_check= "work" ; # The domain should allow AXFR my $res=Net::DNS::Resolver->new( dnssec => 1, tcp_timeout => 1, udp_timeout => 1, retry => 1, ); $domain_to_check . "." unless $domain_to_check =~ /\.$/; my @auth_address=get_authaddress($domain_to_check); die "Could not find authoritative servers for $domain_to_check" unless @auth_address; print "Found the following authoritative servers for $domain_to_check:\n"; foreach my $address ( @auth_address ) { print "\t $address\n"; } my @zone; foreach my $address ( @auth_address ) { print "Trying zonetransfer at $address\n"; my $res=Net::DNS::Resolver->new(); $res->nameserver($address); @zone=$res->axfr($domain_to_check); next unless @zone; } die "Could not zonetransfer from any of the authoritative servers" unless @zone; my %domains; foreach my $rr ( @zone ){ # Those RRs which do not have the same owner name as the domain we # are looking at but are of type NS must be delegations next if ($rr->name eq $domain_to_check); next if ($rr->type ne "NS"); # # Also not deal with things we touched before next if exists $domains{$rr->name}; # use the local resolvers to collect all authoritative servers for # this domain and store the address array that is returned in the # hash-structure. $domains{$rr->name}= [ get_authaddress($rr->name) ]; } # The %domains hash is filled with anonymous arrays containg IP addresses # of the domain that equals the hash key. # # Let us just print that information foreach my $domain (keys %domains){ print "Nameservers for $domain are at: " . join (" ", @{$domains{$domain}}) ."\n"; } # # # Using the above infromation you could check if the SOA is the same # for each server for a particular domain. We skipp that now. # sleep(10); while(1){ print "-----------------------------------\n"; my $res=Net::DNS::Resolver->new( retry => 1, tcp_timeout => 1, udp_timeout => 1, dnssec => 1, ); foreach my $domain (keys %domains){ my @ns= @{$domains{$domain}}; if (! defined @ns) { print "I do not have IP addresses of the nameservers for ". $domains{$domain} ."\n"; next; } $res-> nameserver ( @ns ); my $packet=$res->send($domain,"DNSKEY"); if (! defined $packet ){ print "Nameserver with address(es) ". join(" ", @ns). "do not return answer for $domain DNSKEY \n"; next; } if (! $packet->answer ){ print "DOMAIN \"$domain\" does not have DNSKEYS\n"; }else{ # print "DOMAIN $domain is cool \n"; } my @sigrr; my @keyrr; foreach my $rr ( $packet->answer ){ if ($rr->type eq "DNSKEY"){ push @keyrr, $rr; } if ($rr->type eq "RRSIG"){ push @sigrr, $rr; } } print "DOMAIN \"$domain\" has has not been signed !\n" unless @sigrr; next unless @sigrr; # Check the self signatures over the keyset. foreach my $key (@keyrr){ my $matching_sig; # search the RRSIG with the KEY ID of this key foreach my $sig (@sigrr){ next unless ($key->keytag == $sig->keytag ); $matching_sig=$sig; } if (! defined $matching_sig ){ print "$domain Could not find a self sig for ".$key->keytag ."\n"; next; # next KEY } if (! $matching_sig->verify( \@keyrr , $key )){ print "Validation with ". $key->keytag ." failed\n". "\t". $matching_sig->vrfyerrstr ."\n"; next; }else{ print "$domain Validation with ". $key->keytag .": OK\n"; } } } sleep 5; } # get_authaddress() # Takes a domain as argument and returns an array with IPv4 addresses of # nameservers that are authoritative. sub get_authaddress { my $domain=shift; my $res=Net::DNS::Resolver->new( retry => 1, tcp_timeout => 2, udp_timeout => 2, ); my @addresses; my $packet=$res->send($domain,"NS"); if (! defined $packet ){ print stderr "Resolver does not return answer for $domain \n"; return; # returns undefined vallue. } foreach my $rr ( $packet->answer ){ next if ( $rr->type ne "NS" ); my $packet2=$res->send($rr->nsdname,"A"); foreach my $rr2 ( $packet2->answer ){ next if ($rr2->type ne "A"); next if ($rr2->name ne $rr->nsdname); push @addresses , ($rr2->address); } my $packet3=$res->send($rr->nsdname,"AAAA"); foreach my $rr3 ( $packet3->answer ){ next if ($rr3->type ne "AAAA"); next if ($rr3->name ne $rr->nsdname); push @addresses , ($rr3->address); } } return @addresses; } # Copyright (c) 2007 NLnetLabs # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # # * Neither the name of NLnetLabs nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND # CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR # TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF # THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE.