dnc

CLI tool to check domain names configuration and statistics
Log | Files | Refs | README | LICENSE

dnc (2732B)


      1 #!/usr/bin/env python3
      2 
      3 #
      4 # dnc 0.2.0
      5 # Copyright (c) 2014-2021, Frederic Cambus
      6 # https://github.com/fcambus/dnc
      7 #
      8 # Created: 2014-02-11
      9 # Last Updated: 2021-02-24
     10 #
     11 # dnc is released under the BSD 2-Clause license.
     12 # See LICENSE file for details.
     13 #
     14 
     15 import getopt
     16 import socket
     17 import ssl
     18 import sys
     19 import OpenSSL
     20 import dns.resolver
     21 import textwrap
     22 from datetime import datetime
     23 from prettytable import PrettyTable
     24 
     25 socket.setdefaulttimeout(1)
     26 
     27 
     28 def usage():
     29     usage = """\
     30             dnc [-46hmnsv] domain
     31 
     32             The options are as follows:
     33 
     34             	-4	Resolve and display A records (IPv4 addresses).
     35             	-6	Resolve and display AAAA records (IPv6 addresses).
     36             	-h	Display usage.
     37             	-m	Resolve and display MX records (Mail Exchange).
     38             	-n	Resolve and display NS records (Name Servers).
     39             	-s	Display SSL/TLS certificate expiration date.
     40             	-v	Display version."""
     41 
     42     print(textwrap.dedent(usage))
     43 
     44 
     45 def query(domain: str, rrtype: str) -> str:
     46     try:
     47         answers = dns.resolver.resolve(domain, rrtype)
     48     except dns.exception.DNSException:
     49         return ""
     50 
     51     return "\n".join([rdata.to_text() for rdata in answers])
     52 
     53 
     54 def tls(domain: str, _: str) -> str:
     55     try:
     56         cert = ssl.get_server_certificate((domain, 443))
     57     except (socket.error, socket.timeout):
     58         return "No TLS"
     59 
     60     x509 = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, cert)
     61     return datetime.strptime(
     62         x509.get_notAfter().decode("ascii"), "%Y%m%d%H%M%SZ"
     63     ).strftime("%Y-%m-%d")
     64 
     65 
     66 def main():
     67     results = PrettyTable(hrules=1)
     68 
     69     header = ["Domain"]
     70     actions = []
     71 
     72     try:
     73         options, args = getopt.getopt(sys.argv[1:], "46hmnsv")
     74     except getopt.GetoptError as err:
     75         print(err)
     76         sys.exit(1)
     77 
     78     for option, arg in options:
     79         if option == "-4":
     80             header.append("IPv4")
     81             actions.append((query, "A"))
     82         if option == "-6":
     83             header.append("IPv6")
     84             actions.append((query, "AAAA"))
     85         if option == "-h":
     86             usage()
     87             sys.exit(0)
     88         if option == "-m":
     89             header.append("MX")
     90             actions.append((query, "MX"))
     91         if option == "-n":
     92             header.append("NS")
     93             actions.append((query, "NS"))
     94         if option == "-s":
     95             header.append("TLS")
     96             actions.append((tls, None))
     97         if option == "-v":
     98             print("dnc 0.2.0")
     99             sys.exit(0)
    100 
    101     results.field_names = header
    102     results.align = "l"
    103 
    104     for name in args:
    105         results.add_row([name] + [fn(name, action) for fn, action in actions])
    106 
    107     print(results)
    108 
    109 
    110 if __name__ == "__main__":
    111     main()