Quantcast
Channel: Tutorial/Howto – Weberblog.net
Viewing all 63 articles
Browse latest View live

FortiGate HA Cluster

$
0
0
FortiGate HA featured image

This is a step-by-step tutorial for configuring a high availability cluster (active-standby) with two FortiGate firewalls. Since almost all firewall vendors have different principles for their HA cluster, I am also showing a common network scenario for Fortinet.

I am using two FortiWiFi 90D firewalls with software version v5.2.5,build701. The official Fortinet documentation for “High Availability with two FortiGates” can be found here.

Network Layout

FortiGate HA NetworkBasically, all interfaces must be connected with layer-2 switches among both firewalls. (In my lab, these are the wan1 and internal1 ports.) Furthermore, two directly connected interfaces should be used for the HA heartbeats. If the firewall has no dedicated HA interfaces, any unused interfaces can be used instead. (In my lab, I am using ports internal13 and internal14 for the heartbeats on my FortiWiFi-90D firewalls.)

The crucial point is the out-of-band management for accessing both firewalls independent of their HA state. Fortinet has the feature of the “Management Port for Cluster Member“, which must be set during the initial HA process. This interface must be unused to that point and can be configured later with an IP address within the same IP subnet as an already used interface. (In my lab, I am using the internal12 ports for the management ports.)

Screenshot Guide

Note: Before cabling the HA cluster, you should configure both units and then power off (!) the secondary one. Then connect the HA heartbeat interfaces and power on the secondary unit again. This ensures that the primary unit will stay the primary (since it has the longer uptime) and syncs its configuration to the secondary one.

Following are the screenshots for this HA cluster guide. Note the descriptions under each screenshot:

Set the HA Mode to "Active-Passive", reserve an unsused (!) port for cluster management and set all other cluster settings such as the heartbeat interfaces and port monitors. After applying the HA mode, some network outages is present on the complete FortiGate unit. Configure an IP address on the cluster management port just set. This can be in the same IP range than another routed subnet, as seen in the screenshot. On the second unit, configure almost the same HA settings. And give the cluster management port an other (!) IP address than the primary one. If both cluster management IP addresses should be accessible through routed interfaces, a SNAT must be used to route the traffic correctly. Both firewalls can now be accessed via its new IP addresses. This is master unit. And this is the slave unit. Summary of the HA Cluster.

The following two pictures show the physical units after the HA configuration. On the first picture, the HA cluster was not cabled, while on the second, it was. Note the green HA LED:

HA Cluster configured but not cabled. HA Cluster works correctly.

Via the CLI, the

diagnose ha sys status
  command can be used to investigate the cluster:
fd-wv-fw04b $ diagnose sys ha status
HA information
Statistics
        traffic.local = s:0 p:18860 b:1708434
        traffic.total = s:0 p:19031 b:1726842
        activity.fdb  = c:0 q:0

Model=90, Mode=2 Group=0 Debug=0
nvcluster=1, ses_pickup=1, delay=0

HA group member information: is_manage_master=0.
FWF90D3Z13005629, 1.  Slave:128 fd-wv-fw04b
FWF90D3Z13006159, 0. Master:128 fd-wv-fw04

vcluster 1, state=standby, master_ip=169.254.0.1, master_id=0:
FWF90D3Z13005629, 1.  Slave:128 fd-wv-fw04b(prio=1, rev=0)
FWF90D3Z13006159, 0. Master:128 fd-wv-fw04(prio=0, rev=255)

 


FortiGate Application Traffic Shaping

$
0
0
FortiGate Application Traffic Shaping featured image

This is a really cool and easy to use feature of the FortiGate firewall: the traffic shaper. Once an application category uses too much traffic, the bandwidth consumption can be decreased with it. Just about three clicks:

In my case, a customer had an ISP connection of 20 Mbps. Sometimes, the replication of Lotus Notes takes all of this bandwidth which results in packet delay for all other sessions. We decided to limit the “collaboration” application category to a max bandwidth of 10 M. Immediately, the ISP connection was not slowed down anymore.

The following screenshots show how to configure a traffic shaper and how to use it on an application category. The third screenshots shows the overall bandwidth (interface history of wan1) which dropped from 20 to 10 Mbps. Perfect.

Traffic Shaper Application Control Result from 20 to 10 MBits

Using NetFlow with nProbe for ntopng

$
0
0
nProbe ntopng featured image

This blog post is about using NetFlow for sending network traffic statistics to an nProbe collector which forwards the flows to the network analyzer ntopng. It refers to my blog post about installing ntopng on a Linux machine. I am sending the NetFlow packets from a Palo Alto Networks firewall.

My current ntopng installation uses a dedicated monitoring ethernet port (mirror port) in order to “see” everything that happens in that net. This has the major disadvantage that it only gets packets from directly connected layer 2 networks and vlans. NetFlow on the other hand can be used to send traffic statistics from different locations to a NetFlow flow collector, in this case to the tool nProbe. This single flow collector can receive flows from different subnets and routers/firewalls and even VPN tunnel interfaces, etc. However, it turned out that the “real-time” functionalities of NetFlow are limited since it only refreshes flows every few seconds/bytes, but does not give a real-time look at the network. It should be used only for statistics but not for real-time troubleshooting.

Some Pre Notes

I am using a Ubuntu 14.04.5 LTS (GNU/Linux 3.16.0-77-generic x86_64) server. At the time of writing, nProbe had version v.7.4.160802 while ntopng was in version v.2.4.160802. Furthermore note that nProbe requires a license.

For general information about NetFlow use Wikipedia or Cisco or RFC 3954. For the other tools, use the official web sites: nProbe and ntopng. The nProbe site offers a detailed documentation PDF. A similar tutorial for installing nProbe is this one.

Installation of nProbe

(Since I already showed how to install ntopng, I will only show how to use nProbe here.) The stable builds for nProbe and ntopng are listed here. That is, to install nProbe, I used the following commands:

wget http://apt-stable.ntop.org/14.04/all/apt-ntop-stable.deb
sudo dpkg -i apt-ntop-stable.deb
sudo apt-get update

sudo apt-get install nprobe

Since I want to receive NetFlow packets and forward them to ntopng, nProbe must run in Collector Mode. That is, I am using the following configuration file:

sudo nano /etc/nprobe/nprobe-none.conf

with these entries:

--zmq="tcp://*:5556"
--collector-port=2055
-n=none
-i=none

Note the naming of the config file: “nprobe-none.conf“. This is mandatory due to the documentation of nProbe: “When nProbe is used in probe mode it is not bound to any interface as its job is to collect NetFlow from some other device. In this case the configuration file to be created is: nprobe-none.conf.” (To my mind, this is a spelling mistake because it should read “When nProbe is NOT used in probe mode…”. However, it is working.)

Furthermore, an empty “start” file is needed to tell the init process to use this configuration file:

sudo touch /etc/nprobe/nprobe-none.start

After a start of the service with

sudo service nprobe start
, ntopng must be configured to use this nProbe instance. Open the configuration file:
sudo nano /etc/ntopng/ntopng.conf

and add the following interface (= localhost):

--interface="tcp://127.0.0.1:5556"

Finally, restart the ntopng process:

sudo service ntopng restart
.

A netstat view should indicate the listening 2055 UDP port for nProbe, the 5556 TCP port for the connection between nProbe and ntopng, as well as the common 3000 TCP port from the ntopng WebGUI:

weberjoh@jw-nb10-syslog-mirror:~$ sudo netstat -tulpen
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       User       Inode       PID/Program name
tcp        0      0 127.0.0.1:6379          0.0.0.0:*               LISTEN      107        12714       1184/redis-server 1
tcp        0      0 0.0.0.0:5556            0.0.0.0:*               LISTEN      0          15260       1641/nprobe
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      0          12157       1017/sshd
tcp        0      0 0.0.0.0:3000            0.0.0.0:*               LISTEN      65534      14983       1676/ntopng
tcp6       0      0 :::22                   :::*                    LISTEN      0          12159       1017/sshd
udp        0      0 0.0.0.0:2055            0.0.0.0:*                           0          15261       1641/nprobe
udp        0      0 192.168.120.10:123      0.0.0.0:*                           0          14413       1526/ntpd
udp        0      0 127.0.0.1:123           0.0.0.0:*                           0          14412       1526/ntpd
udp        0      0 0.0.0.0:123             0.0.0.0:*                           0          14405       1526/ntpd
udp        0      0 0.0.0.0:161             0.0.0.0:*                           0          12958       1224/snmpd
udp        0      0 0.0.0.0:514             0.0.0.0:*                           0          12684       1157/syslog-ng
udp        0      0 0.0.0.0:55059           0.0.0.0:*                           0          12943       1224/snmpd
udp6       0      0 :::2055                 :::*                                0          15262       1641/nprobe
udp6       0      0 2003:51:6012:120::1:123 :::*                                0          14416       1526/ntpd
udp6       0      0 fe80::21d:92ff:fe53:123 :::*                                0          14415       1526/ntpd
udp6       0      0 ::1:123                 :::*                                0          14414       1526/ntpd
udp6       0      0 :::123                  :::*                                0          14406       1526/ntpd
udp6       0      0 ::1:161                 :::*                                0          12959       1224/snmpd

Since all services are now configured within configuration files that are referenced in the init scripts, they are started automatically after a system reboot. Great.

Palo Alto NetFlow

I am using a Palo Alto Networks firewall (version 7.1.3) to send NetFlow statistics to the nProbe collector. (More information about NetFlow on Palo.) This is configured in the following way: Adding of a NetFlow Server Profile and referencing this profile on all needed Network Interfaces, such as:

New NetFlow Server Profile. Referenced in some (or all) Network Interfaces. Indicated by these icons at the summary page.

I am using quite fast values for the Template Refresh Rate as well as the Active Timeout. On interfaces with huge amount of traffic other values are probably better.

A small tcpdump capture shows some samples of the NetFlow packets sent by the Palo Alto. The following Wireshark screenshots show a NetFlow template as well as a sample flow:

NetFlow Template 258. Sample flow using template 258: SMTP between two IPv6 host using 27 packets.

ntopng Usage

Now here is the usage within ntopng. Simply choose the tcp://127.0.0.1:5556 interface at the upper right side. All features of ntopng remain the same, such as using the Dashboard, the Flows or the Hosts pages. (Refer to my post to see some features.)

Choosing the nProbe interface. Using ntopng as normal.

However, here comes the problem with NetFlow: It is NOT a real-time application that lets ntopng show every single flow and its bandwidth correctly. It can be used to see a rough view of all flows during the past few seconds, but not its actual throughput at the moment.

Refer to the following two dashboard screenshots from ntopng. The first shows the Realtime Top Application Traffic from the NetFlow probe, while the second one shows the same from the mirror port eth1. The 54 MBit/s peak in the first screenshot is not true at all. In fact, it was a constant download over a few minutes. Whereas the second screenshot from eth1 shows the correct real-time bandwidth usage.

Peak from nProbe not correct on this time basis. Real-time view of a mirror port are correct.

Conclusion

nProbe for ntopng can be used quite easily. It is possible to receive flows from different locations which can be displayed in a single instance of ntopng. However, if the primary goal is to have a real-time look at the network, e.g., which hosts or flows are consuming bandwidth, this approach does not fit. NetFlow data must be used with statistical applications that can report traffic stats, but not with real-time analyzers such as ntopng.

Basic BIND Installation

$
0
0
Basic BIND Installation - featured image

This is a basic tutorial on how to install BIND, the Berkeley Internet Name Domain server, on a Ubuntu server in order to run it as an authoritative DNS server. It differs from other tutorials because I am using three servers (one as a hidden primary and two slaves as the public accessible ones), as well as some security such as denying recursive lookups and public zone transfers, as well as using TSIG for authenticating internal zone transfers. That is, this post is not an absolute beginner’s guide.

The basic environment looks like that. Note that I am showing my real IP addresses. Don’t be confused about that and change them to your IPs accordingly:

BIND weberdns.de Servers Master and Slaves

Some notes about the installation of the servers:

  • My domain for these test servers is weberdns.de.
  • The main motivation for the hidden primary approach comes from DNSSEC (will be published later), in which I am managing the keys only on the hidden primary but not on the slaves. No single access is possible from the public Internet to this server.
  • I am using only the private IPv4 or global IPv6 addresses through site-to-site VPN tunnels in order to transfer the zones between the DNS servers. This brings encryption when traversing the Internet, as well as appropriate security policies on the intermediate firewalls.
  • By default, each server sends notifications to all other NS servers in case of a zone change. In my case, the notifications are set to “explicit” to only notify the private IPv4 addresses specified in the zone configuration “also-notify { };” and not the public ones.
  • TSIG is used in order to authenticate the zone transfers (even though not really mandatory since I am using VPN tunnels anyway). For each slave, I am using an unique key.
  • Public zone transfers (AXFR) are disabled globally. Only servers that authenticated with their key within the “allow-transfer { };” statement are allowed to transfer the zone.
  • Per-zone statistics are enabled on all servers.
  • I am using Ubuntu servers version 14.04 LTS either on VMs or on hardware. Of course they have static (NATted) IPv4 and IPv6 addresses. The bind9 package from Ubuntu at the time of writing is version 9.9.5-3ubuntu0.8-Ubuntu (June 2016).

BIND Installation

To install the BIND package simply use the following two statements:

sudo apt-get update
sudo apt-get install bind9

All configuration files are stored in the folder

/etc/bind/
 .

The started process is called “named“. It listens on udp and tcp port 53, each for IPv4 and IPv6:

weberjoh@jw-vm07-ns1:~$ sudo netstat -tulpen | grep named
tcp        0      0 192.168.110.25:53       0.0.0.0:*               LISTEN      106        480821      4703/named
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      106        480819      4703/named
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      106        480822      4703/named
tcp6       0      0 :::53                   :::*                    LISTEN      106        480814      4703/named
tcp6       0      0 ::1:953                 :::*                    LISTEN      106        480823      4703/named
udp        0      0 192.168.110.25:53       0.0.0.0:*                           106        480820      4703/named
udp        0      0 127.0.0.1:53            0.0.0.0:*                           106        480818      4703/named
udp6       0      0 :::53                   :::*                                106        480813      4703/named

To view syslog messages, grep for the “named” process:

tail -f /var/log/syslog | grep named

 

Master

The master server is the one on which the zone files are maintained. At first, some options are set to secure the authoritative server. These are set within the named.conf.options file (in the /etc/bind/ folder).

sudo nano named.conf.options

Add the following options:

// per zone statistics
	zone-statistics yes;

	// no recursion at all
	recursion no;

	// no transfer afxr by default
	allow-transfer { "none"; };

	// no notify to other NS RRs
	// notify only to also-notify IPs
	notify explicit;

Then, add a zone statement inside the named.conf.local file:

sudo nano named.conf.local

In my case a zone weberdns.de of type master. The allow-transfer statement lists the two slave servers that should be able to transfer the zone. Similarly the also-notify statement lists the slaves, too, in order to notify them in case of a zone update.

zone "weberdns.de" {
        type master;
        file "/etc/bind/db.weberdns.de";
        allow-transfer { 2003:51:6012:110::a07:53; 192.168.90.10; };
        also-notify { 2003:51:6012:110::a07:53; 192.168.90.10; };
};

Finally, the zone file must be created. I am using the template from Hetzner. All relevant statements are already explained there, so I won’t repeat them here.

sudo nano db.weberdns.de

This is my basic zone file. The SOA record starts with “ns1.weberdns.de”. There are two NS records (ns1. and ns2.) for this domain, as well as an MX record. Some examples of A, AAAA, CNAME, and TXT records are also shown. And remember to increment the serial number after each modification of the zone file! 😉

;
; BIND data file for weberdns.de
;
$TTL    1h
@       IN      SOA     ns1.weberdns.de. webmaster.weberdns.de. (
                     2016051804         ; Serial
                             1h         ; Refresh
                            15m         ; Retry
                             4w         ; Expire
                             3m )       ; Negative Cache TTL
;
@       IN      NS      ns1.weberdns.de.
@       IN      NS      ns2.weberdns.de.
@       IN      MX 10   mail.weberdns.de.

fg              IN      A       80.154.108.233
                IN      AAAA    2003:51:6012::4
ip              IN      CNAME   ip.webernetz.net.
mail            IN      A       80.154.108.237
                IN      AAAA    2003:51:6012:110::15
ns1             IN      A       80.154.108.230
                IN      AAAA    2003:51:6012:110::a07:53
ns2             IN      A       213.61.29.182
pa              IN      A       80.154.108.228
                IN      AAAA    2003:51:6012::2
txt             IN      TXT     "This is a text."
www             IN      CNAME   blog.webernetz.net.

After these steps, the BIND server must be restarted for all changes to work:

sudo service bind9 restart

A check of the configuration can be done with 

named-checkconf -z
  . If no errors occur, everything works fine.

For updates of the zone file, a reload of BIND fits. No restart is required. The reload can be triggered by either one of these two commands:

sudo service bind9 reload
sudo rndc reload

A basic test can be done with the dig tool, such as:

weberjoh@jw-vm16-ns0:/etc/bind$ dig @localhost fg.weberdns.de

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> @localhost fg.weberdns.de
; (2 servers found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44847
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 4
;; WARNING: recursion requested but not available

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;fg.weberdns.de.                        IN      A

;; ANSWER SECTION:
fg.weberdns.de.         3600    IN      A       80.154.108.233

;; AUTHORITY SECTION:
weberdns.de.            3600    IN      NS      ns2.weberdns.de.
weberdns.de.            3600    IN      NS      ns1.weberdns.de.

;; ADDITIONAL SECTION:
ns1.weberdns.de.        3600    IN      A       80.154.108.230
ns1.weberdns.de.        3600    IN      AAAA    2003:51:6012:110::a07:53
ns2.weberdns.de.        3600    IN      A       213.61.29.182

;; Query time: 3 msec
;; SERVER: ::1#53(::1)
;; WHEN: Wed May 18 16:02:11 CEST 2016
;; MSG SIZE  rcvd: 155

Note the “aa” flag in line 8 which indicates that this is an “authoritative answer”.

To view the statistics, run 

sudo rndc stats
  in order to dump the stats into the following file:
cat /var/cache/bind/named.stats
. The new statistics are always appended to this file and are listed between the following strings, while the number in brackets is the unixtime:
+++ Statistics Dump +++ (1471872885)
[...]
--- Statistics Dump --- (1471872885)

Great so far. 😉

Slave

The two slave servers are installed in the same way as the primary. The additional options should be the following (

sudo nano named.conf.options
 ):
// per zone statistics
	zone-statistics yes;

	// no recursion at all
	recursion no;

	// no transfer afxr by default
	allow-transfer { "none"; };

	// no NOTIFY to NS RRs
	notify no;

Note that it is REALLY crucial to put in these lines, at least the “allow-transfer none” one. Otherwise the zone is fully loadable through an axfr request. (A painful mistake is to only place this statement at the hidden primary but to forget it on the slave units.)

Now, the only portion to configure in order to be a slave is inside the named.conf.local file.

sudo nano named.conf.local

In my case, it only lists the following lines:

zone "weberdns.de" {
	type slave;
	file "db.weberdns.de";
	masters { 192.168.120.21; };
};

After a restart of the service (

sudo service bind9 restart
 ), everything is ready. Asking the localhost should work, e.g.:
dig @localhost mail.weberdns.de
.

The resource records are stored in the following path:

/var/cache/bind/
. Note that these files are not readable, but can be converted into a textfile with:
named-compilezone -f raw -j -F text -o ~/db.weberdns.de.txt weberdns.de /var/cache/bind/db.weberdns.de

This reads the raw database (-f raw) and includes the journal file (-j). It outputs text (-F text) into the file (-o outputfilename). With 

cat db.weberdns.de.txt
   you can see your RRs.

Parent Zone: Glue Records

To become the authoritative servers, the names and/or IP addresses of the nameservers must be configured at the parent zone, in my case the DENIC which is responsible for *.de. They offer a good online check for domain servers (Nameserver Predelegation Check Web Interface) which tests the nameservers to see if everything is accessible (firewalls with udp/tcp port 53) and configured correctly (SOA record values, …). In my case, this looks like that:

DENIC NAST Test weberdns.de

Since my NS servers for “weberdns.de” are called “ns1.weberdns.de” and “ns2.weberdns.de”, (which won’t be resolvable if only these FQDNs are known), the entries for these nameservers are stored with their glue records, i.e., the name and the IP addresses.

After this step was done, a whois for weberdns.de looks like:

weberjoh@jw-nb12:~$ whois weberdns.de

Domain: weberdns.de
Nserver: ns1.weberdns.de 2003:51:6012:110:0:0:a07:53 80.154.108.230
Nserver: ns2.weberdns.de 213.61.29.182
Status: connect
Changed: 2016-05-17T17:01:42+02:00

The Internet is now able to ask my two slave name servers for everything ending with .weberdns.de. Great again. This can easily be tested with dig +trace from any machine that has Internet access, e.g.:

dig www.weberdns.de +trace

Zone Transfers

At first, it is crucial to test that zone transfers of your servers are not available from the Internet. The Zone Transfer Online Test can be used for this purpose. This should fail because the “allow-transfer” options are already configured for both server types, master and slaves. Here is a sample of my domain:

Zone Transfer Online Test

Dig can be used to test the zone transfers, too, such as:

dig @ns1.weberdns.de weberdns.de axfr

Of course, this command will/must work if it is issued from one of the slaves and directed to the master, in my case:

dig @192.168.120.21 weberdns.de axfr

To authenticate the zone transfers, TSIG can be used. (This won’t be needed in my case, because I am already using private site-to-site VPNs for the connections between my servers. However. ;)) With TSIG, a shared secret is configured on any server pair (master to slave1, and master to slave2). Only if this “password” is present, the slave is able to transfer the zone. Note that this is not encryption (confidentiality), but only authentication.

At first, the keys must be generated. Note the last option which is the key-name, in this example case “key-ns1”:

dnssec-keygen -r /dev/urandom -a HMAC-SHA256 -b 256 -n HOST key-ns1

I am using two different keys for both slave servers. That is, I generated the following keys. Note that the key values in both files (*.key and *.private) are the same keys. (And no, these are not my actual keys, but only demos):

weberjoh@jw-nb12:~/temp$ dnssec-keygen -r /dev/urandom -a HMAC-SHA256 -b 256 -n HOST key-ns1
Kkey-ns1.+163+21468
weberjoh@jw-nb12:~/temp$ ls
Kkey-ns1.+163+21468.key  Kkey-ns1.+163+21468.private
weberjoh@jw-nb12:~/temp$ cat Kkey-ns1.+163+21468.key
key-ns1. IN KEY 512 3 163 32r25Nl7WKMw4AU0QSNC67NHsxE0ZNeJ+POe624fE2E=
weberjoh@jw-nb12:~/temp$ cat Kkey-ns1.+163+21468.private
Private-key-format: v1.3
Algorithm: 163 (HMAC_SHA256)
Key: 32r25Nl7WKMw4AU0QSNC67NHsxE0ZNeJ+POe624fE2E=
Bits: AAA=
Created: 20160519071805
Publish: 20160519071805
Activate: 20160519071805

weberjoh@jw-nb12:~/temp$ dnssec-keygen -r /dev/urandom -a HMAC-SHA256 -b 256 -n HOST key-ns2
Kkey-ns2.+163+35812
weberjoh@jw-nb12:~/temp$ cat Kkey-ns2.+163+35812.key
key-ns2. IN KEY 512 3 163 QZlvozBRA1dGQ2DlIRh90X7kryXjihuDntrl9hEjmD0=
weberjoh@jw-nb12:~/temp$ cat Kkey-ns2.+163+35812.private
Private-key-format: v1.3
Algorithm: 163 (HMAC_SHA256)
Key: QZlvozBRA1dGQ2DlIRh90X7kryXjihuDntrl9hEjmD0=
Bits: AAA=
Created: 20160519071831
Publish: 20160519071831
Activate: 20160519071831

On the master server, open the named.conf file and add both keys one for each slave, such as:

key key-ns1 {
        algorithm hmac-sha256;
        secret "32r25Nl7WKMw4AU0QSNC67NHsxE0ZNeJ+POe624fE2E=";
};

key key-ns2 {
        algorithm hmac-sha256;
        secret "QZlvozBRA1dGQ2DlIRh90X7kryXjihuDntrl9hEjmD0=";
};

Furthermore, open the named.conf.local and change the “allow-transfer” statement to only allow connections with these keys. The IP addresses from the servers must be omitted, for example, comment them out. Otherwise, connections from this IP addresses will still be possible without the key:

//      allow-transfer { 2003:51:6012:110::a07:53; 192.168.90.10; };
        allow-transfer { key key-ns1; key key-ns2; };

Same procedure on both slaves, of course only with the single needed key, e.g., key-ns1 and key-ns2. Furthermore, the “server” statement must be configured. Open the named.conf on the first slave, ns1, and add these lines:

key key-ns1 {
        algorithm hmac-sha256;
        secret "32r25Nl7WKMw4AU0QSNC67NHsxE0ZNeJ+POe624fE2E=";
};

server 2003:51:6012:120::a16:53 {
        keys { key-ns1; };
};

And similarly on ns2:

key key-ns2 {
        algorithm hmac-sha256;
        secret "QZlvozBRA1dGQ2DlIRh90X7kryXjihuDntrl9hEjmD0=";
};

server 192.168.120.21 {
        keys { key-ns2; };
};

Now, restart all bind services 

sudo service bind9 restart
  and you’re done.

A dig test w/o the key will not work anymore:

weberjoh@jw-vm07-ns1:~$ dig @192.168.120.21 weberdns.de axfr

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> @192.168.120.21 weberdns.de axfr
; (1 server found)
;; global options: +cmd
; Transfer failed.

But with the key (-y option), the zone transfer works again:

weberjoh@jw-vm07-ns1:~$ dig @192.168.120.21 -y hmac-sha256:key-ns1:32r25Nl7WKMw4AU0QSNC67NHsxE0ZNeJ+POe624fE2E= weberdns.de axfr

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> @192.168.120.21 -y hmac-sha256 weberdns.de axfr
; (1 server found)
;; global options: +cmd
weberdns.de.            3600    IN      SOA     ns1.weberdns.de. webmaster.weberdns.de. 2016051804 14400 1800 604800 180
weberdns.de.            3600    IN      NS      ns1.weberdns.de.
weberdns.de.            3600    IN      NS      ns2.weberdns.de.
weberdns.de.            3600    IN      MX      10 mail.weberdns.de.
[...]

Note the different syslog messages (captured on the slave) for the following three scenarios:

### Syslog Messages notify + zone transfer (w/o TSIG)
weberjoh@jw-nb13-ns2:~$ tail -100 /var/log/syslog | grep named
May 18 10:15:50 jw-nb13 named[2436]: client 192.168.120.21#55706: received notify for zone 'weberdns.de'
May 18 10:15:50 jw-nb13 named[2436]: zone weberdns.de/IN: Transfer started.
May 18 10:15:50 jw-nb13 named[2436]: transfer of 'weberdns.de/IN' from 192.168.120.21#53: connected using 192.168.90.10#58932
May 18 10:15:50 jw-nb13 named[2436]: zone weberdns.de/IN: transferred serial 2016051801
May 18 10:15:50 jw-nb13 named[2436]: transfer of 'weberdns.de/IN' from 192.168.120.21#53: Transfer completed: 1 messages, 14 records, 1408 bytes, 0.128 secs (11000 bytes/sec)

### Syslog with TSIG on the master but currently not on the slave
May 18 11:14:48 jw-nb13 named[2436]: client 192.168.120.21#22030: request has invalid signature: TSIG key-ns2: tsig verify failure (BADKEY)

### Syslog with TSIG correctly on both, master and slave. Note the "TSIG 'key-ns2'" statements:
May 18 11:30:39 jw-nb13 named[2928]: client 192.168.120.21#40015/key key-ns2: received notify for zone 'weberdns.de': TSIG 'key-ns2'
May 18 11:30:39 jw-nb13 named[2928]: zone weberdns.de/IN: Transfer started.
May 18 11:30:39 jw-nb13 named[2928]: transfer of 'weberdns.de/IN' from 192.168.120.21#53: connected using 192.168.90.10#34207
May 18 11:30:39 jw-nb13 named[2928]: zone weberdns.de/IN: transferred serial 2016051803: TSIG 'key-ns2'
May 18 11:30:39 jw-nb13 named[2928]: transfer of 'weberdns.de/IN' from 192.168.120.21#53: Transfer completed: 1 messages, 14 records, 1420 bytes, 0.141 secs (10070 bytes/sec)

Finally, here are some Wireshark screenshots for different notifies and zone transfers, with and without TSIG. See the descriptions beneath them for more details:

Zone Change Notification from the master to the slave. And the incremental zone transfer IXFR without TSIG. A complete zone transfer (tested with dig axfr) requires lots of messages. A zone transfer initiated from the slave with TSIG. Note the additional key record at the end.

That’s it. Hope this helps.

Links

Other BIND tutorials are here or here [DE]. The following links are more specific ones:

BIND DNSSEC Validation

$
0
0
dnssec-validation auto - featured image

If you are searching for a DNSSEC validating DNS server, you can use BIND to do that. In fact, with a current version of BIND, e.g. version 9.10, the dnssec-validation is enabled by default. If you are already using BIND as a recursive or forwarding/caching server, you’re almost done. If not, this is a very basic installation guide for BIND with DNSSEC validation enabled and some notes on how to test it.

I am using a fresh Ubuntu 16.04 LTS installation with BIND 9.10.3-P4, that is:

sudo apt-get update
sudo apt-get install bind9
sudo service bind9 start

The configuration files are stored in “/etc/bind/“. To allow DNS queries for the local clients, edit the options (

sudo nano named.conf.options
 ), add your subnets, e.g.:
allow-recursion { localhost; 192.168.0.0/16; 2003:51:6012:100::/56; };

and restart the server:

sudo service bind9 restart
.

DNSSEC by Default

The interesting part is that the DNSSEC validation is enabled by default. 😉 The “dnssec-validation auto;” option is already present and the “dnssec-enable yes;” option is not needed, because its default is already “yes”. (See here: DNS BIND Security Statements.)

Furthermore, the directory option is already present, too:

directory "/var/cache/bind";

That is, the managed keys are stored here:

/var/cache/bind/managed-keys.bind
.

Test with Dig

A basic test with dig against a DNSSEC secured domain will show the “ad” flag (authenticated data, see DNS Header Flags), in the header:

weberjoh@jw-nb12:~$ dig weberdns.de

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> weberdns.de
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 34885
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;weberdns.de.                   IN      A

;; AUTHORITY SECTION:
weberdns.de.            180     IN      SOA     ns1.weberdns.de. webmaster.weberdns.de. 2016051901 14400 1800 604800 180

;; Query time: 19 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Thu May 19 14:03:59 CEST 2016
;; MSG SIZE  rcvd: 90

More relevant, a failure in a DNSSEC secured domain will result in a SERVERFAIL without an answer:

weberjoh@jw-nb12:~$ dig sigfail.verteiltesysteme.net

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> sigfail.verteiltesysteme.net
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 64793
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sigfail.verteiltesysteme.net.  IN      A

;; Query time: 58 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Thu May 19 14:04:38 CEST 2016
;; MSG SIZE  rcvd: 57

To test (!) the failure, the cd flag (check disabled) can be sent with dig, which reveals the answer, but of course with the cd flag again and not with the ad flag in the answer:

weberjoh@jw-nb12:~$ dig sigfail.verteiltesysteme.net +cd

; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> sigfail.verteiltesysteme.net +cd
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39420
;; flags: qr rd ra cd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sigfail.verteiltesysteme.net.  IN      A

;; ANSWER SECTION:
sigfail.verteiltesysteme.net. 60 IN     A       134.91.78.139

;; Query time: 20 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Thu May 19 14:04:45 CEST 2016
;; MSG SIZE  rcvd: 197

 

Online Test for Clients

More interesting for the clients is an online test whether DNSSEC validation works or not. I am using the one at http://dnssec.vs.uni-due.de. If a client uses the just configured BIND server, the test looks like that:

DNSSEC Resolver Test ok

Congrats! You are now validating domain names.

Stats ‘n Cache

To view some statistics of BIND, execute the following shell command:

sudo rndc stats

This appends the statistics into this file:

/var/cache/bind/named.stats
. Note the “+++ Statistics Dump +++ (1471872885)” beginning of each new dump, while the number in brackets is the unixtime. In my case, for example, this looks like that:
+++ Statistics Dump +++ (1471872885)
++ Incoming Requests ++
              611719 QUERY
++ Incoming Queries ++
               64716 A
                   1 NS
                 131 SOA
              484641 PTR
                  22 MX
                  40 TXT
               61880 AAAA
                 279 SRV
                   9 ANY
++ Outgoing Queries ++
[View: default]
              140942 A
                  53 NS
                 110 CNAME
                 154 SOA
              143244 PTR
                  23 MX
                   2 TXT
              134638 AAAA
                 206 SRV
              104142 DS
               17265 DNSKEY
                   2 ANY
[View: _bind]
++ Name Server Statistics ++
              416710 IPv4 requests received
              195009 IPv6 requests received
                 328 requests with EDNS(0) received
                  33 TCP requests received
              609642 responses sent
                  46 truncated responses sent
                 328 responses with EDNS(0) sent
              479303 queries resulted in successful answer
               89521 queries resulted in authoritative answer
              509101 queries resulted in non authoritative answer
               29451 queries resulted in nxrrset
               11020 queries resulted in SERVFAIL
               89868 queries resulted in NXDOMAIN
              152697 queries caused recursion
                1881 duplicate queries received
                 196 queries dropped
              611686 UDP queries received
                  33 TCP queries received
++ Zone Maintenance Statistics ++
++ Resolver Statistics ++
[Common]
[View: default]
              363641 IPv4 queries sent
              177140 IPv6 queries sent
              346942 IPv4 responses received
              168436 IPv6 responses received
               24977 NXDOMAIN received
                4212 SERVFAIL received
                  32 FORMERR received
                 118 EDNS(0) query failures
               34758 truncated responses received
                2516 lame delegations received
               87670 query retries
               26471 query timeouts
               69897 IPv4 NS address fetches
               72415 IPv6 NS address fetches
                 870 IPv4 NS address fetch failed
               41590 IPv6 NS address fetch failed
              249786 DNSSEC validation attempted
              123250 DNSSEC validation succeeded
              125845 DNSSEC NX validation succeeded
                 177 DNSSEC validation failed
              180114 queries with RTT < 10ms
              223124 queries with RTT 10-100ms
              104360 queries with RTT 100-500ms
                5988 queries with RTT 500-800ms
                1457 queries with RTT 800-1600ms
                  83 queries with RTT > 1600ms
                  31 bucket size
                7363 REFUSED received
[View: _bind]
                  31 bucket size
++ Cache Statistics ++
[View: default]
             5706174 cache hits
                3570 cache misses
              996705 cache hits (from query)
              933523 cache misses (from query)
                   0 cache records deleted due to memory exhaustion
              414200 cache records deleted due to TTL expiration
               18385 cache database nodes
                8319 cache database hash buckets
            11143805 cache tree memory total
             7815275 cache tree memory in use
             8389020 cache tree highest memory in use
              655360 cache heap memory total
              263168 cache heap memory in use
              271360 cache heap highest memory in use
[View: _bind (Cache: _bind)]
                   0 cache hits
                   0 cache misses
                   0 cache hits (from query)
                   0 cache misses (from query)
                   0 cache records deleted due to memory exhaustion
                   0 cache records deleted due to TTL expiration
                   0 cache database nodes
                  64 cache database hash buckets
              287392 cache tree memory total
               29608 cache tree memory in use
               29608 cache tree highest memory in use
              262144 cache heap memory total
                1024 cache heap memory in use
                1024 cache heap highest memory in use
++ Cache DB RRsets ++
[View: default]
                4045 A
                5685 NS
                 102 CNAME
                3751 PTR
                1300 AAAA
                 455 DS
                3380 RRSIG
                1963 NSEC
                 301 DNSKEY
                   4 !A
                 214 !AAAA
                1135 !DS
                 240 NXDOMAIN
[View: _bind (Cache: _bind)]
++ ADB stats ++
[View: default]
                1021 Address hash table size
                4710 Addresses in hash table
                1021 Name hash table size
                3925 Names in hash table
[View: _bind]
                1021 Address hash table size
                1021 Name hash table size
++ Socket I/O Statistics ++
              341815 UDP/IPv4 sockets opened
              164252 UDP/IPv6 sockets opened
               21867 TCP/IPv4 sockets opened
               12897 TCP/IPv6 sockets opened
                   1 Raw sockets opened
              341813 UDP/IPv4 sockets closed
              164251 UDP/IPv6 sockets closed
               21866 TCP/IPv4 sockets closed
               12928 TCP/IPv6 sockets closed
                  36 UDP/IPv4 socket bind failures
                   6 UDP/IPv6 socket bind failures
                  21 TCP/IPv6 socket connect failures
              341777 UDP/IPv4 connections established
              164245 UDP/IPv6 connections established
               21699 TCP/IPv4 connections established
               12822 TCP/IPv6 connections established
                   3 TCP/IPv4 connections accepted
                  33 TCP/IPv6 connections accepted
                 252 UDP/IPv4 recv errors
                   1 TCP/IPv6 recv errors
                   2 UDP/IPv4 sockets active
                   1 UDP/IPv6 sockets active
                   6 TCP/IPv4 sockets active
                  35 TCP/IPv6 sockets active
                   1 Raw sockets active
++ Per Zone Query Statistics ++
--- Statistics Dump --- (1471872885)

To view the current cache of BIND, run the following command:

sudo rndc dumpdb -cache

This dumps the whole cache into this file:

/var/cache/bind/named_dump.db
.

It can be listed/grepped as normal, e.g.:

weberjoh@jw-vm08-int-dns:/var/cache/bind$ cat named_dump.db | grep ubuntu
ubuntu.com.             172675  NS      ns1.p27.dynect.net.
de.archive.ubuntu.com.  492     CNAME   ubuntu.mirror.tudos.de.
ntp.ubuntu.com.         475     A       91.189.89.198
security.ubuntu.com.    492     A       91.189.88.149
ubuntu.mirror.tudos.de. 10692   \-AAAA  ;-$NXRRSET
0.ubuntu.pool.ntp.org.  1371    \-AAAA  ;-$NXRRSET
1.ubuntu.pool.ntp.org.  1372    \-AAAA  ;-$NXRRSET
2.ubuntu.pool.ntp.org.  23      A       5.9.80.113
3.ubuntu.pool.ntp.org.  1374    \-AAAA  ;-$NXRRSET

 

Final notes: A much more detailed post about BIND as a caching server is here. And yes, I know that some security people don’t like the usage of BIND for a mere forwarding DNS server. The blog post about Unbound is coming soon. 😉 Cheers.

DNSSEC Validation with Unbound on a Raspberry

$
0
0
Unbound RPi featured image

To overcome the chicken-or-egg problem for DNSSEC (“I don’t need a DNSSEC validating resolver if there are no signed zones”), let’s install the DNS server Unbound on a Raspberry Pi for home usage. Up then, domain names are DNSSEC validated. I am listing the commands to install Unbound on a Raspberry Pi as well as some further commands to test and troubleshoot it. Finally I am showing a few Wireshark screenshots from a sample iterative DNS capture. Here we go:

It is really simple to operate an Unbound DNS resolver locally on a Raspberry Pi. Merely an installation and some config changes. That’s it. The Unbound package on a Raspbian Linux of Unbound validates DNSSEC by default. Great!

Installation

I am using an “old” Raspberry Pi 1 Model B with Raspbian GNU/Linux 7 (wheezy) and kernel 4.1.13+. The version of Unbound which comes with this OS is not the newest one (1.4.17-3+deb7u2), but it fits. The installation is really simple:

sudo apt-get update
sudo apt-get install unbound

The Unbound server starts automatically. Have look at the listening ports with:

pi@jw-pi01 ~ $ sudo netstat -tulpen | grep unbound
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      0          7312680     27897/unbound
tcp        0      0 127.0.0.1:8953          0.0.0.0:*               LISTEN      0          7312684     27897/unbound
tcp6       0      0 ::1:53                  :::*                    LISTEN      0          7312676     27897/unbound
tcp6       0      0 ::1:8953                :::*                    LISTEN      0          7312682     27897/unbound
udp        0      0 127.0.0.1:53            0.0.0.0:*                           0          7312678     27897/unbound
udp6       0      0 ::1:53                  :::*                                0          7312674     27897/unbound

Unbound works out of the box for queries from the localhost. In order to allow queries from any host, the configuration file must be edited. It is stored at

/etc/unbound/unbound.conf
 . Note that the config has already DNSSEC validation enabled!
pi@jw-pi01 /etc/unbound $ cat unbound.conf
# Unbound configuration file for Debian.
#
# See the unbound.conf(5) man page.
#
# See /usr/share/doc/unbound/examples/unbound.conf for a commented
# reference config file.

server:
    # The following line will configure unbound to perform cryptographic
    # DNSSEC validation using the root trust anchor.
    auto-trust-anchor-file: "/var/lib/unbound/root.key"

Now, to allow queries add the following lines within the “server:” paragraph:

interface: 0.0.0.0
interface: ::0
access-control: 0.0.0.0/0 allow
access-control: ::0/0 allow

check the config:

pi@jw-pi01 ~ $ unbound-checkconf
unbound-checkconf: no errors in /etc/unbound/unbound.conf

and restart the server:

pi@jw-pi01 ~ $ sudo service unbound restart
[ ok ] Restarting recursive DNS server: unbound.

That’s it! To see a list of all configuration options click here. If you only wanted to install Unbound you’re already done!

-> The following information are only for further analysis etc.

Root Hints & Root Key

Unbound uses a list of the root servers as well as the root dnskey for its DNSSEC validation. Both should be updated regularly to avoid DNS problems in case of real root server changes. To update and use the root-hints file (for the list of root-servers), download the official list:

sudo curl -o /etc/unbound/root.hints https://www.internic.net/domain/named.root

and use it within the unbound.conf configuration file:

root-hints: "/etc/unbound/root.hints"

To update the root.key, use the simple “unbound-anchor” program which downloads the root.key file into /etc/unbound/:

sudo unbound-anchor

And change the auto-trust-anchor-file within the unbound.conf from the default to:

auto-trust-anchor-file: "/etc/unbound/root.key"

Restart Unbound:

sudo service unbound restart
 .

Done. (Click here for more information about the root.hints etc.)

Tests & Status

Here’s a basic test from another Linux machine that queries the Unbound server. Note the ad flag in line 8 which indicates the DNSSEC validation:

pi@ntp1:~ $ dig @192.168.7.5 weberdns.de +noadditional +noauthority

; <<>> DiG 9.9.5-9+deb8u6-Raspbian <<>> @192.168.7.5 weberdns.de +noadditional +noauthority
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 43402
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;weberdns.de.                   IN      A

;; ANSWER SECTION:
weberdns.de.            3600    IN      A       80.154.108.230

;; Query time: 19 msec
;; SERVER: 192.168.7.5#53(192.168.7.5)
;; WHEN: Thu Jun 09 17:23:21 CEST 2016
;; MSG SIZE  rcvd: 186

Of course, a failure in DNSSEC leads to a SERVFAIL (line 7) without any answer:

pi@ntp1:~ $ dig @192.168.7.5 fail03.dnssec.works

; <<>> DiG 9.9.5-9+deb8u6-Raspbian <<>> @192.168.7.5 fail03.dnssec.works
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 42531
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;fail03.dnssec.works.           IN      A

;; Query time: 111 msec
;; SERVER: 192.168.7.5#53(192.168.7.5)
;; WHEN: Thu Jun 09 17:24:25 CEST 2016
;; MSG SIZE  rcvd: 48

Good.

In order to view the status of Unbound, use the following commands: 

unbound-control status
  and
unbound-control stats_noreset
 :
pi@jw-pi01 ~ $ sudo unbound-control status
version: 1.4.17
verbosity: 1
threads: 1
modules: 2 [ validator iterator ]
uptime: 11744 seconds
unbound (pid 28021) is running...
pi@jw-pi01 ~ $ sudo unbound-control stats_noreset
thread0.num.queries=120
thread0.num.cachehits=18
thread0.num.cachemiss=102
thread0.num.prefetch=0
thread0.num.recursivereplies=102
thread0.requestlist.avg=0.54902
thread0.requestlist.max=18
thread0.requestlist.overwritten=0
thread0.requestlist.exceeded=0
thread0.requestlist.current.all=0
thread0.requestlist.current.user=0
thread0.recursion.time.avg=0.201798
thread0.recursion.time.median=0.17367
total.num.queries=120
total.num.cachehits=18
total.num.cachemiss=102
total.num.prefetch=0
total.num.recursivereplies=102
total.requestlist.avg=0.54902
total.requestlist.max=18
total.requestlist.overwritten=0
total.requestlist.exceeded=0
total.requestlist.current.all=0
total.requestlist.current.user=0
total.recursion.time.avg=0.201798
total.recursion.time.median=0.17367
time.now=1465816919.018412
time.up=460.981236
time.elapsed=460.981236

To list the current values of options, e.g. the default values, use unbound-checkconf with the “-o parameter” option, such as:

pi@jw-pi01 ~ $ sudo unbound-checkconf -o use-syslog
yes
pi@jw-pi01 ~ $ sudo unbound-checkconf -o verbosity
1
pi@jw-pi01 ~ $ sudo unbound-checkconf -o do-ip6
yes
pi@jw-pi01 ~ $ sudo unbound-checkconf -o do-ip4
yes
pi@jw-pi01 ~ $ sudo unbound-checkconf -o do-udp
yes
pi@jw-pi01 ~ $ sudo unbound-checkconf -o do-tcp
yes

To dump the cache for further investigations, use this:

pi@jw-pi01 ~ $ sudo unbound-control dump_cache | less
pi@jw-pi01 ~ $ sudo unbound-control dump_cache | grep webernetz.net

Per default, the log messages are sent to syslog. That is, they are stored in the default /var/log/syslog file which can be followed with:

pi@jw-pi01 ~ $ tail -f /var/log/syslog | grep unbound

To increase the verbosity level, add/change the verbosity line in the unbound.conf file. The default is “1”. A level of “2” already logs every DNS request. Use it for troubleshooting but be careful with it!

verbosity: 2

All other details about the Unbound options are listed here.

DNS Server on LAN

To use this Unbound DNS server for all clients in the LAN, it must be announced via DHCP as the DNS server. In my home network I have an AVM FRITZ!Box router which connects to the Internet via FTTH. The settings are as follows. I am using the static IPv4 address as well as the link-local IPv6 address as the DNS server address:

IPv4 local DNS server. And IPv6, too.

Tested from another Raspberry Pi, this leads to the following resolv.conf entries:

pi@ntp1:~ $ cat /etc/resolv.conf
# Generated by resolvconf
domain fritz.box
nameserver 192.168.7.5
nameserver fe80::ba27:ebff:fec9:1637%eth0

This is a test from a Linux client. Once more, note the “ad” flag in line 7:

pi@ntp1:~ $ dig pa.weberdns.de +noadditional +noauthority

; <<>> DiG 9.9.5-9+deb8u6-Raspbian <<>> pa.weberdns.de +noadditional +noauthority
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 58151
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 5

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;pa.weberdns.de.                        IN      A

;; ANSWER SECTION:
pa.weberdns.de.         3592    IN      A       80.154.108.228

;; Query time: 10 msec
;; SERVER: 192.168.7.5#53(192.168.7.5)
;; WHEN: Thu Jun 09 16:45:47 CEST 2016
;; MSG SIZE  rcvd: 189

However, there are problems when querying the IPv6 address via the “-6” switch:

pi@ntp1:~ $ dig -6 dnssec.works

; <<>> DiG 9.9.5-9+deb8u6-Raspbian <<>> -6 dnssec.works
;; global options: +cmd
;; connection timed out; no servers could be reached

But it works when the link-local IPv6 address is specified (with the %eth0 interface suffix) directly:

pi@ntp1:~ $ dig @fe80::ba27:ebff:fec9:1637%eth0 dnssec.works +noadditional +noauthority

; <<>> DiG 9.9.5-9+deb8u6-Raspbian <<>> @fe80::ba27:ebff:fec9:1637%eth0 dnssec.works +noadditional +noauthority
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48062
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;dnssec.works.                  IN      A

;; ANSWER SECTION:
dnssec.works.           3600    IN      A       5.45.109.212

;; Query time: 71 msec
;; SERVER: fe80::ba27:ebff:fec9:1637%2#53(fe80::ba27:ebff:fec9:1637%2)
;; WHEN: Thu Jun 09 16:48:44 CEST 2016
;; MSG SIZE  rcvd: 113

So maybe it’s not a good idea to use the link-local address for the DNS server. Maybe I will disable the “IPv6 DNS Server” option in my home network since the availability of a legacy IP DNS server perfectly fits for dual-stacked clients.

And a web browser GUI test to http://dnssec.vs.uni-due.de looks like that:

DNSSEC Resolver Test okGreat!

Sample Wireshark Screenshots

This is a small tcpdump capture on the Raspberry Pi, displayed with Wireshark. It shows an iterative (!) lookup of “licher.de” with its initial request from the client to the Raspberry Pi, the iterative lookup and the final answer to the client. Also note the “Statistics -> DNS” summary within Wireshark which can be used for troubleshooting, too:

Initial request from the client. Iterative query (1). Iterative query (2). Reply to the client. Wireshark DNS Statistics.

Conclusion

Now, all DNS answers are DNSSEC validated. Really all DNS answer? Well, actually, no. Only those which are DNSSEC signed. However, we solved the chicken-egg problem and are now able to validate DNSSEC answers.

DNSSEC Signing w/ BIND

$
0
0
BIND DNSSEC Signing

To solve the chicken-or-egg problem for DNSSEC from the other side, let’s use an authoritative DNS server (BIND) for signing DNS zones. This tutorial describes how to generate the keys and configure the “Berkeley Internet Name Domain” (BIND) server in order to automatically sign zones. I am not explaining many details of DNSSEC at all, but only the configuration and verification steps for a concrete BIND server.

It is really easy to tell BIND to do the inline signing. With this option enabled, the admin can still configure the static database for his zone files without any relation to DNSSEC. Everything with signing and maintaining is fully done by BIND without any user interaction. Great.

Prerequisites

I am assuming that there is a working BIND server in place which is the authoritative name server for at least one zone. The BIND server must at least run with version 9.9! I am using an Ubuntu Server 14.04.4 LTS with BIND version 9.9.5-3ubuntu0.8-Ubuntu. A few days age I published a blog post covering the secure installation of BIND. Refer to it to see how. For this tutorial, I am using my test domain weberdns.de.

Furthermore, please read some general DNSSEC information on other sites, or simply google it and read the Wikipedia, DNSSEC.net, or RFC (4033, 4034, 4035) articles. I am assuming that you are already familiar with KSK & ZSK, RRSIG, DNSKEY, DS, NSEC & NSEC3. If not, come back again in two hours. 😉 Ok, in any case, here it is: DNSSEC signes zones with a private key (ZSK and KSK), while the public key is used to verify the signature. The signature for all resource records are stored in additional records, called RRSIG. The “Next SECure record” (NSEC) is used to prove that no entry exists between two other entries (NXDOMAIN).

Design and Keys

One thing to think about is the placement of the keys. The private keys (for both, the KSK as well as for the ZSKs) should NOT be accessible from the Internet. In the best way, a hardware security module (HSM) would be used for them. However, since this is not that trivial, the concept of a hidden primary can be used. With this way, the private keys are only stored on a not-accessible server, while only the slaves (which must not store the private keys) are queried from the Internet:

BIND Servers Master and Slaves

Another consideration is the usage of NSEC or NSEC3. For small zones that only store a few well-known names such as ns, www, and mail, NSEC can be used. (Remember the zone walking.) For complex zones with many hidden domain names, the usage of NSEC3 should be considered. However, note that “security through obscurity” is not a good design at all. 😉

BIND Configuration

We will first generate the keys followed by the configuration of BIND. A great (hence: small) tutorial is also available at ISC: Inline Signing in ISC BIND 9.9.0 — Examples. Note that I am using /dev/urandom for my key generation. If you are interested in more details, read this or that. And again, note that you must have at least BIND 9.9 for these features to work.

dnssec-keygen

First, create a new directory for the keys:

sudo mkdir /etc/bind/keys

And generate both, the KSK and the ZSK, within that newly created directory. I am using the RSASHA256 algorithm and 2048 bit for the KSK, while 1024 bit for the ZSK:

sudo dnssec-keygen -r /dev/urandom -a RSASHA256 -b 2048 -K /etc/bind/keys/ -f KSK -n ZONE weberdns.de
sudo dnssec-keygen -r /dev/urandom -a RSASHA256 -b 1024 -K /etc/bind/keys/ -n ZONE weberdns.de

Since BIND must be able to read the private key, change the permissions for the group (bind) to read the *.private files:

sudo chmod g+r *.private

Now, the /keys directory should look like that. Note that the private files are NOT readable from others:

weberjoh@jw-vm16-ns0:/etc/bind/keys$ ls -ahl Kweberdns*
-rw-r--r-- 1 root bind  431 May 20 09:46 Kweberdns.de.+008+57909.key
-rw-r----- 1 root bind 1012 May 20 09:46 Kweberdns.de.+008+57909.private
-rw-r--r-- 1 root bind  605 May 20 09:46 Kweberdns.de.+008+63202.key
-rw-r----- 1 root bind 1.8K May 20 09:46 Kweberdns.de.+008+63202.private

For example, my public KSK for weberdns.de looks like that:

weberjoh@jw-vm16-ns0:/etc/bind/keys$ cat Kweberdns.de.+008+63202.key
; This is a key-signing key, keyid 63202, for weberdns.de.
; Created: 20160205194002 (Fri Feb  5 20:40:02 2016)
; Publish: 20160205194002 (Fri Feb  5 20:40:02 2016)
; Activate: 20160205194002 (Fri Feb  5 20:40:02 2016)
weberdns.de. IN DNSKEY 257 3 8 AwEAAdQXI+UfqnGbHdwJtBBStf0CM8Q8nXcriaOysrpGEDNkM//amUBD 2YMWQ3g+htca6tmzfDJMM5D0gOk5d4IdEmdywkcH+0rGLjNiNEPFnZUp wb6XsYD+ZI/WEuSlp+KCEV8vwELq7VltABrFT+9Rz5CEvokTxonzQrvn fclVHaGwO7cglgALsFqJCqBpvDZvEr2Z6dSepjDnFC9BPS6V8PGSNwAY EtzDp/lrQojkCj28xHj2OCjpr0dIQjdjGFJTHIlc9cYTAHjdPDsC8Eqf s5HcL3ruU6cbqjTn+5Lm4RdXpOWVgemVvIGDnUN+v+Tma/WgtQk7U3sa izNJ3epCv3s=

[Note that I had some problems on Ubuntu with the keys for BIND. This post helped me to solve it. But I am not fully sure whether this is the best way:

sudo nano /etc/apparmor.d/usr.sbin.named

and changing the following line to this:

/etc/bind/** rw,

and a restart of apparmor:

sudo service apparmor restart
.]

named.conf.options & named.conf.local

It is really simple to tell BIND that it should sign its zones for the proper usage of DNSSEC. The first step is to set the key-directory and to enable dnssec. (Note that dnssec-enable is “yes” per default. However, I am adding the lines anyway.) Open the named.conf.options file:

sudo nano named.conf.options
and add the following two lines within the options { } section:
dnssec-enable yes;
        key-directory "/etc/bind/keys";

The second step is to configure the concrete zone to be signed and maintained. That is: BIND will 1) use the existing zone file and sign it in the background and 2) maintains the signed file in order to update any signatures once they expire.

Open the named.conf.local file in which the zones are declared:

sudo nano named.conf.local
and add the following two lines to the zone which should be signed:
auto-dnssec maintain;
        inline-signing yes;

That’s it!!

Reload the server in order to let BIND sign the zone:

sudo service bind9 reload
. The following command checks the correct signing, e.g.:
weberjoh@jw-vm16:/etc/bind$ sudo rndc signing -list weberdns.de
Done signing with key 57909/RSASHA256
Done signing with key 63202/RSASHA256

Note that you now have two more files within the /etc/bind/ directory, namely the *.signed and *.signed.jnl files. These are the real zone files that are presented to the world, while the original zone file is the file which is still edited by the admin:

weberjoh@jw-vm16-ns0:/etc/bind$ ls -ahl db.weberdns*
-rw-r--r-- 1 root bind 8.0K Aug 23 12:41 db.weberdns.de
-rw-r--r-- 1 bind bind  34K Aug 23 12:41 db.weberdns.de.jnl
-rw-r--r-- 1 bind bind  26K Aug 23 12:53 db.weberdns.de.signed
-rw-r--r-- 1 bind bind 387K Aug 23 12:41 db.weberdns.de.signed.jnl

 

KSK/DS to Parent Zone

In order to have the full DNS tree secured by DNSSEC, you must transfer your KSK or DS record to your registrar. They will sign it with their private key. This is the main part of DNSSEC because afterwards anyone in the world will be able to validate that you really own the private key for your zone.

If the registrar wants the DS record, obtain it from the KSK keys with the tool dnssec-dsfromkey, such as:

weberjoh@jw-vm16-ns0:/etc/bind/keys$ dnssec-dsfromkey Kweberdns.de.+008+63202.
weberdns.de. IN DS 63202 8 1 45B896D0F5735832203F18A600A605072596D368
weberdns.de. IN DS 63202 8 2 2F9112FF344BCDF9C6F9A7548F04184AAE73458C7150DE8FFFA3B7D9893C5EEE

If they want the whole public KSK, simply “cat” it from the keyfile, as already shown above (cat Kweberdns.de.+008+63202.key).

After the registrar has received and signed the KSK, it can be queried within the DNS. For the German DENIC, the KSK is also present in the whois query:

whois weberdns.de

Domain: weberdns.de
Nserver: ns1.weberdns.de 2003:51:6012:110:0:0:a07:53 80.154.108.230
Nserver: ns2.weberdns.de 213.61.29.182
Dnskey: 257 3 8 AwEAAdQXI+UfqnGbHdwJtBBStf0CM8Q8nXcriaOysrpGEDNkM//amUBD2YMWQ3g+htca6tmzfDJMM5D0gOk5d4IdEmdywkcH+0rGLjNiNEPFnZUpwb6XsYD+ZI/WEuSlp+KCEV8vwELq7VltABrFT+9Rz5CEvokTxonzQrvnfclVHaGwO7cglgALsFqJCqBpvDZvEr2Z6dSepjDnFC9BPS6V8PGSNwAYEtzDp/lrQojkCj28xHj2OCjpr0dIQjdjGFJTHIlc9cYTAHjdPDsC8Eqfs5HcL3ruU6cbqjTn+5Lm4RdXpOWVgemVvIGDnUN+v+Tma/WgtQk7U3saizNJ3epCv3s=
Status: connect
Changed: 2016-05-17T17:01:42+02:00

The DS record can be queried with a normal DNS request. In the following example, I am using the +trace and +dnssec options in order to see the DS returning from the parent zone (in my case .de) and to see some RRSIG signatures for all answers:

weberjoh@jw-nb12-lx:~$ dig weberdns.de ds +multi +dnssec +trace

; <<>> DiG 9.10.3-P4-Ubuntu <<>> weberdns.de ds +multi +dnssec +trace
;; global options: +cmd
.                       451618 IN NS i.root-servers.net.
.                       451618 IN NS d.root-servers.net.
.                       451618 IN NS l.root-servers.net.
.                       451618 IN NS g.root-servers.net.
.                       451618 IN NS h.root-servers.net.
.                       451618 IN NS j.root-servers.net.
.                       451618 IN NS b.root-servers.net.
.                       451618 IN NS e.root-servers.net.
.                       451618 IN NS c.root-servers.net.
.                       451618 IN NS a.root-servers.net.
.                       451618 IN NS m.root-servers.net.
.                       451618 IN NS f.root-servers.net.
.                       451618 IN NS k.root-servers.net.
.                       518356 IN RRSIG NS 8 0 518400 (
                                20160902050000 20160823040000 46551 .
                                C2NM1S7/NzZQDbx9H1tWLl1VotgaC0+YG0LtkW6Gfy5l
                                91WCLoK7RZJfl2joYyU4KnB/4/jRJhV4tbfvB4+GA7pp
                                c0V/v00KLipbCB+i39RFP5WVy9nlBgyXbqy8AqzJKnPH
                                BePme3m4q36RESbBxl3fENeoPPUWtO4/iSbxgsg= )
;; Received 397 bytes from 192.168.120.22#53(192.168.120.22) in 1 ms

de.                     172800 IN NS a.nic.de.
de.                     172800 IN NS f.nic.de.
de.                     172800 IN NS l.de.net.
de.                     172800 IN NS n.de.net.
de.                     172800 IN NS s.de.net.
de.                     172800 IN NS z.nic.de.
de.                     86400 IN DS 24220 8 2 (
                                FFE926ACA67ED94089390250F1F294AC84A6D84F9121
                                DF73A79E439F42E820C2 )
de.                     86400 IN DS 39227 8 2 (
                                AAB73083B9EF70E4A5E94769A418AC12E887FC3C0875
                                EF206C3451DC40B6C4FA )
de.                     86400 IN RRSIG DS 8 1 86400 (
                                20160901170000 20160822160000 46551 .
                                YNFLS/92zyUl+kiulpePRyyqc33LqbAO2PSCQvzBup+Q
                                5HfhS4KpoXPf7nuLB4BuVMGyjg0pmeFhqpk+yY7Ny8b1
                                UYoy3jTZ82z0Kx8pxTdkU/25cLBn7HHxGIakOupcd0cF
                                LpalPqLFzmvmWATy6G2CBRKj73mfCBFK4JEr9b0= )
;; Received 609 bytes from 2001:503:c27::2:30#53(j.root-servers.net) in 165 ms

weberdns.de.            86400 IN DS 63202 8 2 (
                                2F9112FF344BCDF9C6F9A7548F04184AAE73458C7150
                                DE8FFFA3B7D9893C5EEE )
weberdns.de.            86400 IN RRSIG DS 8 2 86400 (
                                20160830060000 20160823060000 56953 de.
                                pwtHpsI4NLVHDPP43PvQNJqZ0idkAMt0PACex8+d3et7
                                f2laUbWydCkQwlFymWl+UGelXBk249vENMPUdyb5p0Je
                                9juE0n+ruvf83YNXNjFoNjMloOwc7qDA0VB/tJr0o/kX
                                56dkBHzPM4Vba4fvOBXdp4IbM16u7PWXYeMxW50= )
;; Received 250 bytes from 194.246.96.1#53(z.nic.de) in 9 ms

In the same way, the dnskeys (KSK and ZSK) can be queried:

weberjoh@jw-nb12-lx:~$ dig weberdns.de dnskey +multi

; <<>> DiG 9.10.3-P4-Ubuntu <<>> weberdns.de dnskey +multi
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 44554
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;weberdns.de.           IN DNSKEY

;; ANSWER SECTION:
weberdns.de.            448 IN DNSKEY 256 3 8 (
                                AwEAAc1G9dfFSBL+/NxRd7//80J8Hx8hjUyaQ7oaJV0t
                                OErEc1+To0BGp3FOB7fQFQ6dJIHzfRD4YO0KoJjaH4P7
                                fWO6Qs+05U6dnf2BGPy91m/4LHqM+6jzFMMf566GHxuZ
                                YB/8OkKcyRU7IS+vubtYL8jT7hqzqg+XXpQbDRlbtNgP
                                ) ; ZSK; alg = RSASHA256; key id = 57909
weberdns.de.            448 IN DNSKEY 257 3 8 (
                                AwEAAdQXI+UfqnGbHdwJtBBStf0CM8Q8nXcriaOysrpG
                                EDNkM//amUBD2YMWQ3g+htca6tmzfDJMM5D0gOk5d4Id
                                EmdywkcH+0rGLjNiNEPFnZUpwb6XsYD+ZI/WEuSlp+KC
                                EV8vwELq7VltABrFT+9Rz5CEvokTxonzQrvnfclVHaGw
                                O7cglgALsFqJCqBpvDZvEr2Z6dSepjDnFC9BPS6V8PGS
                                NwAYEtzDp/lrQojkCj28xHj2OCjpr0dIQjdjGFJTHIlc
                                9cYTAHjdPDsC8Eqfs5HcL3ruU6cbqjTn+5Lm4RdXpOWV
                                gemVvIGDnUN+v+Tma/WgtQk7U3saizNJ3epCv3s=
                                ) ; KSK; alg = RSASHA256; key id = 63202

;; Query time: 1 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Tue Aug 23 10:27:18 CEST 2016
;; MSG SIZE  rcvd: 464

Tests (AD & RRSIG)

Now, lets check the correct signing of the DNSSEC secured zone. You must use a DNSSEC validating name server, such as BIND or Unbound, as I showed in the past two blog posts. If you do not have a validating server yourself, you can use the Google public DNS server at 2001:4860:4860::8888 or 8.8.8.8 because it already does validating DNSSEC answers. (Note that your authoritative server won’t ever reply with the “ad” flag, but only with the “aa” flag. This is by design. The authoritative server must not prove his own records, because he has direct access to the source and trusts it.)

The main part when using dig is the “ad” flag within the DNS answer. This indicates the “Authentic Data” being transferred. (Ref: IANA, DNS Header Flags.)

weberjoh@jw-nb12-lx:~$ dig mail.weberdns.de

; <<>> DiG 9.10.3-P4-Ubuntu <<>> mail.weberdns.de
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48243
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;mail.weberdns.de.              IN      A

;; ANSWER SECTION:
mail.weberdns.de.       3529    IN      A       80.154.108.237

;; Query time: 1 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Tue Aug 23 10:43:33 CEST 2016
;; MSG SIZE  rcvd: 61

In order to see the signatures (RRSIG), use dig with the +dnssec and +multi options. Now, the DNSSEC related information are displayed, as well as listed within multiple lines with some explanatory notes. Note that my domain name “mail.weberdns.de” has an A and an AAAA record. Therefore this example shows two answers along with two signatures:

weberjoh@jw-nb12-lx:~$ dig mail.weberdns.de any +dnssec +multi

; <<>> DiG 9.10.3-P4-Ubuntu <<>> mail.weberdns.de any +dnssec +multi
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 53578
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;mail.weberdns.de.      IN ANY

;; ANSWER SECTION:
mail.weberdns.de.       3505 IN RRSIG AAAA 8 3 3600 (
                                20160915070035 20160816062828 57909 weberdns.de.
                                UQCnmReXJ0jqU7u0frFR9Nj+vTPxlXB/k2h2yc9pNZht
                                GvhNYbRzvslI9P/XH1cBXphqs1YNSntMGcl/GDpR5ZK6
                                Mn0PN5LGJ+Q/SI/mVgZSSRrnFRaZn1/w0muAcintv8kq
                                Mkhh47WT2QJ2JAiaUcB8P3P/w2X57oeTr1hrawg= )
mail.weberdns.de.       3505 IN AAAA 2003:51:6012:110::15
mail.weberdns.de.       3451 IN RRSIG A 8 3 3600 (
                                20160915070035 20160816062828 57909 weberdns.de.
                                aOublailZ4XyYZEO5Wq1ucexwYrIs6LDjiwbav2wBRq1
                                ALNT4+0w6BqZ+so5xvYpH0bW9bHcXH+oJx7yUZEZi0Ka
                                IlrU96PvMKJGluqpZiuzS8jGhVQgKAfwLqKJOQzBB+4M
                                s21YkDAOu/oDiso42yP9GuFakK1JzZPhE5Z5t6Y= )
mail.weberdns.de.       3451 IN A 80.154.108.237

;; Query time: 1 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Tue Aug 23 10:44:51 CEST 2016
;; MSG SIZE  rcvd: 431

In both cases, note the AD flag.

Congratulations. You’re done. You have correctly secured your DNS zone!

Tools

There are some great online tools to verify the DNSSEC signatures. Have a look at DNSViz. It reveals and visualizes any DNS name, for example for mail.weberdns.de. Another tool is the DNSSEC Analyzer for iPhone. Here are two screenshots of these tools:

DNSViz. Great online visualizer for DNSSEC. DNSSEC Analyzer for iPhone from Verisign.

Further Reading

One key word that was not mentioned until now is: key rollover. I have only generated a single ZSK without any further expiration dates or following keys. In an upcoming blogpost I will show how to rollover the ZSK.

Furthermore, there are some cool things to come with DNSSEC: DANE and SSHFP, which I will cover in upcoming posts, too.

And keep in mind that you MUST have accurate date and time settings on your DNSSEC servers. If you’re drifting too much, all signatures will become invalid. Consider the usage of an own NTP server with different sources.

Some more links:

How to use DANE/TLSA

$
0
0
DANE featured image

DNS-based Authentication of Named Entities (DANE) is a great feature that uses the advantages of a DNSSEC signed zone in order to tell the client which TLS certificate he has to expect when connecting to a secure destination over HTTPS or SMTPS. Via a secure channel (DNSSEC) the client can request the public key of the server. This means, that a Man-in-the-Middle attack (MITM) with a spoofed certificate would be exposed directly, i.e., is not possible anymore. Furthermore, the trust to certificate authorities (CAs) is not needed anymore.

In this blog post I will show how to use DANE and its DNS records within an authoritative DNS server to provide enhanced security features for the public.

In my last posts I covered a secure installation of BIND as an authoritative DNS server, as well as the implementation of DNSSEC. This is really mandatory because without a signed DNS zone DANE would be useless. Though I am using BIND for the examples below, DANE can be used with any other DNS server, too.

What’s DANE?

The abstract of RFC 6698 “The DNS-Based Authentication of Named Entities (DANE) Transport Layer Security (TLS) Protocol: TLSA”, in which DANE is proposed, describes pretty good what DANE is: “Encrypted communication on the Internet often uses Transport Layer Security (TLS), which depends on third parties to certify the keys used. This document improves on that situation by enabling the administrators of domain names to specify the keys used in that domain’s TLS servers. This requires matching improvements in TLS client software, but no change in TLS server software.”

Today, a browser establishes a secure TLS connection to a known server (DNS name) with an “unkown” certificate (not proved by the end user). We are relying to certificate authorities (CAs), which once verified the certificate to be owned by the server operator. Unluckily, any (!) CA is able to sign every (!) certificate in the world, even if a certificate is NOT owned by the server itself, but by a malicious third party that wants to intercept the secure communication via a man-in-the-middle (MITM) attack.

With the new DNS resource record “TLSA”, the hashed public key is publicized within the DNS server of the same authority/entity that owns the TLS server, e.g., an HTTPS server or an SMTPS mail gateway. Now, an end user client can really validate that the server TLS certificate is owned by the same organization which owns the DNSSEC server. Hence, MITM attacks with spoofed certificates are not possible anymore.

For more information about DANE, refer to the RFCs: 6698, 7218, 7671, and 7672.

Generate TLSA Records

No changes must be made by the TLS servers. The only thing to do is to place the hashed public key into the DNS zone. For the most common scenarios, the fields within the TLSA record are the following (refer to RFC 7671, section 5.1):

  • Usage: 3 – DANE-EE: Domain Issued Certificate
  • Selector: 1 – SPKI: Use subject public key
  • Matching-Type: 1 – SHA-256

For an on-site generation of TLSA records the tool “tlsa” out of the “hash-slinger” toolkit can be used. On a Ubuntu server this works as follows:

weberjoh@jw-nb12-lx:~$ sudo apt-get install hash-slinger
weberjoh@jw-nb12-lx:~$ tlsa --create --selector 1 --certificate host-dane.weberdns.de.crt host-dane.weberdns.de
_443._tcp.host-dane.weberdns.de. IN TLSA 3 1 1 0d6fce3320315023ff499a3f3de1c362c88f8380311ac8c036890dab13243aa7

An easy to use online tool by Shumon Huque is here: Generate TLSA Record. Copy and paste your certificate, etc., and choose the selector field of “0 – Cert”:

Generate TLSA Records 01 Generate TLSA Records 02

In any way, the TLSA resource record for my test domain “host-dane.weberdns.de” is this:

_443._tcp.host-dane.weberdns.de. IN TLSA 3 1 1 0d6fce3320315023ff499a3f3de1c362c88f8380311ac8c036890dab13243aa7

This string must be placed into the appropriate zone file on the DNSSEC signing server, in my case “weberdns.de”. After then, I can manually test/request the TLSA record

_443._tcp. ...
  via DNS and can see that it is there authentic (AD flag):
weberjoh@jw-nb12-lx:~$ dig _443._tcp.host-dane.weberdns.de tlsa +dnssec +multi

; <<>> DiG 9.10.3-P4-Ubuntu <<>> _443._tcp.host-dane.weberdns.de tlsa +dnssec +multi
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59953
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;_443._tcp.host-dane.weberdns.de. IN TLSA

;; ANSWER SECTION:
_443._tcp.host-dane.weberdns.de. 3066 IN TLSA 3 1 1 (
                                0D6FCE3320315023FF499A3F3DE1C362C88F8380311A
                                C8C036890DAB13243AA7 )
_443._tcp.host-dane.weberdns.de. 3066 IN RRSIG TLSA 8 5 3600 (
                                20160929094014 20160830084014 57909 weberdns.de.
                                aZgVX1C6uxACoNnPo4m36CRzMjfe2Gk7pciV2knGrb5P
                                Hbq1UV/u2EdFJD6v5Dhd4JAquuM7OW9CQVfE1f0g380/
                                HsUMzg6eZeOr3sMR2ERZXv4hut4sikdtjGhVmA6jSbfg
                                EQFM0BELYz/+Xzh9uJYoqzkbJ54uKCpapaWgELs= )

;; Query time: 1 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Tue Aug 30 11:50:16 CEST 2016
;; MSG SIZE  rcvd: 278

 

Examples

I generated three different TLSA records for my test domains (IPv6-only):

  • host-dane.weberdns.de <- with a trusted CA signed certificate
  • host-dane-self.weberdns.de <- with a self-signed (!) certificate
  • mail.weberdns.de <- with a CA signed certificate whose FQDN is NOT mail.weberdns.de

The appropriate TLSA records are the following. Note that I have some different usage and matching type fields, e.g., SHA256 and SHA512:

_443._tcp.host-dane.weberdns.de.        IN TLSA 3 1 1 0d6fce3320315023ff499a3f3de1c362c88f8380311ac8c036890dab13243aa7
_443._tcp.host-dane-self.weberdns.de.   IN TLSA 3 1 1 97b57e11a9f07976ae0a44b3d68179e61637f3ca43b719a149f8d524c0dc2405
_443._tcp.host-dane-self.weberdns.de.   IN TLSA 3 1 2 bab6316ace46fdce7028ea0100c4c0c364dc2f092258f8958b9ab1bde89c73ade3bd37aebf54245268128b039114e760b6a0d79e366c8c0b396884ab4287a05a
_25._tcp.mail.weberdns.de.              IN TLSA 3 0 1 ae822a14fd5e56c213eeeb5d6755556980caf4c3f2531c1ec8eca3076f9b7e68

Note that in all three cases a TLSA check is valid though only the first TLS certificate is correctly signed by a trusted CA with its correct common name! This is the main advantage of DANE, that self-signed certificates can be used, even with incorrect names, as long as the certificate itself is the correct one published in the DNS.

Online Tools

There are great online tools for checking TLSA records either for HTTPS or for SMTPS:

Here a two sample screenshots out of the tools for my test domains. The “host-dane-self” domain is valid though self-signed, while the “mail.weberdns.de” is valid, too, though not congruent with the name of the certificate:

host-dane-self 03 Verification mail.weberdns.de DANE Validation

A more detailed view is the text output from Shumon’s SMTPS test with STARTTLS. It greatly shows the connection (via IPv4 and IPv6), the common name of the cert, as well as the matching TLSA record:

TLSA records found: 1
TLSA: 3 0 1 ae822a14fd5e56c213eeeb5d6755556980caf4c3f2531c1ec8eca3076f9b7e68

Connecting to IPv6 address: 2003:51:6012:110::15 port 25
recv: 220 mail.webertest.net ESMTP
send: EHLO cheetara.huque.com
recv: 250-mail.webertest.net
recv: 250-8BITMIME
recv: 250-SIZE 10485760
recv: 250 STARTTLS
send: STARTTLS
recv: 220 Go ahead with TLS
TLSv1.2 handshake succeeded.
Cipher: SSLv3 DHE-RSA-AES256-SHA
Peer Certificate chain:
 0 Subject CN: mail.webertest.net
   Issuer  CN: StartCom Class 2 IV Server CA
 1 Subject CN: StartCom Class 2 IV Server CA
   Issuer  CN: StartCom Certification Authority
 SAN dNSName: mail.webertest.net
DANE TLSA 3 0 1 [ae822a14fd5e...] matched EE certificate at depth 0
Validated Certificate chain:
 0 Subject CN: mail.webertest.net
   Issuer  CN: StartCom Class 2 IV Server CA
 SAN dNSName: mail.webertest.net

Connecting to IPv4 address: 80.154.108.237 port 25
recv: 220 mail.webertest.net ESMTP
send: EHLO cheetara.huque.com
recv: 250-mail.webertest.net
recv: 250-8BITMIME
recv: 250-SIZE 10485760
recv: 250 STARTTLS
send: STARTTLS
recv: 220 Go ahead with TLS
TLSv1.2 handshake succeeded.
Cipher: SSLv3 DHE-RSA-AES256-SHA
Peer Certificate chain:
 0 Subject CN: mail.webertest.net
   Issuer  CN: StartCom Class 2 IV Server CA
 1 Subject CN: StartCom Class 2 IV Server CA
   Issuer  CN: StartCom Certification Authority
 SAN dNSName: mail.webertest.net
DANE TLSA 3 0 1 [ae822a14fd5e...] matched EE certificate at depth 0
Validated Certificate chain:
 0 Subject CN: mail.webertest.net
   Issuer  CN: StartCom Class 2 IV Server CA
 SAN dNSName: mail.webertest.net

And by the way, for more information about DANE, have a look at the resources from “sys4”. They offer a DANE mailing list as well as a common mistakes help page.

Browser Add-On: DNSSEC/TLSA Validator

The only good browser plugin for checking DNSSEC and DANE records is the “DNSSEC/TLSA Validator“. Unluckily it is not updated since almost two years (as of October 2016) and I ran into some Firefox errors while this plugin was enabled.

However, for some tests it shows the status of the DNS name (first green icon) as well as the DANE/TLSA status (second green icon):

host-dane-self 04 DNSSEC Validator host-dane-self 05 DANE Validator

Problem: SSL Interception

One problem will arise if browsers do their own DANE check (which is unluckily not happening today) while organizations are using SSL/TLS interception at their firewalls/proxies. In these cases, the SSL man-in-the-middle “attack” will spoof the certificate to an own created one which is signed by the organizations CA. Though this CA is installed in the browsers, the TLSA check will fail. To my mind, the only way to accomplish this (while not stopping the MITM) is the creation of an “Island of Trust” for DNSSEC with real-time TLSA record spoofing. (Any other ideas?)

Conclusion

That was easy! With only some little DNS resource records, much more security, i.e., authentication, can be achieved. Browsers can access self-signed websites without relying on (malicious) CAs, and MTAs (mail transfer agents) can send mails with the usage of TLS directly to the correct (authentic) destinations.

Today (2016), we are still stuck in the chicken-or-egg problem: Only some sites have DNSSEC signed TLSA records while only some end systems (browsers, MTAs) can validate them. To overcome this problem: Start signing you DNS zones now and insert as many TLSA records as you can. 😉


SSHFP: Authenticate SSH Fingerprints via DNSSEC

$
0
0
SSHFP featured image

This is really cool. After DNSSEC is used to sign a complete zone, SSH connections can be authenticated via checking the SSH fingerprint against the SSHFP resource record on the DNS server. With this way, administrators will never get the well-known “The authenticity of host ‘xyz’ can’t be established.” message again. Here we go:

The Problem

If you are an SSH admin you definitely know the following message:

pi@ntp1:~ $ ssh lx.weberdns.de
The authenticity of host 'lx.weberdns.de (2003:51:6012:110::9)' can't be established.
ECDSA key fingerprint is 49:f7:d1:ea:2c:4c:f8:0a:5b:26:08:b2:ce:7d:bb:76.
Are you sure you want to continue connecting (yes/no)? ^C

You are connecting to an SSH server the first time and you get the “can’t be established” message. And we all know: Nobody ever checks this fingerprint against a manually distributed list of fingerprints… 😉 That is: If the first attempt to a new SSH server is spoofed by a man-in-the-middle attack (or a next-generation firewall with SSH decryption), you won’t recognize it!

The Solution: SSHFP

A technical solution to overcome this “whom can you trust” problem is the secure distribution of SSHFP (Secure Shell Key Fingerprints) within the Domain Name System (DNS). If the authoritative DNS server is signed via DNSSEC, the connecting SSH client can securely verify/authenticate the fingerprint of the SSH server it is connecting to.

The standard is defined in RFC 4255 “Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints” and RFC 6594 “Use of the SHA-256 Algorithm with RSA, Digital Signature Algorithm (DSA), and Elliptic Curve DSA (ECDSA) in SSHFP Resource Records” and RFC 7470 “Using Ed25519 in SSHFP Resource Records”. The DNS SSHFP Resource Record Parameters are listed by IANA.

The only required step is to distribute the SSH fingerprints within the DNS. To accomplish this, the fingerprints must be generated/listed on the SSH server itself via the ssh tool 

ssh-keygen -r name
. This lists the fingerprints for all available public key algorithms (RSA, DSA, ECDSA, Ed25519) in SHA1 and SHA256:
weberjoh@jw-nb12:~$ ssh-keygen -r lx
lx IN SSHFP 1 1 1449b6b574092366759d72c3617fd69b6093b22e
lx IN SSHFP 1 2 9ad79ecde76840aad6c07dddd8463f95f121029b94181786f6135fb817152835
lx IN SSHFP 2 1 cb0b8a83ab63f37d475a5b44f9558c96b65f4d91
lx IN SSHFP 2 2 5d1c30f734c6b1ffdc9f5c058245db7b15591855cab0149508f58bf65ddfafb9
lx IN SSHFP 3 1 0e91f83edce8bfc7c72d4e538c28d1bbcd66fb15
lx IN SSHFP 3 2 f4c7f572af9204a753f5842848743e8c18ba832b1cee8df7d979e1217006282f
lx IN SSHFP 4 1 df623280cbffce18f0bb37fc8864df51fd3d7e90
lx IN SSHFP 4 2 4e125c92d0c3bf6162b3b253ea49a167c129b606c778a1d5940bfdbab0ae8668

After these records are placed into the DNS server zone (and signed via DNSSEC), they can be queried and validated via DNSSEC. Note the “AD” flag for authentic data within the DNS header. There is only one RRSIG record since all SSHFP records are signed at once.

weberjoh@jw-nb12-lx:~$ dig lx.weberdns.de sshfp +dnssec +multi

; <<>> DiG 9.10.3-P4-Ubuntu <<>> lx.weberdns.de sshfp +dnssec +multi
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48421
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 9, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;lx.weberdns.de.                IN SSHFP

;; ANSWER SECTION:
lx.weberdns.de.         3589 IN SSHFP 1 1 (
                                1449B6B574092366759D72C3617FD69B6093B22E )
lx.weberdns.de.         3589 IN SSHFP 2 1 (
                                CB0B8A83AB63F37D475A5B44F9558C96B65F4D91 )
lx.weberdns.de.         3589 IN SSHFP 2 2 (
                                5D1C30F734C6B1FFDC9F5C058245DB7B15591855CAB0
                                149508F58BF65DDFAFB9 )
lx.weberdns.de.         3589 IN SSHFP 4 2 (
                                4E125C92D0C3BF6162B3B253EA49A167C129B606C778
                                A1D5940BFDBAB0AE8668 )
lx.weberdns.de.         3589 IN SSHFP 1 2 (
                                9AD79ECDE76840AAD6C07DDDD8463F95F121029B9418
                                1786F6135FB817152835 )
lx.weberdns.de.         3589 IN SSHFP 3 1 (
                                0E91F83EDCE8BFC7C72D4E538C28D1BBCD66FB15 )
lx.weberdns.de.         3589 IN SSHFP 4 1 (
                                DF623280CBFFCE18F0BB37FC8864DF51FD3D7E90 )
lx.weberdns.de.         3589 IN SSHFP 3 2 (
                                F4C7F572AF9204A753F5842848743E8C18BA832B1CEE
                                8DF7D979E1217006282F )
lx.weberdns.de.         3589 IN RRSIG SSHFP 8 3 3600 (
                                20160911095338 20160812085338 57909 weberdns.de.
                                p+r5oNKajiQXN/arL8nYtUCSGJ8kWOY/2ihxhNy/NOVB
                                MkOXQn6XI5+eEXzyl8S6y6rQ6Zc7cRXXlodyaaZGGPGc
                                vdtB+ooez7Nms2+q5t2qbpyjU/LJ9UF45iMc0cTMcJ6K
                                XuUNjjJ/pDLv8IJkURrYDSka3AGB2itdtAGdyd8= )

;; Query time: 1 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Tue Aug 30 13:58:50 CEST 2016
;; MSG SIZE  rcvd: 534

An SSH client that is configured to check the SSHFP record is now able to verify the fingerprint. If this client furthermore gets authentic data (DNSSEC validated “AD” flag), it will silently connect to the SSH server since it was able to authenticate the server. Great!

Tests

Currently, the 

VerifyHostKeyDNS
  option from the OpenSSH client is not enabled by default. That is, a connection to an unknown server will still result in the following message:
weberjoh@jw-vm08-rdns:~$ ssh lx.weberdns.de
The authenticity of host 'lx.weberdns.de (2003:51:6012:110::9)' can't be established.
ECDSA key fingerprint is SHA256:T09/p/ZSubnkraG3oslDMehfIiLRe6UiVn1dGZvtjZE.
Are you sure you want to continue connecting (yes/no)? ^C

But when used with the

-o VerifyHostKeyDNS=yes
  option, it will not warn about an unauthenticated server, because it IS authenticated now:
weberjoh@jw-vm08-rdns:~$ ssh -o VerifyHostKeyDNS=yes weberjoh@lx.weberdns.de
weberjoh@lx.weberdns.de's password:

Of course, this option can/should/must be set in the global ssh config, too:

sudo nano /etc/ssh/ssh_config
    VerifyHostKeyDNS yes

This is great at all! Customers that have many servers and firewalls placed around the world can now connect from a jump host to any of them without the fear of man-in-the-middle decrypted SSH sessions. Yeah.

Note that it is crucial that the DNS reply is DNSSEC validated. If not, OpenSSH will get the SSHFP record (“Matching host key fingerprint found in DNS.”) but will still warn such as:

pi@ntp2:~ $ ssh -o VerifyHostKeyDNS=yes weberjoh@lx.weberdns.de
The authenticity of host 'lx.weberdns.de (2003:51:6012:110::9)' can't be established.
ECDSA key fingerprint is 49:f7:d1:ea:2c:4c:f8:0a:5b:26:08:b2:ce:7d:bb:76.
Matching host key fingerprint found in DNS.
Are you sure you want to continue connecting (yes/no)? ^C

 

MD5, SHA256, Hex, Base64

What? “Why is the SSHFP fingerprint not the same as the log message from ssh?” This question took my a while to fully understand. And I am not the only one (click, click). In fact, there are several options to display fingerprints, e.g., with MD5, SHA256, either in hexadecimal or base64 notation. OpenSSH displays the fingerprint in MD5-hex or SHA256-base64 notation by default, whereas the SSHFP records list the SHA1 and SHA256 fingerprints, each in hex notation. That is: they are mutually exclusive. (Refer to OpenSSH/Cookbook/Authentication Keys. “The fingerprint can be forced to display as an MD5 hash in hexadecimal instead by passing FingerprintHash configuration directive as a runtime argument or in ssh_config. But the default is now SHA256 in base64. […] In OpenSSH 6.7 and earlier this fingerprint was a hexadecimal MD5 checksum instead a of the base64-encoded SHA256 checksum currently used.”)

The output of the fingerprint can be set to other hash algorithms, such as:

weberjoh@jw-vm08-rdns:~$ ssh -o FingerprintHash=sha256 lx.weberdns.de
The authenticity of host 'lx.weberdns.de (2003:51:6012:110::9)' can't be established.
ECDSA key fingerprint is SHA256:T09/p/ZSubnkraG3oslDMehfIiLRe6UiVn1dGZvtjZE.
Are you sure you want to continue connecting (yes/no)? ^C

Now, with some online tools, this SHA256 fingerprint can be converted from base64 to hex, which then compares to the SSHFP records. 😉 Uff.

What about PuTTY?

Unfortunately PuTTY is not supporting SSHFP yet. 🙁 It is on the wishlist a few years now, but still not supported. Of course this is bad since many admins are using Windows machines with PuTTY to manage Linux servers. However, if a central (Linux) jump server is used for connecting to all other servers/firewall/routers/whatever, SSHFP is still very useful.

As a small workaround I placed a TXT record for my Linux server on the DNS to be able to compare the fingerprint with the ssh message, such as:

pi@ntp1:~ $ host -t txt lx.weberdns.de
lx.weberdns.de descriptive text "ECDSA key fingerprint is 49:f7:d1:ea:2c:4c:f8:0a:5b:26:08:b2:ce:7d:bb:76"
pi@ntp1:~ $ ssh lx.weberdns.de
The authenticity of host 'lx.weberdns.de (2003:51:6012:110::9)' can't be established.
ECDSA key fingerprint is 49:f7:d1:ea:2c:4c:f8:0a:5b:26:08:b2:ce:7d:bb:76.
Are you sure you want to continue connecting (yes/no)? ^C

Of course this is no automatic security, but at least I can manually check whether I am talking to the correct server. (But, you know, I won’t…)

DNSSEC ZSK Key Rollover

$
0
0
"Keys" by Rosa Say is licensed under CC BY-NC-ND 2.0

One important maintenance requirement for DNSSEC is the key rollover of the zone signing key (ZSK). With this procedure a new public/private key pair is used for signing the resource records, of course without any problems for the end user, i.e., no falsified signatures, etc.

In fact it is really simply to rollover the ZSK with BIND. It is almost one single CLI command to generate a new key with certain time ranges. BIND will use the correct keys at the appropriate time automatically. Here we go:

Some Prenotes

clock
TISSOT PRC200” by tomo nosi is licensed under CC BY-NC-ND 2.0

It’s all about timing! A new ZSK must be present in the zone before (!) it signs resource records. Likewise it should remain in the zone even after it is not used anymore for some time.

The DNSSEC keys have four main dates stored within them, which are the following:

  • Publish: The time at which the key is public available in the zone
  • Activate: From this time on it is used to sign RRs
  • Inactive: No longer used to sign
  • Delete: Removed from the zone

The later on used CLI commands have the following options to specify these dates: -P, -A, -I, and -D, exactly matching the first letter of the descriptions above.

Let’s have a look at a common key rollover timing, i.e., a pre-publish phase of 1 month, while an active time of 3 months, followed by one more month (inactive) before it is deleted:

Timeline ZSK Key Rollover

Note that a new key is published in the last month of the active phase from the predecessor key. This enables all DNS resolvers to see the new key before it is actively used to sign data.

Time values are specified either discrete or with an offset: “Dates can be expressed in the format YYYYMMDD or YYYYMMDDHHMMSS. If the argument begins with a ‘+’ or ‘-‘, it is interpreted as an offset from the present time. For convenience, if such an offset is followed by one of the suffixes ‘y’, ‘mo’, ‘w’, ‘d’, ‘h’, or ‘mi’, then the offset is computed in years (defined as 365 24-hour days, ignoring leap years), months (defined as 30 24-hour days), weeks, days, hours, or minutes, respectively. Without a suffix, the offset is computed in seconds. To unset a date, use ‘none’.” (From the dnssec-settime manual.) Also note that all time values are in UTC!

dnssec-settime

To command line tool

dnssec-settime
  changes dates of existing keys. In a common scenario you have never rotated your ZSK before. That is: it has no inactive nor delete time set. But to rollover to a new ZSK (created later), the inactive and delete dates must be set. Use the -I and -D options on the existing ZSK key pair, e.g., to set the inactive date 4 month from now, while the delete date to 5 month from now:
dnssec-settime -I +4mo -D +5mo <key>

For example, I started with these values for my first ZSK from

weberdns.de
and “cat”ted the result. Note the activate and inactive dates:
weberjoh@jw-vm16-ns0:/etc/bind/keys$ sudo dnssec-settime -I +4mo -D +5mo Kweberdns.de.+008+57909
dnssec-settime: warning: Permissions on the file ./Kweberdns.de.+008+57909.private have changed from 0640 to 0600 as a result of this operation.
./Kweberdns.de.+008+57909.key
./Kweberdns.de.+008+57909.private
weberjoh@jw-vm16-ns0:/etc/bind/keys$ cat Kweberdns.de.+008+57909.key
; This is a zone-signing key, keyid 57909, for weberdns.de.
; Created: 20160205194924 (Fri Feb  5 20:49:24 2016)
; Publish: 20160205194924 (Fri Feb  5 20:49:24 2016)
; Activate: 20160205194924 (Fri Feb  5 20:49:24 2016)
; Inactive: 20161001134524 (Sat Oct  1 15:45:24 2016)
; Delete: 20161031134524 (Mon Oct 31 14:45:24 2016)
weberdns.de. IN DNSKEY 256 3 8 AwEAAc1G9dfFSBL+/NxRd7//80J8Hx8hjUyaQ7oaJV0tOErEc1+To0BG p3FOB7fQFQ6dJIHzfRD4YO0KoJjaH4P7fWO6Qs+05U6dnf2BGPy91m/4 LHqM+6jzFMMf566GHxuZYB/8OkKcyRU7IS+vubtYL8jT7hqzqg+XXpQb DRlbtNgP

That was the first step. Now let’s continue with the creation of new ZSKs:

dnssec-keygen -S

As in the first post about DNSSEC signing,

dnssec-keygen
  is used to create the keys. It has the great “-S <key>” option, described as: “Create a new key which is an explicit successor to an existing key. The name, algorithm, size, and type of the key will be set to match the existing key. The activation date of the new key will be set to the inactivation date of the existing one. The publication date will be set to the activation date minus the prepublication interval, which defaults to 30 days.” That is: referring to the last key, only the inactive and delete dates must be set to generate a new key, the publish and activate dates are set automatically. If using the “ZSK rollover every 3 month” approach while starting in 4 month from now on with the activation (due to inactivation of the first key with dnssec-settime), the -I and -D values must be incremented by 3, starting with 7 and 8:
weberjoh@jw-vm16-ns0:/etc/bind/keys$ sudo dnssec-keygen -S Kweberdns.de.+008+57909 -I +7mo -D +8mo -r /dev/urandom
Generating key pair.....++++++ ....................++++++
Kweberdns.de.+008+26703

That is: this new key

  • will be published in 3 months (that is: 1 month before the first key is “inactive”),
  • used in 4 month (because the first key is inactive in 4 month),
  • inactive in 7 month (set with -I, –> after the usage of 3 months), and
  • deleted in 8 month (set with -D, –> 1 month after inactive).

Refer to the timeline figure shown above. 😉 It helps!

And then keep on going creating new keys, each one using for 3 month, i.e., increment the I and D times by 3 such as:

sudo dnssec-keygen -S Kweberdns.de.+008+26703 -I +10mo -D +11mo
sudo dnssec-keygen -S Kweberdns.de.+008+41295 -I +13mo -D +14mo
sudo dnssec-keygen -S Kweberdns.de.+008+61119 -I +16mo -D +17mo

Create as much keys as you want, e.g., for 2-3 years. But NOTE: For the last key you are creating, don’t use the -I and -D options to have a lifetime of forever. This avoids the situation in which no key can be active anymore which would result in falsified (or even no) DNS signatures.

sudo dnssec-keygen -S Kweberdns.de.+008+07401

You should add a big reminder to your calendar to generate more keys when the old ones are inactive!

In my installation of BIND with DNSSEC signing, the *.private files must be readable by the group, so I adjusted the permissions with:

sudo chmod g+r *.private

The final step is to reload the keys for the zone:

sudo rndc loadkeys weberdns.de

Watch out the syslog entries whether BIND accepts and uses them, such as:

Sep  1 16:11:20 jw-vm16-ns0 named[1720]: received control channel command 'loadkeys weberdns.de'
Sep  1 16:11:20 jw-vm16-ns0 named[1720]: zone weberdns.de/IN (signed): reconfiguring zone keys
Sep  1 16:11:20 jw-vm16-ns0 named[1720]: zone weberdns.de/IN (signed): next key event: 01-Sep-2016 17:11:20.248

That’s it.

Examples

The following DNSViz graphs and dig listings show the process during my key rollover for weberdns.de. Refer to the descriptions below the graphs for more details:

Graph 1: The DNSKEY with id=57909 is used for all RRs. No other key is published yet. Graph 2: The new ZSK with id=26703 is published but not used yet. Graph 3: The new ZSK 26703 is used for some RRs (the SOA record) while the old 57909 ZSK has still valid signatures for other RRs. Graph 4: The old ZSK is deleted, the 26709 key signs almost all RRs, and a new ZSK with id=41295 is already present and active.

The same is true if querying the dnskeys with dig. For example, the following listing only shows the first ZSK with id = 57909:

weberjoh@jw-nb12-lx:~$ dig weberdns.de dnskey +multi

; <<>> DiG 9.10.3-P4-Ubuntu <<>> weberdns.de dnskey +multi
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54400
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;weberdns.de.           IN DNSKEY

;; ANSWER SECTION:
weberdns.de.            3591 IN DNSKEY 257 3 8 (
                                AwEAAdQXI+UfqnGbHdwJtBBStf0CM8Q8nXcriaOysrpG
                                EDNkM//amUBD2YMWQ3g+htca6tmzfDJMM5D0gOk5d4Id
                                EmdywkcH+0rGLjNiNEPFnZUpwb6XsYD+ZI/WEuSlp+KC
                                EV8vwELq7VltABrFT+9Rz5CEvokTxonzQrvnfclVHaGw
                                O7cglgALsFqJCqBpvDZvEr2Z6dSepjDnFC9BPS6V8PGS
                                NwAYEtzDp/lrQojkCj28xHj2OCjpr0dIQjdjGFJTHIlc
                                9cYTAHjdPDsC8Eqfs5HcL3ruU6cbqjTn+5Lm4RdXpOWV
                                gemVvIGDnUN+v+Tma/WgtQk7U3saizNJ3epCv3s=
                                ) ; KSK; alg = RSASHA256; key id = 63202
weberdns.de.            3591 IN DNSKEY 256 3 8 (
                                AwEAAc1G9dfFSBL+/NxRd7//80J8Hx8hjUyaQ7oaJV0t
                                OErEc1+To0BGp3FOB7fQFQ6dJIHzfRD4YO0KoJjaH4P7
                                fWO6Qs+05U6dnf2BGPy91m/4LHqM+6jzFMMf566GHxuZ
                                YB/8OkKcyRU7IS+vubtYL8jT7hqzqg+XXpQbDRlbtNgP
                                ) ; ZSK; alg = RSASHA256; key id = 57909

;; Query time: 1 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Thu Sep 01 16:35:25 CEST 2016
;; MSG SIZE  rcvd: 464

While a few days later the next ZSK with id = 26703 was published:

weberjoh@jw-nb12-lx:~$ dig weberdns.de dnskey +multi

; <<>> DiG 9.10.3-P4-Ubuntu <<>> weberdns.de dnskey +multi
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54177
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;weberdns.de.           IN DNSKEY

;; ANSWER SECTION:
weberdns.de.            3600 IN DNSKEY 257 3 8 (
                                AwEAAdQXI+UfqnGbHdwJtBBStf0CM8Q8nXcriaOysrpG
                                EDNkM//amUBD2YMWQ3g+htca6tmzfDJMM5D0gOk5d4Id
                                EmdywkcH+0rGLjNiNEPFnZUpwb6XsYD+ZI/WEuSlp+KC
                                EV8vwELq7VltABrFT+9Rz5CEvokTxonzQrvnfclVHaGw
                                O7cglgALsFqJCqBpvDZvEr2Z6dSepjDnFC9BPS6V8PGS
                                NwAYEtzDp/lrQojkCj28xHj2OCjpr0dIQjdjGFJTHIlc
                                9cYTAHjdPDsC8Eqfs5HcL3ruU6cbqjTn+5Lm4RdXpOWV
                                gemVvIGDnUN+v+Tma/WgtQk7U3saizNJ3epCv3s=
                                ) ; KSK; alg = RSASHA256; key id = 63202
weberdns.de.            3600 IN DNSKEY 256 3 8 (
                                AwEAAdAeTdXab14Qp3A8YjQUhu2DSkJwWC6X6Y8V4O34
                                UiRAxfXb3Z3zYIeMntyQIgSXrIiY60WW532O21borUfS
                                SReundoZiyq/GBLsPtXL1iQeLXT4QWWg9w2fg3y7Xde5
                                gzTswXazRIgMX8lqttmfIuZuU9qnWi2OoUCR5Pm2/rdj
                                ) ; ZSK; alg = RSASHA256; key id = 26703
weberdns.de.            3600 IN DNSKEY 256 3 8 (
                                AwEAAc1G9dfFSBL+/NxRd7//80J8Hx8hjUyaQ7oaJV0t
                                OErEc1+To0BGp3FOB7fQFQ6dJIHzfRD4YO0KoJjaH4P7
                                fWO6Qs+05U6dnf2BGPy91m/4LHqM+6jzFMMf566GHxuZ
                                YB/8OkKcyRU7IS+vubtYL8jT7hqzqg+XXpQbDRlbtNgP
                                ) ; ZSK; alg = RSASHA256; key id = 57909

;; Query time: 21 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Sun Sep 04 23:22:17 CEST 2016
;; MSG SIZE  rcvd: 612

 

How Often?

"Calendar*" by Dafne Cholet is licensed under CC BY 2.0
Calendar*” by Dafne Cholet is licensed under CC BY 2.0

How often should you rollover your ZSK? Well, it depends. The “use your ZSK for 3 month” opinion is quite conservative from my point of view. We are talking about 2048 bit crypto! This is used within TLS certificates that stay on the Internet for a couple of years.

You should rollover your ZSK on a regular basis to be prepared if your private key got lost. That is: to never rollover your keys is not a good advise. To my mind a good compromise is to rollover the ZSK every 6 month or 12 month. With this regularity you will practise key rollovers at least once a year while you have not that much burden.

Featured image: “Keys” by Rosa Say is licensed under CC BY-NC-ND 2.0.

DNSSEC with NSEC3

$
0
0
"Chain" by Astro is licensed under CC BY 2.0

By default DNSSEC uses the next secure (NSEC) resource record “to provide authenticated denial of existence for DNS data”, RFC 4034. This feature creates a complete chain of all resource records of a complete zone. While it has its usage to prove that no entry exists between two other entries, it can be used to “walk” through a complete zone, known as zone enumeration. That is: an attacker can easily gather all information about a complete zone by just using the designed features of DNSSEC.

For this reason NSEC3 was introduced: It constructs a chain of hashed and not of plain text resource records (RFC 5155). With NSEC3 enabled it is not feasible anymore to enumerate the zone. The standard uses a hash function and adds the NSEC3PARAM resource record to the zone which provides some details such as the salt.

In this post I will show how to create the KSK and ZSK keys that are NSEC3-capable and how to insert the NSEC3PARAM parameters to the zone. (For an introduction of DNSSEC with BIND refer to this blog post or note the DNSSEC category on my blog.) For now I am using another test domain:

sshfp.net
 . I will also show some dig commands for verifying the NSEC3 hashes.

NSEC3-Capable Algorithm

The first step to sign the zone is the creation of appropriate keys. The command line interface tool

dnssec-keygen
  provides the
-3
  option: “Use an NSEC3-capable algorithm to generate a DNSSEC key. If this option is used and no algorithm is explicitly set on the command line, NSEC3RSASHA1 will be used by default. Note that RSASHA256, RSASHA512, ECCGOST, ECDSAP256SHA256 and ECDSAP384SHA384 algorithms are NSEC3-capable.” I decided to use the RSASHA512 algorithm, so here are my commands for the generation of the KSK and the ZSK, as well as the correct permissions (refer to my lasts posts):
cd /etc/bind/keys/
sudo dnssec-keygen -a RSASHA512 -b 2048 -3 -f KSK -r /dev/urandom sshfp.net
sudo dnssec-keygen -a RSASHA512 -b 2048 -3 -r /dev/urandom sshfp.net
sudo chmod g+r *.private
sudo rndc loadkeys sshfp.net

(I also tried the algorithm number 14, ECDSAP384SHA384, but this did not work at all. rndc was not responding anymore. Maybe this is related to a bug in my BIND version?)

Note that up to this point the mere NSEC is still used for signing the zone. To enable NSEC3, follow the next step:

Adding the Salt

To tell the zone to use NSEC3, the NSEC3PARAM resource record must be inserted. This is done with

rndc signing -nsec3param
 : “rndc signing -nsec3param sets the NSEC3 parameters for a zone. […] Parameters are specified in the same format as an NSEC3PARAM resource record: hash algorithm, flags, iterations, and salt, in that order.”

There is only one registered hash function that is used for NSEC3, namely SHA1, refer to DNSSEC NSEC3 Hash Algorithms. (Why aren’t there any better hash functions yet? Short discussion here.) SHA1 has value number 1 listed within the nsec3param section. The flags parameter is left by 0. For the hash iterations I chose 10. (Some notes are here.) This sets the cost of computing a dictionary for the attacker, as well as the cost for signing the zone. To my mind 10 is a good starting point but it could be increased if needed.

"Kosher Salt" by stlbites.com is licensed under CC BY-ND 2.0
Kosher Salt” by stlbites.com is licensed under CC BY-ND 2.0

Finally, a salt must be set to prevent precomputed dictionary attacks. Choose a random salt, e.g., by using a password generator. Some other tutorials recommend a salt length of 8 hexadecimal digits, but it can be much longer. However, I used 8 digits, too. (“The salt SHOULD be at least 64 bits long and unpredictable, so that an attacker cannot anticipate the value of the salt and compute the next set of dictionaries before the zone is published”, RFC 5155 section 12.1.1.)

 

In the end this is my rndc command to use NSEC3 for my zone called “sshfp.net”:

sudo rndc signing -nsec3param 1 0 10 5053851B sshfp.net.

Without any other commands BIND is now using NSEC3 with the just defined parameters.

Test with Dig

The first step to test is the presence of the nsec3param record. Answer in line 15:

weberjoh@jw-nb12-lx:~$ dig sshfp.net nsec3param +noadditional +noauthority

; <<>> DiG 9.10.3-P4-Ubuntu <<>> sshfp.net nsec3param +noadditional +noauthority
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45143
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sshfp.net.                     IN      NSEC3PARAM

;; ANSWER SECTION:
sshfp.net.              0       IN      NSEC3PARAM 1 0 10 5053851B

;; Query time: 5 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Fri Nov 11 15:54:13 CET 2016
;; MSG SIZE  rcvd: 59

The more interesting test case is querying a non-existent domain. With mere NSEC, some plain text FQDNs would be revealed. Not so with NSEC3 which shows many (and long …) hashes, as well as the DNSSEC signatures (which are even longer in my case since I used the SHA512 hash for signing …):

weberjoh@jw-nb12-lx:~$ dig foobar.sshfp.net +dnssec

; <<>> DiG 9.10.3-P4-Ubuntu <<>> foobar.sshfp.net +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 24021
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 6, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;foobar.sshfp.net.              IN      A

;; AUTHORITY SECTION:
sshfp.net.              159     IN      SOA     ns1.weberdns.de. webmaster.weberdns.de. 2016090128 3600 900 2419200 180
sshfp.net.              159     IN      RRSIG   SOA 10 2 86400 20161208021634 20161108011634 31055 sshfp.net. kCY+TA1Q/RdjdzpMc1CHihGB+t4ou8QZPwuhzvkRkrYxicdXY320b+dO akTIcddJinI6dGo70OrRq+cWV9A9IAK7aak0Nonj/V20mHUzCVeaRrqp iBD1RjnKxNRqX5rb+fvf6S4NuzynGP57PWnntLqB/AnDljHcrBhN9IHe i87K0JsK/cmGzPCq9Dz50Tg4/7Pq3kI9p5pfdeRwLXyzIu4cb0BNIDvl MchVhTx/m44UbLdRlA9dzbZQuAZj5k5HqiDZFbwidK98w8AeMMbRy71P D16GvKnoIsOm3Ew+EcX0gCBWqcmccExm5zeiQkLf7KmDdDRVMvdd5uyK yZIE4w==
NA9D0NB498S0ROOIF2NGLHQF85HQLKJP.sshfp.net. 159 IN RRSIG NSEC3 10 3 180 20161207204758 20161107195347 31055 sshfp.net. GLqlvFaWiemLree+4WQeR+0ANSEYeuLW/KEWZw9mZPUJ1bcb1OQCxp43 7DNdPCSmS/RqJGiVGtSW8xsGoRgUwOdczL8s4j/z3pVi8wDlhw2jXE0k fGBiOshH+3VjZV4eLlDmDixZ3WmA9gzf0G+qAwRP9tjps2+vqRfXOpoj /UffmcMgZODEDGonHAOX/k35sBL+zIP4k6i6Kq/lpPZd8oxsxCwyxAYl E1oMxeE14TnRZoqCZdAEgvrViF91z/tnMbYAY/JNWYK4iREOuuWTLOox C0hKBsymi3fyLjwZ1NV1Bh3lqYN0rr1uo8ZSZmGrfLdg4l+hO4Xl6kG6 JTn27Q==
NA9D0NB498S0ROOIF2NGLHQF85HQLKJP.sshfp.net. 159 IN NSEC3 1 0 10 5053851B PF2TNEL79K4HTCBINCDBE9FPBU5I04KD A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM TYPE65534
PTBUDK4PK9HRK5HKTF5JVSULBP75V0AK.sshfp.net. 159 IN RRSIG NSEC3 10 3 180 20161208011815 20161108010731 31055 sshfp.net. h3TaJpQU9JXAMY7Eu4cjS28rdXxiPpm9VDjugpr71ilpSGo6UCowXaoE 44FMQWqRXj57yXrRyjFS2BDKBa6r5FIG5hM3jye04ksJxoT95ZgH9dVN wXf45oc/vh0v9BFaQi2a/7CFmTeUf36qaEdS1duTaQOMuV9fqLhQhzwQ nga40LIHCFqHJYmOPK2R41fn8VfpxD2fI95oCYCtLr6HQkmQ2uGWGSvF fxi+zAs0I1O5zyoc6JedbX7mFVs63/6B2Q9H9rYZbPnm92Py/OKTCR9Z kX1/6NA2DQZuTJKaZf7q/qKOdSmmkX7Np8Nc52Evdzw6yTFKT031SN8X L9UNWQ==
PTBUDK4PK9HRK5HKTF5JVSULBP75V0AK.sshfp.net. 159 IN NSEC3 1 0 10 5053851B 4B37B7ENKCCOB0IM83C004NA76LA3V4T A RRSIG

;; Query time: 1 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Fri Nov 11 15:58:09 CET 2016
;; MSG SIZE  rcvd: 1198

In fact, no other DNS leaves are revealed with this query. Great!

Changing the Salt

“The salt SHOULD be changed periodically to prevent pre-computation using a single salt”, RFC 5155 section C.1.

Ok, so let’s change the salt exemplary. This is really simple because it only requires the single rndc command I already showed. For this example I increased the size of the salt to 32 bytes (128 bits) as well as the hash iteration from 10 to 20:

sudo rndc signing -nsec3param 1 0 20 80637d8af055b5eeca2a621edaaa3c5e sshfp.net.

Without any problems BIND signed the complete zone with this new parameters. Here is the new nsec3param answer:

weberjoh@jw-nb12-lx:~$ dig sshfp.net nsec3param

; <<>> DiG 9.10.3-P4-Ubuntu <<>> sshfp.net nsec3param
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48904
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 3, ADDITIONAL: 4

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sshfp.net.                     IN      NSEC3PARAM

;; ANSWER SECTION:
sshfp.net.              0       IN      NSEC3PARAM 1 0 20 80637D8AF055B5EECA2A621EDAAA3C5E

;; AUTHORITY SECTION:
sshfp.net.              172800  IN      NS      ns1.weberdns.de.
sshfp.net.              172800  IN      NS      ns3.weberdns.de.
sshfp.net.              172800  IN      NS      ns2.weberdns.de.

;; ADDITIONAL SECTION:
ns1.weberdns.de.        86400   IN      A       80.154.108.230
ns1.weberdns.de.        86400   IN      AAAA    2003:51:6012:110::a07:53
ns2.weberdns.de.        86400   IN      A       213.61.29.182

;; Query time: 150 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Mon Nov 14 11:20:00 CET 2016
;; MSG SIZE  rcvd: 196

And the NSEC3 answer for a non-existent domain which also shows the new salt, etc. Note that some NXDOMAIN answeres have 3 different NSEC3 records, refer to RFC 7129, section 5 (a litte bit complicated though). Furthermore note that for the following listing I wrapped the lines in the output to see the whole big bunch of the answer 😉 :

weberjoh@jw-nb12-lx:~$ dig foobar.sshfp.net +dnssec

; <<>> DiG 9.10.3-P4-Ubuntu <<>> foobar.sshfp.net +dnssec
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 12968
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 8, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
;; QUESTION SECTION:
;foobar.sshfp.net.              IN      A

;; AUTHORITY SECTION:
sshfp.net.              180     IN      SOA     ns1.weberdns.de. webmaster.weberdns.de. 2016090133 3600 900 2419200 180
sshfp.net.              180     IN      RRSIG   SOA 10 2 86400 20161214101931 20161114091931 31055 sshfp.net. jh67fVaz7t9W5JGtgd+Ac3IxmT6hVVIHGzvzpikZ01ITZmtR6vE/A1/Y AZidYoTtSbVOO396cwewtMR+VjS8zP/LrYzZoKSmHVY7sqLYKhV7Cw/O xcDxwIo3/EWPSuu2xNzONGVwlZ9MPvFk7PIql7O1/mFNRNygP3oZWLIW 7yTEs28LRmFl/4l3jrFXGoZtk/IxaWCVONrqW0ThfUzppN1U6bSiFLkA PT2NajPPQaUoSHBME7PNy8fQMEUzijqfD1p+++KSQlChUN6ccedm0AXK 2Cf42k7g4zSPlDenSNYNWZ9M09Pl3Ctkw17LN0wYqqE70jtyR8Y9qVJ7 fNlqcA==
1009PRUOMI99TQ7NKVD75UH5KSVG82EV.sshfp.net. 180 IN RRSIG NSEC3 10 3 180 20161214094443 20161114091931 31055 sshfp.net. Z305JjP/bCNjuLhbgx0UheRQq0ZyZgzwYiy59D0Dnxb9NO3B/caVlM0S OnqM6zjkM+xpX8QGGMVrM4xVfya/4ajOFf7/c6CL03i0v+UQ6nyPcZ5j 17hpetBW1RpTkLXnpXTfaGtNYbBC4scMj41kU9Gxj2jophQ34dgcZkJ9 lBsLQjfKva1IQOyUTBrWVo8+zjj0k07P3n3ocEp3UXf62LZEurCaMmaM iQvOsWtVDOVjsI8lmQR3d3jelCuRkXBEa7tFfFsf0jWKZ6lbTLoSXGMz RQGKQqOy7yQUjxQbuQ6vBf+N6mAe0YGH56sm1+Z/SScgpnpTAviDF9nx rj4Sow==
1009PRUOMI99TQ7NKVD75UH5KSVG82EV.sshfp.net. 180 IN NSEC3 1 0 20 80637D8AF055B5EECA2A621EDAAA3C5E 3J6JP5RLFGU7E10AMBAKNT7UGEBP6IUI A RRSIG
F5AFOMBUT7BNO1I94Q43Q6F1KJAKEJB5.sshfp.net. 180 IN RRSIG NSEC3 10 3 180 20161214092455 20161114091931 31055 sshfp.net. nCAgLDaro/t1MixVVIg2ClnnGuZ8C8YVVt1VwKJWfJr7N8JFKILJGjkM GKvvRltQAfNtTpBmUYYwP7HXDISoL3X3ruM5PNZwBNjJ0x+E7LU9MCb7 uBhuoE9eKP69L9IGefUWzL5UZYW+T288V1bjayVNZi4UsZY7TwY2WDcJ Ef25HuvZskBooTgePf5+++kZti8Qm13rwh65jSSzQQPP2OjdwZJic1HP bwqGjnu2RzzxzSfHLQvyz9Xny43uT9IImZCSwTJW/bhsghhRiv79HK8o dPqWW+l5xqdbgTTwM9Rw52k6MboU+pD1z4HAFxEjZ5iq6H81WRZLfnOq ig59OA==
F5AFOMBUT7BNO1I94Q43Q6F1KJAKEJB5.sshfp.net. 180 IN NSEC3 1 0 20 80637D8AF055B5EECA2A621EDAAA3C5E QOERG35FBV9KBEKT0HHJ603KARPRHA6E A RRSIG
VLQ247QI8P1TT3A8CGMD7GLFNDTIGSDU.sshfp.net. 180 IN RRSIG NSEC3 10 3 180 20161214092455 20161114091931 31055 sshfp.net. f62YeWWFM9+d+jqVRJWVHkkgLL740EO6fCv5sQghuRCCJTzZbehRN365 3X5YNvOFvbZtR7i41SGV2+XXV5U8JgqzW0jc9+bw2k8lK2cQF/nfodLN RSoxymiqN6mNesEsb3ovCDTamB5gSCs7bj+iT7pS8NqtctkhTRYDPJAT lAId0H6cmL486msfeziU2fAelHx++Tc29II7PhYN87VOgtWQV02omkG1 Ysp8NCm4KQbuXQnXZ9aF6nFIIB70sA95kyND4dt0WNXkRwR0CUrv53sM X2Pvcop56jl3ssdgLqb79BlYU/dZrfhUjpLXfAXaRFp3jSvukSj9qcYu bsS6bQ==
VLQ247QI8P1TT3A8CGMD7GLFNDTIGSDU.sshfp.net. 180 IN NSEC3 1 0 20 80637D8AF055B5EECA2A621EDAAA3C5E 1009PRUOMI99TQ7NKVD75UH5KSVG82EV A NS SOA MX AAAA RRSIG DNSKEY NSEC3PARAM TYPE65534

;; Query time: 9 msec
;; SERVER: 192.168.120.22#53(192.168.120.22)
;; WHEN: Mon Nov 14 11:21:14 CET 2016
;; MSG SIZE  rcvd: 1614

That’s it. 😉 Good luck.

Links

Featured image: “Chain” by Astro is licensed under CC BY 2.0.

ntopng Installation

$
0
0
Some time ago I published a post introducing ntopng as an out-of-the-box network monitoring tool. I am running it on a Knoppix live Linux notebook with two network cards. However, I have a few customers that wanted a persistent installation of ntopng in their  environment. So this is a step-by-step tutorial on how to install … Continue reading ntopng Installation

FortiGate HA Cluster

$
0
0
This is a step-by-step tutorial for configuring a high availability cluster (active-standby) with two FortiGate firewalls. Since almost all firewall vendors have different principles for their HA cluster, I am also showing a common network scenario for Fortinet. I am using two FortiWiFi 90D firewalls with software version v5.2.5,build701. The official Fortinet documentation for “High … Continue reading FortiGate HA Cluster

CAA: DNS Certification Authority Authorization

$
0
0
I really like the kind of security features that are easy to use. The CAA “DNS Certification Authority Authorization” is one of those. As a domain administrator you must only generate the appropriate CAA records and you’re done. (Unlike other security features such as HPKP that requires deep and careful planning or DANE which is … Continue reading CAA: DNS Certification Authority Authorization

PGP Key Distribution via DNSSEC: OPENPGPKEY

$
0
0
What is the biggest problem of PGP? The key distribution. This is well-known and not new at all. What is new is the OPENPGPKEY DNS resource record that delivers PGP public keys for mail addresses. If signed and verified with DNSSEC a mail sender can get the correct public key for his recipient. This solves … Continue reading PGP Key Distribution via DNSSEC: OPENPGPKEY

SSHFP: FQDN vs. Domain Search/DNS-Suffix

$
0
0
This is actually a bad user experience problem: To generally omit the manual verification of SSH key fingerprints I am using SSHFP. With fully qualified domain names (FQDN) as the hostname for SSH connections such as [crayon-5a89e57f1c65b290806212-i/] this works perfectly. However, admins are lazy and only use the hostname without the domain suffix to connect … Continue reading SSHFP: FQDN vs. Domain Search/DNS-Suffix

Generating SSHFP Records Remotely

$
0
0
Until now I generated all SSHFP resource records on the SSH destination server itself via [crayon-5a89e57f1c0a5688208614-i/]. This is quite easy when you already have an SSH connection to a standard Linux system. But when connecting to third party products such as routers, firewalls, whatever appliances, you don’t have this option. Hence I searched and found … Continue reading Generating SSHFP Records Remotely

Signing a Delegated Subdomain

$
0
0
If you are already familiar with DNSSEC this is quite easy: How to sign a delegated subdomain zone. For the sake of completeness I am showing how to generate and use the appropriate DS record in order to preserve the chain of trust for DNSSEC. Scenario You already have a DNSSEC signed zone, in my … Continue reading Signing a Delegated Subdomain

DNSSEC KSK Key Rollover

$
0
0
Probably the most crucial part in a DNSSEC environment is the maintenance of the key-signing key, the KSK. You should rollover this key on a regular basis, though not that often as the zone signing keys, the ZSKs. I am doing a KSK rollover every 2 years. In the following I will describe the two … Continue reading DNSSEC KSK Key Rollover

DNSSEC KSK Emergency Rollover

$
0
0
In my last blogpost I showed how to perform a DNSSEC KSK rollover. I did it quite slowly and carefully. This time I am looking into an emergency rollover of the KSK. That is: What to do if your KSK is compromised and you must replace it IMMEDIATELY. I am listing the procedures and commands … Continue reading DNSSEC KSK Emergency Rollover
Viewing all 63 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>