#!/usr/bin/env python # Add, remove or query IP addresses in DNSBL zone. # # Requires Debian package: python-dnspython import argparse import sys import dns.update import dns.query import dns.tsigkeyring import dns.resolver __author__ = "Niccolo Rigacci" __copyright__ = "Copyright 2020 Niccolo Rigacci " __license__ = "GPLv3-or-later" __email__ = "niccolo@rigacci.org" __version__ = "0.1.1" # Set your DNSBL zone, DNS server and key here: DNSBL_ZONE = 'bl.rigacci.org' DNS_HOSTNAME = 'ns1.rigacci.org' RNDC_KEY = {'bl-rigacci-org_rndc-key.' : 'rg2aizg+T6XkKkmpI42K7g=='} #--------------------------------------------------------------- #--------------------------------------------------------------- def main(): parser = argparse.ArgumentParser(description='Add, remove or query IP addresses in DNSBL zone.') group = parser.add_mutually_exclusive_group(required=True) group.add_argument('-a', '--add', metavar='ADDRESS', help='add address to the zone') group.add_argument('-r', '--remove', metavar='ADDRESS', help='remove address from the zone') group.add_argument('-q', '--query', metavar='ADDRESS', help='query for address in the zone') args = parser.parse_args() if args.query != None: address = args.query rev_address = '.'.join(reversed(address.split("."))) sys.exit(QueryDNS(rev_address, address)) elif args.add != None: address = args.add rev_address = '.'.join(reversed(address.split("."))) sys.exit(AddDNS(rev_address)) elif args.remove != None: address = args.remove rev_address = '.'.join(reversed(address.split("."))) sys.exit(DeleteDNS(rev_address)) #--------------------------------------------------------------- #--------------------------------------------------------------- def AddDNS(rev_address, value='127.0.0.1'): print('Adding type A record "%s" for %s.%s :' % (value, rev_address, DNSBL_ZONE)), keyring = dns.tsigkeyring.from_text(RNDC_KEY) update = dns.update.Update(DNSBL_ZONE, keyring = keyring, keyalgorithm = 'hmac-md5.sig-alg.reg.int') update.add(rev_address, 8600, 'A', value) response = dns.query.tcp(update, DNS_HOSTNAME) if response.rcode() == dns.rcode.NOERROR: print('NOERROR') return 0 elif response.rcode() == dns.rcode.REFUSED: print('REFUSED') return 1 else: print('Response: %s' % (response,)) return 2 def DeleteDNS(rev_address): print('Removing type A record %s.%s :' % (rev_address, DNSBL_ZONE)), keyring = dns.tsigkeyring.from_text(RNDC_KEY) update = dns.update.Update(DNSBL_ZONE, keyring = keyring, keyalgorithm = 'hmac-md5.sig-alg.reg.int') update.delete(rev_address, 'A') response = dns.query.tcp(update, DNS_HOSTNAME) if response.rcode() == dns.rcode.NOERROR: print('NOERROR') return 0 elif response.rcode() == dns.rcode.REFUSED: print('REFUSED') return 1 else: print('Response: %s' % (response,)) return 2 def QueryDNS(rev_address, address): query = rev_address + "." + DNSBL_ZONE resolver = dns.resolver.Resolver() resolver.timeout = 8 resolver.lifetime = 8 try: answers = resolver.query(query, 'A') a_record = answers[0] except: a_record = None if a_record != None: print("Address %s is listed as %s.%s => %s" % (address, rev_address, DNSBL_ZONE, a_record)) return 1 else: print("Address %s is not listed." % (address,)) return 0 #--------------------------------------------------------------- #--------------------------------------------------------------- if __name__ == '__main__': main()