daily system administration

Linux, Debian and the rest
any questions or comments: Tom@d7031.de

Checking DNS and DNSSEC with Icinga2

The new and very good Icinga2 has a new way to define and apply checks. At first it takes a litte bit more time to define the commands, but it’s much more flexible. I’ve running all my domains with DNSSEC on my own DNS-Servers. All zones are secured with OpenDNSSEC, so I’ve to check the signature.

The next step to secure my communication is using DANE, so I also have to check all my DANE-entries.

Steps to configure remote DNS-Monitoring with Icinga2

Download and install

  • Download and install the plugin for DNS and DNSSEC from GitHub monitoringplug and for DANE also form GitHub debfx.
  • Download my command definitions also from GitHub d7031 and save it inside your icinga2 config.

Configure your external monitoring system

Define some variables as arrays in the host configuration files for your outside server:

DNS checks

  vars.dns_domains["d7031.de"] = {
        dns_authoritative_address = "213.239.217.194"
        dns_authoritative_address6 = "2a01:4f8:a0:73c4::53"
        dns_authoritative_domain = "d7031.de"
        dns_sync_domain = "d7031.de"
        dnssec_expiration_domain = "d7031.de"
        dnssec_expiration_wtime = "5d"
        dnssec_expiration_ctime = "2d"
        dnssec_trace_domain = "d7031.de"
  }

  vars.dns_domains["outgrey.com"] = {
        dns_authoritative_address = "213.239.217.194"
        dns_authoritative_address6 = "2a01:4f8:a0:73c4::53"
        dns_authoritative_domain = "outgrey.com"
        dns_sync_domain = "outgrey.com"
        dnssec_expiration_domain = "outgrey.com"
        dnssec_expiration_wtime = "5d"
        dnssec_expiration_ctime = "2d"
        dnssec_trace_domain = "outgrey.com"
  }

You can group some variables in one like dns_domain = “d7031.de” and then assign this to your check variables, but that’s not so human readable in six months or so.

DANE checks

  vars.dane_hosts["www.d7031.de"] = {
        dane_hostname = "www.d7031.de"
        dane_port = 443
  }

  vars.dane_hosts["www.outgrey.com"] = {
        dane_hostname = "www.outgrey.com"
        dane_port = 443
  }

  vars.dane_hosts["mx0.d7031.de"] = {
        dane_hostname = "mx0.d7031.de"
        dane_port = 25
        dane_starttls = "smtp"
  }

  vars.dane_hosts["mx1.d7031.de"] = {
        dane_hostname = "mx1.d7031.de"
        dane_port = 25
        dane_starttls = "smtp"
  }

Define the DNS checks

apply Service "dns_authoritative-" for (dns_domains => config in host.vars.dns_domains) {
  import "generic-service"
  import "10-min-interval"

  check_command = "dns_authoritative"
  vars += config
  vars.dns_authoritative_noaxfr = true
  notes = "DNS authoritative checks for " + dns_domains
  assign where host.vars.dns_domains
}

apply Service "dns_sync-" for (dns_domains => config in host.vars.dns_domains) {
  import "generic-service"
  import "5-min-interval"

  check_command = "dns_sync"
  vars += config
  notes = "DNS sync checks for " + dns_domains
  assign where host.vars.dns_domains
}

Define the DNSSEC checks

apply Service "dnssec_expiration-" for (dns_domains => config in host.vars.dns_domains) {
  import "generic-service"
  import "12-hour-interval"

  check_command = "dnssec_expiration"
  vars += config
  notes = "DNSSEC expiration checks for " + dns_domains
  assign where host.vars.dns_domains
}

apply Service "dnssec_trace-" for (dns_domains => config in host.vars.dns_domains) {
  import "generic-service"
  import "10-min-interval"

  check_command = "dnssec_trace"
  vars += config
  notes = "DNSSEC trace checks for " + dns_domains
  assign where host.vars.dns_domains
}

Please take a look at the command definition file about root.dnskey !

Define the DANE checks

apply Service "dane-" for (dane_hosts => config in host.vars.dane_hosts) {
  import "generic-service"
  import "10-min-interval"

  check_command = "dns_dane"
  vars += config
  notes = "DANE checks for " + dane_hosts
  assign where host.vars.dane_hosts
}

That’s all, congratulations.

Tom