dnc

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

dnc (2774B)


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