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 file.
#
# See unbound.conf(5) man page.
#
# this is a comment.
#Use this to include other text into the file.
#include: "otherfile.conf"
# The server clause sets the main parameters.
server:
# verbosity number, 0 is least verbose. 1 is default.
verbosity: 1
# specify the interfaces to answer queries from by ip-address.
# The default is to listen to localhost (127.0.0.1 and ::1).
# specify 0.0.0.0 and ::0 to bind to all available interfaces.
# specify every interface[@port] on a new 'interface:' labelled line.
# The listen interfaces are not changed on reload, only on restart.
interface: 192.168.47.210
# Enable IPv4, "yes" or "no".
do-ip4: yes
# Enable IPv6, "yes" or "no".
# do-ip6: yes
# Enable UDP, "yes" or "no".
do-udp: yes
# Enable TCP, "yes" or "no".
do-tcp: yes
# control which clients are allowed to make (recursive) queries
# to this server. Specify classless netblocks with /size and action.
# By default everything is refused, except for localhost.
# Choose deny (drop message), refuse (polite error reply),
# allow (recursive ok), allow_snoop (recursive and nonrecursive ok)
# access-control: 0.0.0.0/0 refuse
access-control: 127.0.0.0/8 allow
access-control: 192.168.47.0/24 allow
# if given, user privileges are dropped (after binding port),
# and the given username is assumed. Default is user "unbound".
# If you give "" no privileges are dropped.
username: ""
# file to read root hints from.
# get one from ftp://FTP.INTERNIC.NET/domain/named.cache
root-hints: "/usr/local/etc/unbound/root-hints.conf"
# enable to not answer id.server and hostname.bind queries.
hide-identity: no
# enable to not answer version.server and version.bind queries.
hide-version: no
# the identity to report. Leave "" or default to return hostname.
identity: "My_Perl_OS.pm"
# the version to report. Leave "" or default to return package version.
version: "My_DNS.pl"
# if yes, perform key lookups adjacent to normal lookups.
# prefetch-key: no
# module configuration of the server. A string with identifiers
# separated by spaces. "iterator" or "validator iterator"
# module-config: "validator iterator"
# File with DLV trusted keys. Same format as trust-anchor-file.
# There can be only one DLV configured, it is trusted from root down.
# Download http://ftp.isc.org/www/dlv/dlv.isc.org.key
# dlv-anchor-file: "dlv.isc.org.key"
# File with trusted keys for validation. Specify more than one file
# with several entries, one file per entry.
# Zone file format, with DS and DNSKEY entries.
# trust-anchor-file: ""
# File with trusted keys, kept uptodate using RFC5011 probes,
# initial file like trust-anchor-file, then it stores metadata.
# Use several entries, one per domain name, to track multiple zones.
# auto-trust-anchor-file: ""
# Trusted key for validation. DS or DNSKEY. specify the RR on a
# single line, surrounded by "". TTL is ignored. class is IN default.
# (These examples are from August 2007 and may not be valid anymore).
# trust-anchor: "nlnetlabs.nl. DNSKEY 257 3 5 AQPzzTWMz8qSWIQlfRnPckx2BiVmkVN6LPupO3mbz7FhLSnm26n6iG9N Lby97Ji453aWZY3M5/xJBSOS2vWtco2t8C0+xeO1bc/d6ZTy32DHchpW 6rDH1vp86Ll+ha0tmwyy9QP7y2bVw5zSbFCrefk8qCUBgfHm9bHzMG1U BYtEIQ=="
# trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A"
# File with trusted keys for validation. Specify more than one file
# with several entries, one file per entry. Like trust-anchor-file
# but has a different file format. Format is BIND-9 style format,
# the trusted-keys { name flag proto algo "key"; }; clauses are read.
# trusted-keys-file: ""
# Ignore chain of trust. Domain is treated as insecure.
# domain-insecure: "example.com"
# Override the date for validation with a specific fixed date.
# Do not set this unless you are debugging signature inception
# and expiration. "" or "0" turns the feature off.
# val-override-date: ""
# Have the validator log failed validations for your diagnosis.
# 0: off. 1: A line per failed user query. 2: With reason and bad IP.
val-log-level: 2
python:
# Script file to load
# python-script: "/usr/local/etc/unbound/ubmodule-tst.py"
# Remote control config section.
remote-control:
# Enable remote control with unbound-control(8) here.
# set up the keys and certificates with unbound-control-setup.
# control-enable: no
# what interfaces are listened to for remote control.
# give 0.0.0.0 and ::0 to listen to all interfaces.
# control-interface: 127.0.0.1
# control-interface: ::1
# port number for remote control operations.
# control-port: 953
# unbound server key file.
# server-key-file: "/usr/local/etc/unbound/unbound_server.key"
# unbound server certificate file.
# server-cert-file: "/usr/local/etc/unbound/unbound_server.pem"
# unbound-control key file.
# control-key-file: "/usr/local/etc/unbound/unbound_control.key"
# unbound-control certificate file.
# control-cert-file: "/usr/local/etc/unbound/unbound_control.pem"
# Stub zones.
# Create entries like below, to make all queries for 'example.com' and
# 'example.org' go to the given list of nameservers. list zero or more
# nameservers by hostname or by ipaddress. If you set stub-prime to yes,
# the list is treated as priming hints (default is no).
# stub-zone:
# name: "example.com"
# stub-addr: 192.0.2.68
# stub-prime: no
# stub-zone:
# name: "example.org"
# stub-host: ns.example.com.
# Forward zones
# Create entries like below, to make all queries for 'example.com' and
# 'example.org' go to the given list of servers. These servers have to handle
# recursion to other nameservers. List zero or more nameservers by hostname
# or by ipaddress. Use an entry with name "." to forward all queries.
# forward-zone:
# name: "example.com"
# forward-addr: 192.0.2.68
# forward-addr: 192.0.2.73@5355 # forward to port 5355.
# forward-zone:
# name: "example.org"
# forward-host: fwd.example.com
// example configuration for a recursive server
options {
pid-file "named.pid";
dnssec-enable yes;
listen-on { 192.168.47.151;};
query-source address 192.168.47.151 ;
allow-recursion {localnets; localhost; 192.168.47.128/25; 255.255.255.0 ; };
directory "/usr/local/etc/named_bla_work/";
// For a recursive server add:
// dnssec-validation yes;
// recursion yes;
recursion no;
};
/// 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 192.168.47.157 port 953
allow { 192.168.47.157;} keys { "rndc-key"; };
};
zone "." {
type hint;
file "root.hints";
};
// Only for a authoritative server
zone "bla.work" {
type master;
file "bla.work";
};
logging {
channel syslog_channel {
syslog daemon; // end to syslog's daemon
severity debug 6;
print-severity yes;
print-category yes;
};
channel query_channel {
file "querylog" size 5m ;
print-time yes;
};
channel update_channel {
file "notify+update.log" size 5m;
print-time yes;
severity debug 5;
};
channel notify_channel {
file "notify+update.log" size 5m;
severity debug 6;
print-time yes;
};
channel everything_else {
file "runlog" size 5m;
print-time yes;
severity debug 6;
print-severity yes;
print-category yes;
};
channel dnssec_log { // a DNSSEC log channel
file "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 192.168.47.<YOUR NUMBER> demo A 10.0.0.1 ; Add when you sign your zone ; $include K<your keysigning>.key ; $include K<your zonesigning>.key
If you store the Workshop Root Hints in a file (e.g. root.hints) and the DNSKEY RR that is used as trust anchor in another (e.g. keyfile.pub) you can use "drill".
drill can be used in two ways: First by tracing using the "-T" flag wich will start at the root and try to follow the chain of trust from there.
$drill -k keyfile.pub -r root.hints -T www.infra.work A
;; Domain: .
;; Signature ok but no chain to a trusted key or ds record
[S] . 100 IN DNSKEY 256 3 5 ;{id = 46728 (zsk), size = 1024b}
. 100 IN DNSKEY 257 3 5 ;{id = 34129 (ksk), size = 2048b}
Checking if signing key is trusted:
New key: . 100 IN DNSKEY 256 3 5 AwEAAbyUyIWQnMn58xwQVTzv+S+cOqJYT7Y8MH6Q3hdhBXjajZGD+3/oKDzR1s47jc763qgJOBXU/62MWfmcrCxbBPNdMysIl+7Bj/uqt6LD+PvA3dG59QmNHPYvTZdOfXlBrOZXAeBJvm/7OL8ugLoIi+1jYsbI+5DxPJ2cmtzEWyxp ;{id = 46728 (zsk), size = 1024b}
Trusted key: . 3600 IN DNSKEY 257 3 5 AwEAAefwq///dxpJmppvNLLH/2RNST0Lcka2WHr6sd3N3nH4gzHg7qFM267FGNwoX8VEqgLvlszaAHUY5bRrNFF00xsHkWFHfYvm5pufZdfNgGLU ;{id = 5259 (ksk), size = 640b}
[S] work. 100 IN DS 41791 5 2 833bbd1c9210dfcb8a6ec03dcbd3dca096cbc5ddcc17d36dd3fb4b2bf0233bd3
work. 100 IN DS 41791 5 1 6d4063c47bef486d5901a3225bb505e0d57b5ae6
;; Domain: work.
;; Signature ok but no chain to a trusted key or ds record
[S] work. 100 IN DNSKEY 257 3 5 ;{id = 41791 (ksk), size = 1024b}
work. 100 IN DNSKEY 256 3 5 ;{id = 19641 (zsk), size = 1024b}
[S] Existence denied: infra.work. DS
;; No ds record for delegation
;; Domain: infra.work.
;; Signature ok but no chain to a trusted key or ds record
[S] infra.work. 100 IN DNSKEY 257 3 5 ;{id = 10177 (ksk), size = 1024b}
infra.work. 100 IN DNSKEY 256 3 5 ;{id = 57798 (zsk), size = 1024b}
[S] Existence denied: www.infra.work. DS
;; No ds record for delegation
;; Domain: www.infra.work.
;; No DNSKEY record found for www.infra.work.
[S] www.infra.work. 100 IN A 192.168.47.10
;;[S] self sig OK; [B] bogus; [T] trusted
The other approach is the chase functionality with the "-S" option
where you start at the leave and try to work your way up in order to
find a link to an existing trust anchor.
$drill -k keyfile.pub -r root.hints -S www.infra.work A
;; Chasing: www.infra.work. A
DNSSEC Trust tree:
www.infra.work. (A)
|---infra.work. (DNSKEY keytag: 57798)
|---infra.work. (DNSKEY keytag: 10177)
No trusted keys found in tree: first error was: No DNSSEC public key(s)
I the example above the root, work, and infra.work were all signed but there was no secure delegation from work to infra.work.