Installing Stubby on Fedora Linux 27
DNS-over-TLS Part 1: Stubby
Stubby (https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Daemon+-+Stubby) is a DNS privacy stub resolver. Stubby, among other things, does support DNS-over-TLS (RFC 7858 "Specification for DNS over Transport Layer Security (TLS)" https://tools.ietf.org/html/rfc7858).
- Stubby availability in pre-compiled form (status December 2017)
- Homebrew (MacOS X)
- Chocolatey (Windows)
- Manjaro-Linux
- Arch-Linux
- Windows Installer https://dnsprivacy.org/wiki/display/DP/Windows+installer+for+Stubby
This document describes the installation from source on Fedora Linux 27:
Install the dependencies
sudo dnf install -y make gcc libtool libyaml-devel openssl-devel wget
Building Stubby from source
Below are the commands to check-out the stubby source code and compile and install stubby. This has been tested on Fedora Linux 27, but it might work also on other recent Linux versions:
mkdir ~/src cd ~/src git clone https://github.com/getdnsapi/getdns.git cd getdns git checkout develop git submodule update --init libtoolize -ci autoreconf -fi mkdir build cd build ../configure --without-libidn --enable-stub-only \ --with-ssl --with-stubby make sudo make install
SELinux fixes
Fedora Linux uses SELinux by default. To be able to use stubby, the security label on the binary needs to be set:
sudo restorecon -v /usr/local/bin/stubby
review the Stubby default configuration
Stubby configuration is written in YAML (https://en.wikipedia.org/wiki/YAML). Review the default configuration and adapt where needed:
sudo $EDITOR /usr/local/etc/stubby/stubby.yml
Stubby testrun
This command will start Stubby on the commandline in foreground. This is a test if the configuration is valid. After the test, terminate Stubby with CTRL+C.
sudo /usr/local/bin/stubby -l
change stub-resolver configuration
Stubby is listening on port 53 on the loopback IP-Address for
DNS-queries from applications. The resolver configuration in
/etc/resolv.conf
must point to the loopback address.
In this example a very direct way is used by re-writing
/etc/resolv.conf
and making it immutable with an extended
attribute. In production environments, it is cleaner to change the
resolver information in Network-Manager
echo "nameserver 127.0.0.1" > /etc/resolv.conf chattr +i /etc/resolv.conf
test DNS queries
dig dnsworkshop.org a
Systemd-Startunit
Now that Stubby has been successfully tested, stop the running
stubby
process with CTRL+C
and create a new unit configuration for
systemd in /etc/systemd/system/stubby.service
[Unit] Description=Stubby DNS-over-TLS Stub-Resolver After=network.target [Service] ExecStart=/usr/local/bin/stubby -l [Install] WantedBy=multi-user.target
start end enable Stubby
register the new unit file in systemd and start Stubby
systemctl daemon-reload systemctl enable --now stubby systemctl status stubby
Now the enhanced security of privacy of stubby
is available for all
applications on the system.
Delve deep into DNSSEC
BIND 9.10 is the new version of the BIND 9 DNS server from ISC http://isc.org (not to confuse with BIND 10, which is a different DNS server product). I will report in a series of articles about the new features in BIND 9.10. The first beta version of BIND 9.10 has been released this week and can be found at ftp://ftp.isc.org/isc/bind9/9.10.0b1/.
BIND 9.10 contains a new command-line tool to test DNSSEC
installations. The tool is called delve
and it works very much like
the already know dig
. It is like dig
with special DNSSEC
validation powers.
delve
checks the DNSSEC validation chain using the same code that is
used by the BIND 9 DNS server itself. Compared with the DNSSEC testing
function in dig +sigchase
, delve
is much closer to what really
happen inside a DNS server.
1.1 A simple lookup
shell> delve dnsworkshop.org ; fully validated dnsworkshop.org. 3600 IN A 91.190.147.212 dnsworkshop.org. 3600 IN RRSIG A 8 2 3600 20140318181408 20140216173922 63654 dnsworkshop.org. qS9/slk/jvcMc7+HSTMFD1D7GfuW5LIgBj0J1vCCCP5X+g9puhDdRSMM dURzelY6wsPVaUgtx44azEoJYHmNwFJlSsALPnekC6DWjKYMhzYilpUl OKAIZQh5lZxs3oimZHe6GEpEfkZ3ZV0IDTLLe4pIKRXoxDQ2eRJ543GD iTk=
Without extra arguments, delve
will query the local DNS server (taken
from /etc/resolv.conf
) for an IPv4-Address record at the given domain
name. It tries to validate the answer received, prints the result of the
validation, the requested data and the RRSIG Record (DNSSEC signature)
used to verify the data.
1.2 pretty-printing
As with dig
, resource record types and network classes can be given in
almost any order on the commandline. The switch +multi
(for multiline)
enables pretty printing; human readable output that is nearly
formatted for a 78 column screen.
shell> delve dnsworkshop.org soa +multi ; fully validated dnsworkshop.org. 3600 IN SOA ns1.myinfrastructure.org. hostmaster.strotmann.de. ( 86 ; serial 86400 ; refresh (1 day) 7200 ; retry (2 hours) 3542400 ; expire (5 weeks 6 days) 3600 ; minimum (1 hour) ) dnsworkshop.org. 3600 IN RRSIG SOA 8 2 3600 ( 20140321030247 20140219020247 63654 dnsworkshop.org. O8mmiuNdXIWG6huaLiQrvKabDY3qivQ3R5qRUZ1IG3wp bd0UBnvpazpG01ntk8uZ7wEStScmiY7oYtvRGIHG37mG 8GFI60CUx3pdXJIpmodfoUBk8cfGsJXFQODIZCTUQiyk Pv9I6+wjyseDJJTYlrsBCvAEabPExFKZc7v+L+k= )
and IPv6
shell> delve dnsworkshop.org AAAA +multi ; fully validated dnsworkshop.org. 7200 IN AAAA 2001:470:1f08:f1d::2 dnsworkshop.org. 7200 IN RRSIG AAAA 8 2 7200 ( 20140321025727 20140219020247 63654 dnsworkshop.org. gqkc1Xq/UveKrhcXpqOwDsN5HFSqMsPkxXOyCqu9bMyx dtnkh0J0Iqukv+uHL/dDQLnPcxjdFqs3N5Jf3BFHdgkG tf0UPhNKsuhlsRdo2H5O+TqmLvA1zCsYhH/72vVvxslR MiiuZ1ILGpLA2EOyiZu70/ZIU3Ypc3nb8+ydgx4= )
1.3 tracing DNSSEC validation
delve
comes with a set of trace switches that can help
troubleshoot DNSSEC validation issues. The first switch, +rtrace
,
prints the extra DNS lookups delve
performs to validate the answer:
delve dnsworkshop.org mx +multi +rtrace ;; fetch: dnsworkshop.org/MX ;; fetch: dnsworkshop.org/DNSKEY ;; fetch: dnsworkshop.org/DS ;; fetch: org/DNSKEY ;; fetch: org/DS ;; fetch: ./DNSKEY ; fully validated dnsworkshop.org. 3600 IN MX 100 mail.strotmann.de. dnsworkshop.org. 3600 IN RRSIG MX 8 2 3600 ( 20140308193355 20140206183355 63654 dnsworkshop.org. hCOcPJrDCXpcVS82FgGEdUhaUmW3XkxXEuEa4AFvzkzi mDcokYNjrW/Hay4NclSWV0jrBwrXABXik5dh7w7KsPkD WKhw/qVvkuiFCm+T5lb9OVkGQAuPhBOplbVgdbZce9L7 N2IVTQTLMECKfzCTfKeOtwupJAMPXCt/Xskd5o4= )
In this example, in addition to the MX-Record (Mail-Exchanger) Record,
the DNSKEY record (DNSSEC public key) and the DS record (Delegation
signer) for dnsworkshop.org
, as well as the DNSKEY and DS records
for ORG
and the DNSKEY for the root-zone ".
" have been
requested. The trust-anchor for the Internet Root-Zone is compiled
into delve
and acts as the starting trust anchor for the validation.
The switch +mtrace
prints the content of any additional DNS records
that have been fetched for validation.
+vtrace
prints out the DNSSEC chain of validation:
shell> delve _443._tcp.dnsworkshop.org TLSA +multi +vtrace ;; fetch: _443._tcp.dnsworkshop.org/TLSA ;; validating _443._tcp.dnsworkshop.org/TLSA: starting ;; validating _443._tcp.dnsworkshop.org/TLSA: attempting positive response validation ;; fetch: dnsworkshop.org/DNSKEY ;; validating dnsworkshop.org/DNSKEY: starting ;; validating dnsworkshop.org/DNSKEY: attempting positive response validation ;; fetch: dnsworkshop.org/DS ;; validating dnsworkshop.org/DS: starting ;; validating dnsworkshop.org/DS: attempting positive response validation ;; fetch: org/DNSKEY ;; validating org/DNSKEY: starting ;; validating org/DNSKEY: attempting positive response validation ;; fetch: org/DS ;; validating org/DS: starting ;; validating org/DS: attempting positive response validation ;; fetch: ./DNSKEY ;; validating ./DNSKEY: starting ;; validating ./DNSKEY: attempting positive response validation ;; validating ./DNSKEY: verify rdataset (keyid=19036): success ;; validating ./DNSKEY: signed by trusted key; marking as secure ;; validating org/DS: in fetch_callback_validator ;; validating org/DS: keyset with trust secure ;; validating org/DS: resuming validate ;; validating org/DS: verify rdataset (keyid=33655): success ;; validating org/DS: marking as secure, noqname proof not needed ;; validating org/DNSKEY: in dsfetched ;; validating org/DNSKEY: dsset with trust secure ;; validating org/DNSKEY: verify rdataset (keyid=21366): success ;; validating org/DNSKEY: marking as secure (DS) ;; validating dnsworkshop.org/DS: in fetch_callback_validator ;; validating dnsworkshop.org/DS: keyset with trust secure ;; validating dnsworkshop.org/DS: resuming validate ;; validating dnsworkshop.org/DS: verify rdataset (keyid=24209): success ;; validating dnsworkshop.org/DS: marking as secure, noqname proof not needed ;; validating dnsworkshop.org/DNSKEY: in dsfetched ;; validating dnsworkshop.org/DNSKEY: dsset with trust secure ;; validating dnsworkshop.org/DNSKEY: verify rdataset (keyid=2611): success ;; validating dnsworkshop.org/DNSKEY: marking as secure (DS) ;; validating _443._tcp.dnsworkshop.org/TLSA: in fetch_callback_validator ;; validating _443._tcp.dnsworkshop.org/TLSA: keyset with trust secure ;; validating _443._tcp.dnsworkshop.org/TLSA: resuming validate ;; validating _443._tcp.dnsworkshop.org/TLSA: verify rdataset (keyid=63654): success ;; validating _443._tcp.dnsworkshop.org/TLSA: marking as secure, noqname proof not needed ; fully validated _443._tcp.dnsworkshop.org. 3544 IN TLSA 3 0 1 ( 3E5E70BBA957CA0DAFCB799F15F6236133C0F6C73FA7 3762BFFBCA4AF92389CA ) _443._tcp.dnsworkshop.org. 3544 IN RRSIG TLSA 8 4 3600 ( 20140309145739 20140207135739 63654 dnsworkshop.org. JYkLiFqvrjqiIlm/bA4CaffJ3Iikos31bfEVb2njjIR+ /7dudq9pAj898OVZrtqIjmfD7knyCT2nt6Gp/yFYif4k Tt7W2XMhnWecwRnFexhVYp1zg2dkZSw4XcBRMz/F2NkM 0xziG9dNFg/6AAs/0ehMurLvRj1ula/UIO/wU5w= )
delve
is a very useful tool, not only for BIND 9 admins, but for
everyone who needs to troubleshoot and fix DNS- and DNSSEC related
issues.
Compiling BIND 9.9.5 on OpenBSD
while compiling BIND 9 Version 9.9.5 on OpenBSD, I've got
making all in /usr/src/bind-9.9.5/lib/lwres/unix/include/lwres gcc -I/usr/src/bind-9.9.5 -I./unix/include -I. -I./include -I./include - -I/usr/src/bind-9.9.5/lib/isc/include -I../../lib/isc - -I../../lib/isc/include -I../../lib/isc/unix/include - -I../../lib/isc/nothreads/include -I../../lib/isc/x86_32/include - -g -O2 -W -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings - -Wformat -Wpointer-arith -fno-strict-aliasing -c gethost.c gethost.c: In function `copytobuf': gethost.c:307: error: `uintptr_t' undeclared (first use in this function) gethost.c:307: error: (Each undeclared identifier is reported only once gethost.c:307: error: for each function it appears in.) *** Error code 1 Stop in /usr/src/bind-9.9.5/lib/lwres. *** Error code 1 Stop in /usr/src/bind-9.9.5/lib (line 103 of Makefile). *** Error code 1 Stop in /usr/src/bind-9.9.5 (line 107 of Makefile).
adding
#ifdef HAVE_INTTYPES_H #include <inttypes.h> /* uintptr_t */ #endif
to the file <bind9-source>/lib/lwres/gethost.c
fixes this issue (type
"uintptr\t" not known). This issue has been reported upstream to ISC
and will be fixed in the next BIND 9 release.
a local, augmented root-zone with DNSSEC
Sunday Dec 22, 2013
Why a local root zone
Sometimes I get this question in my DNSSEC training classes: "now DNSSEC seems to be a good technology, but the root-zone is controlled by the US government. Because of that, can we trust DNSSEC?".
My answer is not to mix technology (DNSSEC) with implementation (the DNS system of the Internet).
Both are separate. While I can understand that some people do not trust the organisations in control of the Internet DNS root-zone, I see no flaw in DNSSEC (at this moment).
One way to solve the trust issue with the Internet root-zone is to host your own root-zone for the Internet. Then you are in full control of that zone. Have that zone in your own network, or on your Laptop computer und use it for the starting.point of all DNSSEC validation (the trust anchor) for DNS.
Besides the trust question, there might be another reason to operate a local root-zone: some organisations have created an internal, private top-level domain (TLD)1. A local, dnssec-signed root-zone enables the operator to remove or add any delegations, while still being able to validate all DNSSEC signed data in the Internet, as well as data that is stored in their own private DNS namespace.
The following tutorial explains the steps required to generate a local augmented and DNSSEC signed root-zone. The tutorial requires some understanding of DNS concepts and basic knowledge on DNSSEC. A good starting point to learn about DNSSEC (besides a training) is the book DNSSEC mastery by Michael W. Lucas.
All the tools used are part of the BIND DNS Server for ISC (Internet Systems Consortium). This tutorial has been tested using BIND 9.9.4-P1. Older or newer versions of BIND might require a different setup.
The setup
We need one or more authoritative servers to host the augmented root-zone. For production deployments in an internal network, at least two authoritative servers are required. For a local root-zone on a mobile device (Laptop etc.), one single authoritative server might be good enough.
We also need at least one caching DNS server (smart resolver). This cannot be the same DNS server instance as the authoritative server, however it is possible to run both (caching and authoritative server) on the same machine, but have them listen to different IP addresses. In this tutorial, I will use two separate machines:
- authoritative server: a.myroot-server.loc:192.0.2.53
- caching server: cache.loc:192.0.2.153
On both servers, the BIND configuration file will be in
/etc/named.conf
and the BIND "data" directory will be /var/named
.
The operating-system used is Debian 7.x.
Authoritative Server (DNS root-server)
Root-Zone
The starting point is the official root-zone. The "F" root-server
allows zone transfer of the full root-zone (alternatively, the
root-zone can be downloaded by ftp from ftp.internic.net
).
shell> mkdir -p /var/named/root shell> cd /var/named/root shell> dig @f.root-servers.net . axfr +onesoa | grep -v DNSKEY > root.zone shell> named-checkzone . root.zone
The grep command will remove the public DNSSEC keys (the DNSKEY records) from the zone, as we will use our own DNSSEC keys for signing the root zone.
The command named-checkzone
will test if the zone is completely
transferred and will load. Expect to see a couple of "glue record"
warnings from the tool, we can ignore them.
Next, we create a new Zone-Signing-Key (ZSK) and a Key-Signing-Key (KSK) for the root-zone:
shell> dnssec-keygen -K /var/named/keys/ -a RSASHA256 -b 2048 -n ZONE . shell> dnssec-keygen -K /var/named/keys/ -a RSASHA256 -b 4096 -f KSK -n ZONE .
Now we copy the new DNSKEY records into the root-zone file2:
shell> cat ../keys/K.+008+*.key >> root.zone
The official Internet root-zone authoritative servers have names in
the root-servers.net
domain. As we do not have the private key for
that name, and we cannot enter a DS record (delegation signer) for our
internal root-server into the .net
zone, we need to change the NS
records and the SOA record. In my example, the hostname of the local
root-server is in the myroot-servers.loc
domain. That name is stored
inside the loc.
TLD, which we will also host on our authoritative
server.
With an text editor, we change the SOA record and the NS record(s) to point to our own authoritative servers. We also need to add proper glue records for every hostname used in the NS records:
. 86400 IN SOA a.myroot-servers.loc. hostmaster.loc. 2013122200 1800 900 604800 86400 . 518400 IN NS a.myroot-servers.loc. loc. 86400 IN NS a.myroot-servers.loc. a.myroot-servers.loc. 86400 IN A 192.0.2.53
Make sure that all other NS records for the root zone "." have been removed.
Now we can sign our zone:
shell> dnssec-signzone -o . -t -R -S -K /var/named/keys/ root.zone Fetching ZSK 15795/RSASHA256 from key repository. Fetching KSK 50434/RSASHA256 from key repository. Verifying the zone using the following algorithms: RSASHA256. Zone fully signed: Algorithm: RSASHA256: KSKs: 1 active, 0 stand-by, 0 revoked ZSKs: 1 active, 0 stand-by, 0 revoked root.zone.signed Signatures generated: 528 Signatures retained: 0 Signatures dropped: 3 Signatures successfully verified: 0 Signatures unsuccessfully verified: 0 Signing time in seconds: 85.686 Signatures per second: 6.161 Runtime in seconds: 89.025
The -R
switch removed all signatures created by the DNSSEC keys of
the real root zone. The -t
switch prints out some benchmark
information. Your signing process is probably faster, as I tested
this on a Rasberry Pi.
the augmented ".loc" TLD-Zone
Below is the content of the zone-file for the .loc
TLD zone. It
contains the same NS records as we have seen in the root-zone for the
delegation of the .loc
zone:
$TTL 86400 loc. 86400 IN SOA a.myroot-servers.loc. ( hostmaster 1 1d 2h 41d 1h ) loc. 86400 IN NS a.myroot-servers.loc. a.myroot-servers.loc. 86400 IN A 192.0.2.53
The .loc
TLD should also be DNSSEC secured, so we create a set of keys
for this zone as well:
shell> dnssec-keygen -K /var/named/keys/ -a rsasha256 -b 2048 \ -n ZONE loc shell> dnssec-keygen -K /var/named/keys/ -a rsasha256 -b 4096 \ -f KSK -n ZONE loc
The BIND configuration file
This is the BIND configuration file named.conf
for the authoritative
server. It loads both the root-zone and the .loc
private TLD. Both
zones are configured as dynamic zones. After loading the zones into
the BIND DNS Server, you cannot change the zone content with an text
editor anymore. You need to use nsupdate
instead. I highly recommend
nsupdate
, as it catches a number of errors that can occur when
editing zone file manually:
options { directory "/var/named"; key-directory "keys"; dnssec-enable yes; dnssec-validation auto; dnssec-lookaside auto; recursion no; }; zone "." { type master; file "root/root.zone.signed"; update-policy local; auto-dnssec maintain; }; zone "loc" { type master; file "master/loc.zone"; update-policy local; auto-dnssec maintain; };
This is the time to check the BIND configuration and all zone-files:
shell> named-checkconf -z zone ./IN: loaded serial 2013122201 (DNSSEC signed) zone loc/IN: loaded serial 1
If named-checkconf
does not report any errors, we start our DNS
Server (from the command-line or using the start-script):
shell> named shell> tailf /var/log/syslog 22-Dec-2013 14:39:27.405 starting BIND 9.9.4-P1 -g 22-Dec-2013 14:39:27.407 built with '--libdir=/usr/local/lib' 22-Dec-2013 14:39:27.409 ---------------------------------------------------- 22-Dec-2013 14:39:27.411 BIND 9 is maintained by Internet Systems Consortium, 22-Dec-2013 14:39:27.412 Inc. (ISC), a non-profit 501(c)(3) public-benefit 22-Dec-2013 14:39:27.412 corporation. Support and training for BIND 9 are 22-Dec-2013 14:39:27.412 available at https://www.isc.org/support 22-Dec-2013 14:39:27.412 ---------------------------------------------------- 22-Dec-2013 14:39:27.414 using 1 UDP listener per interface 22-Dec-2013 14:39:27.418 using up to 4096 sockets 22-Dec-2013 14:39:27.471 loading configuration from '/etc/named.conf' [...] 22-Dec-2013 14:39:28.143 zone ./IN: loaded serial 2013122200 (DNSSEC signed) 22-Dec-2013 14:39:28.148 all zones loaded 22-Dec-2013 14:39:28.150 running 22-Dec-2013 14:39:28.152 zone ./IN: sending notifies (serial 2013122200) 22-Dec-2013 14:39:28.159 zone ./IN: reconfiguring zone keys 22-Dec-2013 14:39:28.172 zone ./IN: next key event: 22-Dec-2013 15:39:28.159
The .loc
TLD needs to be signed, we do that using rndc
:
shell> rndc sign loc
As rndc sign
does not report some types of errors, we check if the
.log
zone is now really signed:
shell> dig -t soa loc +dnssec +m @localhost ; <<>> DiG 9.9.4-P1 <<>> -t soa loc +dnssec +m @localhost ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 31525 ;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 3 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags: do; udp: 4096 ;; QUESTION SECTION: ;loc. IN SOA ;; ANSWER SECTION: loc. 86400 IN SOA a.myroot-servers.loc. hostmaster.loc. ( 3 ; serial 86400 ; refresh (1 day) 7200 ; retry (2 hours) 3542400 ; expire (5 weeks 6 days) 3600 ; minimum (1 hour) ) loc. 86400 IN RRSIG SOA 8 1 86400 ( 20140121142448 20131222132448 38865 loc. cDBUly3QhZ0dm6HJboA/UQPYkMLFK3pWGOt8x98pzY+W oD3cBult7trdxAqNgMuyl5nTZbciEU0o0HNKZlr9cJ75 sxqY2PbKjPyZ63t9837LRIoWQtce62M+uP9KLnbaBXrw x9eeyUofy8hNFRstGwoTuDqT5s0GgcUBGjpOWS3vyQB2 zAj1cNvy8Mr9sTdxw84VdM7np30dn6z/9IrGurVD3Etz YXo94QgZrNMExqV2u9vYE+tJWldeo+swbwctWH6f/oqC jvOArSiR378h0XiHq11IzM4cjx0IwW0rsVYmD+dhwsEm svLsY66mZRKqyskaXXbbIOUoXWrydwiv+Q== ) ;; AUTHORITY SECTION: [...]
Yes, we see a RRSIG signature for the SOA record, so the signing process was successful.
To create a full DNSSEC chain-of-trust from the .loc
TLD to the
local root-zone, we need to add the DS record (delegation signer) into
out private root-zone. We create the DS-Record from the KSK of .loc
…
shell> dnssec-dsfromkey /var/named/keys/Kloc.+008+38611.key loc. IN DS 38611 8 1 FBBBF41938C6CA0E286675F9BBD38C7719217B89 loc. IN DS 38611 8 2 52F2B009BCD019B9AE2470EAE321DAE74AE77B58F094778BCCD9A53AF38A30F8
… and use nsupdate
to add the DS-Records to the root-zone:
# nsupdate -l > ttl 86400 > add loc. IN DS 38611 8 1 FBBBF41938C6CA0E286675F9BBD38C7719217B89 > add loc. IN DS 38611 8 2 52F2B009BCD019B9AE2470EAE321DAE74AE77B58F094778BCCD9A53AF38A30F8 > send > quit
Our authoritative server is now ready. Next is the caching server(s).
the Caching Server configuration
We start with a basic BIND named.conf
configuration file for a
caching, validating DNS Server:
acl myclients { 192.0.2.0/24; localhost; }; options { directory "/var/named"; allow-recursion { myclients; }; dnssec-enable yes; dnssec-validation yes; dnssec-lookaside auto; }; logging { channel syslog { syslog daemon; severity info; }; channel security { file "security.log" versions 10 size 50M; print-time yes; }; channel query_log { file "query.log" versions 10 size 50M; severity debug; print-time yes; }; category general { syslog; }; category security { security; }; category queries { query_log; }; category dnssec { security; }; category default { syslog; }; category resolver { syslog; }; category client { syslog; }; category query-errors { query_log; }; category edns-disabled { syslog; }; }; managed-keys { "." initial-key 257 3 8 "AwEAAcFN/moqnq1SxdGnZW9JigGYgmFx5WN68RKJ90Je 61LJVXi8pKFRz+rajcAu7g7hb0o56RGShWkIWJAosOGr O4onzJ5t+h+rwRNe7EX++KI9XJobzHp+LQiOi/eo2cze 91oik9+9Tr+NzyJsssOEq9X/mm9hP44a8YgqSzR+rwCb 8jeB9WPhQk25Sp7qN3o8WLCfDxFy6ioOFa7MFirUa1dK 30B92X10JN0KA3d0UmOJ3GU50T0WSbWq15k28qX0et/M W3Wl3T5CclG0goM19ET0iQPJh4mN3Gdw9bHqDyiPsqeP MRJNzjb+EgK+MOp3eAqbQ1hlnr/ruwOMKz6oEIYviec8 QWvJShmeY4+rRCL5lzZuQ7AYOQq8QO4jUnqTe2/t/Oqy o6yqOtiwsLjmgnsK11qZojJ9RSzjb1r5D5Icl5UHGNxG O6/CQYJMHFsyksYzc1Brtg1PdyHc1zy/GFNI6QEQzlhQ H1nTa+F2MnoZp3k1Z6PTh+GU1796jNtUhMgy4pN7dOqC 35hP3GzaP3/XkXtzWbpZRgcXNahbiKso8eqt3r45MCsK AsW3r3hg+CzujTOjVBveKhGfb3nQvx702IdW6Jy62HWX TvipTuG1Kqw+zWHofR2P0ugAszYQBL7G3Zo45VtEScwP XaWavSbGNnHJH5OQQT6HnDvF8hZP"; }; zone "." { type hint; file "root.hint"; };
The managed-key
is the DNSKEY record of our private root-zone. We
get that record with the query:
shell> dig @192.0.2.53 . DNSKEY | grep 257
This will request the DNSKEY record set from the private root-server,
the grep
will filter out the key-signing-key (KSK) with the flag
field of "257"3.
The file root.hint
will contain the root-hints (NS records and
A/AAAA records of our authoritative DNS servers for the private
root-zone):
shell> dig @192.0.2.53 ns . ; <<>> DiG 9.9.4-P1 <<>> @192.0.2.53 ns . ; (1 server found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 3958 ;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 2 ;; WARNING: recursion requested but not available ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;. IN NS ;; ANSWER SECTION: . 518400 IN NS a.myroot-servers.loc. ;; ADDITIONAL SECTION: a.myroot-servers.loc. 86400 IN A 192.0.2.53 ;; Query time: 15 msec ;; SERVER: 192.0.2.53#53(192.0.2.53) ;; WHEN: Sun Dec 22 15:06:50 CET 2013 ;; MSG SIZE rcvd: 77
This data can be redirected into the file:
shell> dig @192.0.2.53 ns . > root.hint
Next, we check that the BIND configuration is error free …
shell> named-checkconf -z
and if no error is shown, we start the BIND DNS Server:
shell> named shell> tail /var/log/syslog Dec 22 18:19:13 raspidev named[2384]: automatic empty zone: 9.E.F.IP6.ARPA Dec 22 18:19:13 raspidev named[2384]: automatic empty zone: A.E.F.IP6.ARPA Dec 22 18:19:13 raspidev named[2384]: automatic empty zone: B.E.F.IP6.ARPA Dec 22 18:19:13 raspidev named[2384]: automatic empty zone: 8.B.D.0.1.0.0.2.IP6.ARPA Dec 22 18:19:13 raspidev named[2384]: command channel listening on 127.0.0.1#953 Dec 22 18:19:13 raspidev named[2384]: command channel listening on ::1#953 Dec 22 18:19:13 raspidev named[2384]: managed-keys-zone: loaded serial 9 Dec 22 18:19:13 raspidev named[2384]: all zones loaded Dec 22 18:19:13 raspidev named[2384]: running
Now, on the caching server, we should be able to validate out own root zone (watch for the AD-Flag):
; <<>> DiG 9.9.4-P1 <<>> @localhost soa . +adflag +m ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13316 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;. IN SOA ;; ANSWER SECTION: . 86327 IN SOA a.myroot-servers.loc. nstld.verisign-grs.com. ( 2013122200 ; serial 1800 ; refresh (30 minutes) 900 ; retry (15 minutes) 604800 ; expire (1 week) 86400 ; minimum (1 day) ;; AUTHORITY SECTION: . 518274 IN NS a.myroot-servers.loc. ;; Query time: 3 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Dec 22 15:13:02 CET 2013 ;; MSG SIZE rcvd: 118
And we should also be able to validate other data out in the Internet,
like the domain name for this blog (dnsworkshop.de
or
dnsworkshop.org
):
; <<>> DiG 9.9.4-P1 <<>> dnsworkshop.de @localhost ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60851 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;dnsworkshop.de. IN A ;; ANSWER SECTION: dnsworkshop.de. 7200 IN A 91.190.147.212 ;; AUTHORITY SECTION: dnsworkshop.de. 7200 IN NS ns2.myinfrastructure.org. dnsworkshop.de. 7200 IN NS ns1.myinfrastructure.org. ;; Query time: 1230 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Dec 22 15:14:16 CET 2013 ;; MSG SIZE rcvd: 115
And we can also validate our augmented .loc
TLD that does not exist
in the public Internet:
; <<>> DiG 9.9.4-P1 <<>> @localhost a.myroot-servers.loc +adflag ; (2 servers found) ;; global options: +cmd ;; Got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 15859 ;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1 ;; OPT PSEUDOSECTION: ; EDNS: version: 0, flags:; udp: 4096 ;; QUESTION SECTION: ;a.myroot-servers.loc. IN A ;; ANSWER SECTION: a.myroot-servers.loc. 86400 IN A 192.0.2.53 ;; AUTHORITY SECTION: loc. 86399 IN NS a.myroot-servers.loc. ;; Query time: 94 msec ;; SERVER: 127.0.0.1#53(127.0.0.1) ;; WHEN: Sun Dec 22 18:22:33 CET 2013 ;; MSG SIZE rcvd: 79
Voila, a DNSSEC signed local root-zone.
The root-zone is a busy place right now. New TLDs are added all the
time. Make sure you follow these changes. A good way to get notice of
updates in the root zone is to follow @diffroot on Twitter. Please
remember, if you followed this tutorial, you need to add the changes
using nsupdate
, do not use a text editor on the zone files!
Footnotes:
1]
I do not recomment hosting a private TLD, it is much easier and less
error-prone to run a private DNS delegation on the second or third level
of the DNS hierachy, such as private.example.com
.
2]
Be sure to use the double >>
to append to the file, a single >
will
override the zonefile with the keys. Not what we want.
3] Always double check the key data, there is a slight chance that the sequence "257" will appear in the key material of the ZSK as well!
Mirror - Mirror -- Resources on DNS reflection attacks
NCSC 2013 conference Presentation
RFC and BCP
DNS Monitoring
DNS reflection and amplification attacks
Open Resolvers
Minimal Responses
RateLimit
- Tony Finch - Rate limiting DNS
- BIND 9 patches by Paul Vixie and Vernon Schryver
- BIND 9 binaries for MacOS X, Debian, RedHat, Solaris with RRL patches applied (look for RRL in the filename)
- DNS Dampening by Lutz Donnerhacke
- DNS Response Rate Limit in NSD
- RRL in the Knot DNS Server (CZ.NIC Labs)
- BIND 10 RRL checkin information