From 8f99c858ec87966c0e9d107d681ff9d2c496f380 Mon Sep 17 00:00:00 2001 From: Cyberes Date: Thu, 22 Jun 2023 16:24:28 -0600 Subject: [PATCH] add check_dns_tls.py --- check_curl.sh | 2 +- check_dns_tls.py | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100755 check_dns_tls.py diff --git a/check_curl.sh b/check_curl.sh index b43b61a..ed34fdb 100755 --- a/check_curl.sh +++ b/check_curl.sh @@ -387,7 +387,7 @@ fi RESPONSE_TIME_MS=$(echo "$RESPONSE_TIME * 1000" | bc | xargs printf "%0.0f\n") -perfdata="response_time=${RESPONSE_TIME_MS}ms;${WARN_TIME};${CRIT_TIME};0;;" +perfdata="response_time=${RESPONSE_TIME_MS}ms;${WARN_TIME};${CRIT_TIME};0;" # Check response time if [ $(echo "$RESPONSE_TIME_MS > $CRIT_TIME" | bc) -eq 1 ]; then diff --git a/check_dns_tls.py b/check_dns_tls.py new file mode 100755 index 0000000..e7d0e65 --- /dev/null +++ b/check_dns_tls.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 + +import argparse +import sys +import time +import dns.query +import dns.message +import socket + +def resolve_dns_server_ip(server): + try: + ip_address = socket.getaddrinfo(server, None, family=socket.AF_INET)[0][4][0] + except socket.gaierror: + raise ValueError("Failed to resolve DNS server domain") + return ip_address + +def main(): + parser = argparse.ArgumentParser(description='Check DNS-over-TLS connectivity and response time') + parser.add_argument('-c', '--critical', type=float, default=0.5, help='Critical threshold for response time in seconds (default: 0.5)') + parser.add_argument('-w', '--warning', type=float, default=0.3, help='Warning threshold for response time in seconds (default: 0.3)') + parser.add_argument('-d', '--domain', type=str, default='google.com', help='Domain to resolve (default: google.com)') + parser.add_argument('-s', '--server', type=str, required=True, help='DNS server address') + parser.add_argument('-p', '--port', type=int, default=853, help='Port to use for DNS-over-TLS (default: 853)') + args = parser.parse_args() + + try: + server_ip = resolve_dns_server_ip(args.server) + except ValueError as e: + print(f'CRITICAL - {str(e)}') + sys.exit(2) + + error_message = None + query = dns.message.make_query(args.domain, dns.rdatatype.A) + start_time = time.time() + try: + response = dns.query.tls(query, server_ip, port=args.port, timeout=args.critical) + except dns.exception.SyntaxError: + error_message = "invalid IP address or domain name" + except dns.exception.Timeout: + error_message = "the DNS operation timed out" + except Exception as e: + error_message = e + + if error_message: + print(f'CRITICAL - DNS-over-TLS query failed: {error_message}') + sys.exit(2) + + + response_time = time.time() - start_time + response_time_ms = int(response_time * 1000) + + if response.rcode() != dns.rcode.NOERROR: + print(f'CRITICAL - DNS query returned error: {dns.rcode.to_text(response.rcode())}') + sys.exit(2) + + resolved_ips = [str(rr.address) for rr in response.answer[0] if rr.rdtype == dns.rdatatype.A] + perfdata = f'Resolved IPs: {", ".join(resolved_ips)} | response_time={response_time_ms}ms;{int(args.warning * 1000)};{int(args.critical * 1000)};0;' + + if response_time >= args.critical: + print(f'CRITICAL - DNS-over-TLS response time: {response_time:.2f} sec.') + sys.exit(2) + elif response_time >= args.warning: + print(f'WARNING - DNS-over-TLS response time: {response_time:.2f} sec.') + sys.exit(1) + else: + print(f'OK - DNS-over-TLS response time: {response_time:.2f} sec. {perfdata}') + sys.exit(0) + +if __name__ == '__main__': + main()