Skip to content

Instantly share code, notes, and snippets.

@fliphess
Created June 23, 2017 19:04
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fliphess/053209b5cb8d0cfa29df5b013eb22a19 to your computer and use it in GitHub Desktop.
Save fliphess/053209b5cb8d0cfa29df5b013eb22a19 to your computer and use it in GitHub Desktop.
Add dynamic DNS records to bind using nsupdate
#!/usr/bin/env python
from __future__ import print_function, absolute_import
import argparse
import os
import socket
import subprocess
import sys
KEY_FILE = "/etc/bind/update_dns.private"
BASE_STRING = "\nserver ns1.local\n"
def parse_arguments():
parser = argparse.ArgumentParser(description="Manage dns records")
parser.add_argument("--name", dest="name", type=str, required=True, help="The record to create")
parser.add_argument("--value", dest="value", type=str, required=True, help="The value (ip) of the record")
parser.add_argument("--ttl", dest="ttl", type=int, default=300, help="The TTL of the record")
parser.add_argument("--type", dest="type", type=str, default="A", help="The type of record to create")
parser.add_argument("--create", dest="create", action="store_true", default=False, help="Add a DNS record")
parser.add_argument("--rm", dest="remove", action="store_true", default=False, help="Remove a DNS record")
parser.add_argument("--reverse", dest="reverse", action="store_true", default=False, help="Add a reversed DNS record too")
arguments = parser.parse_args()
if all((arguments.create, arguments.remove)):
parser.error("You can't use --rm and --create together.")
if not KEY_FILE or not os.path.isfile(KEY_FILE):
parser.error('Key file {} not found!'.format(KEY_FILE))
arguments.key_file = KEY_FILE
return arguments
def run_nsupdate(command_string):
try:
subprocess.check_call("echo '{}' | /usr/bin/nsupdate -k {} /dev/stdin".format(command_string, KEY_FILE), shell=True)
except subprocess.CalledProcessError as e:
print("Failed to run nsupdate: {}".format(e), file=sys.stderr)
def remove_record(rtype, name):
command = BASE_STRING + "update delete {} {}\nsend\n".format(name, rtype)
return run_nsupdate(command_string=command)
def add_record(rtype, name, value, ttl):
command = BASE_STRING + "update add {} {} {} {}\nsend\n".format(name, ttl, rtype, value)
return run_nsupdate(command_string=command)
def get_arpa(ip):
try:
return socket.gethostbyaddr(ip)[1][0]
except (socket.error, IndexError, ValueError):
return None
if __name__ == "__main__":
arguments = parse_arguments()
arpa_record = get_arpa(ip=arguments.value)
remove_record(name=arguments.name, rtype=arguments.type)
if arpa_record and arguments.reverse:
remove_record(name=arpa_record, rtype="PTR")
if arguments.create:
add_record(rtype="A", name=arguments.name, value=arguments.value, ttl=arguments.ttl)
if arguments.reverse:
add_record(rtype="PTR", name=arpa_record, value=arguments.name, ttl=arguments.ttl)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment