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.