Nach einer Umstellung an meinem DNS-Cluster ist mir ein Icinga Alarm aufgefallen, der mir meldet, dass einer der Nodes sporadisch nicht auf DNS-Anfragen reagiert. Eine manuelle Prüfung ergab jeweils, dass der Server aber erreichbar war. Viellleicht ein kurzer Packet Loss? Ich konnte aber keinen direkten Zusammenhang mit ab und zu auftretenden Paketverlusten feststellen.

Konkret sah das wie folgt aus:

/usr/lib/nagios/plugins/check_dns -s 2001:DB8::53 -H monitoring.example.com -a 127.0.0.1 -A
DNS CRITICAL - expected '127.0.0.1' but got ''

dig +short @2001:DB8::53 monitoring.example.com
127.0.0.1

Und ja, praktisch direkt hintereinander. Was mir dann aufgefallen ist: im Icinga2 Check gebe ich nicht extra an, dass ich den A record haben will. Nachdem ich das im Check geforced habe, kommt ein anderer Fehler:

/usr/lib/nagios/plugins/check_dns -s 2001:DB8::53 -H monitoring.example.com -a 127.0.0.1 -A -q A
/usr/lib/nagios/plugins/check_dns: invalid option -- 'q'
Usage:
check_dns -H host [-s server] [-a expected-address] [-A] [-t timeout] [-w warn] [-c crit]

Wie bitte? Der kennt -q nicht? Ich verwende für Icinga2 Ubuntu Bionic. Dort gibt es monitoring-plugins, aber nicht nagios-plugins als Paket. Kann das den Unterschied ausmachen? Also mal selber compilieren:

wget https://github.com/nagios-plugins/nagios-plugins/releases/download/release-2.2.1/nagios-plugins-2.2.1.tar.gz
tar xvzf nagios-plugins-2.2.1.tar.gz
make
make install

/usr/local/nagios/libexec/check_dns -s 2001:DB8::53 -H monitoring.example.com -a 127.0.0.1 -A -q A
DNS OK: 0.062 seconds response time. monitoring.example.com returns 127.0.0.1|time=0.061654s;;;0.000000

Ja, so ist der Fehler weg. Warum die Pakete eigentlich seit 2017 die -q Option haben, aber nicht die in Ubuntu ist mir ein komplettes Rätsel. Die Icinga2 Dokumentation erwähnt ja extra dns_query_type.

Nun muss ich nur noch ein neues Check Kommando definieren, dass auf das selbst compilierte check_dns zeigt:

object CheckCommand "self-compiled-dns" {
        import "ipv4-or-ipv6"

        command = [ "/usr/local/nagios/libexec/check_dns" ]

        arguments = {
                "-H" = {
                        value = "$dns_lookup$"
                        description = "The name or address you want to query."
                }
                "-s" = {
                        value = "$dns_server$"
                        description = "Optional DNS server you want to use for the lookup."
                }
                "-q" = {
                        value = "$dns_query_type$"
                        description = "Optional DNS record query type where TYPE =(A, AAAA, SRV, TXT, MX, ANY). The default query type is 'A' (IPv4 host entry)"
                }
                "-a" = {
                        value = "$dns_expected_answers$"
                        description = "Optional ip address or host you expect the DNS server to return. Host must end with a dot (.). This option can be repeated multiple times (Returns OK if any value match). If multiple addresses are returned at once, you have to match the whole string of addresses separated with commas (sorted alphabetically)."
                }
                "-A" = {
                        set_if = "$dns_authoritative$"
                        description = "Optionally expect the DNS server to be authoritative for the lookup"
                }
                "-n" = {
                        set_if = "$dns_accept_cname$"
                        description = "Optionally accept cname responses as a valid result to a query. The default is to ignore cname responses as part of the result"
                }
                "-w" = {
                        value = "$dns_wtime$"
                        description = "Return warning if elapsed time exceeds value."
                }
                "-c" = {
                        value = "$dns_ctime$"
                        description = "Return critical if elapsed time exceeds value."
                }
                "-t" = {
                        value = "$dns_timeout$"
                        description = "Seconds before connection times out. Defaults to 10."
                }
        }

        vars.dns_lookup = "$host.name$"
        vars.dns_timeout = 10
}

Fertig. Problem gelöst. Warum das überhaupt nötig war, verstehe ich aber immer noch nicht.