Add update_mikrotik_dns.py
This commit is contained in:
138
update_mikrotik_dns.py
Normal file
138
update_mikrotik_dns.py
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
#! /usr/bin/python
|
||||||
|
#
|
||||||
|
# update_dns.py - Update DNS static entries on your Mikrotik Router(s) using this python script.
|
||||||
|
# Copyright (C) 2021 WILDERNETS LLC, Distributed under GPL-3.0, GNU General Public License v3.0 only
|
||||||
|
#
|
||||||
|
# How it works:
|
||||||
|
# - Grab a copy of the master host table off the host table server.
|
||||||
|
# - Get existing DNS static entries from a list of Mikrotik routers.
|
||||||
|
# - Compare entries to the master host table
|
||||||
|
# - Issue add/set/remove commands as needed to update the Mikrotik DNS entries.
|
||||||
|
#
|
||||||
|
# Setup Notes:
|
||||||
|
# - Setup DNS server on your mikrotik router(s)
|
||||||
|
# - Run this on a trusted secure system so you don't have to trust the host master with access to your router(s).
|
||||||
|
# - OR just Comment out Step0 and run from the machine that has the host master file.
|
||||||
|
# - Setup password-less ssh to the host master machine.
|
||||||
|
# - Setup password-less ssh to your router(s).
|
||||||
|
# - Adv Topic: consider setting up a portable subnet/IP for your router so you can implement DNS server redundancy.
|
||||||
|
# (I use 10.10.10.10 on two routers and 10.10.10.1 on two routers and inject these as /32 into OSPF)
|
||||||
|
#
|
||||||
|
# Requirements:
|
||||||
|
# - Setup password-less SSH using keys to the machine that hosts the master copy of the host table
|
||||||
|
# - Setup password-less SSH using keys to the router that act as DNS servers
|
||||||
|
# - Change the Script vars listed below
|
||||||
|
# - Test on a non-production router
|
||||||
|
#
|
||||||
|
# Coding Notes:
|
||||||
|
# - Hosts file parsed into two master dictionaries.
|
||||||
|
# - For each router updated a working copy is made of these two masters.
|
||||||
|
# - As hosts are processed they are deleted from the dictionary copy.
|
||||||
|
# - Next router updated gets a brand new copy from the master.
|
||||||
|
#
|
||||||
|
import re # strip comments
|
||||||
|
import sys # system stuff
|
||||||
|
import subprocess # Popen command
|
||||||
|
import os # Execute scp command
|
||||||
|
|
||||||
|
# Script vars
|
||||||
|
#HOSTMASTER = "nismaster:etc/hosts"
|
||||||
|
#HOSTMASTER = "/etc/hosts"
|
||||||
|
HOSTSFILE = "/root/hosts.txt"
|
||||||
|
SSHCMD = "/ip dns static export"
|
||||||
|
routerlist = ['10.87.2.1']
|
||||||
|
routeruser = "dnsupdate"
|
||||||
|
debug = 1
|
||||||
|
|
||||||
|
# Step0 Go Grab latest hosts file
|
||||||
|
#print "# Getting hosts file: scp "+HOSTMASTER+" "+HOSTSFILE
|
||||||
|
#os.system("scp "+HOSTMASTER+" "+HOSTSFILE)
|
||||||
|
|
||||||
|
#os.system("cp "+HOSTMASTER+" "+HOSTSFILE)
|
||||||
|
|
||||||
|
# Step1 Open hosts file, parse and check for duplicates
|
||||||
|
if debug: print("# Verifying hostsfile: "+HOSTSFILE)
|
||||||
|
error = 0
|
||||||
|
masteriphosts = {}
|
||||||
|
masterhostip = {}
|
||||||
|
hosts = open(HOSTSFILE,'r',encoding='utf-8')
|
||||||
|
|
||||||
|
for line in hosts:
|
||||||
|
if not line.startswith('#') and line.strip():
|
||||||
|
line=re.sub(r'#.*$', '', line).rstrip()
|
||||||
|
data = line.split()
|
||||||
|
i = data.pop(0)
|
||||||
|
if debug > 1: print("checking ip "+i)
|
||||||
|
if (i in masteriphosts):
|
||||||
|
print("ERROR: Duplicate ipaddress "+i+" for "+str(data)+" and "+str(masteriphosts[i]))
|
||||||
|
error += 1
|
||||||
|
else:
|
||||||
|
masteriphosts[i] = data
|
||||||
|
|
||||||
|
for h in data:
|
||||||
|
if debug > 1: print("checking host "+h)
|
||||||
|
if (h in masterhostip):
|
||||||
|
print("ERROR: Duplicate hostname "+h+" in hosts file for "+i+" and "+masterhostip[h])
|
||||||
|
error += 1
|
||||||
|
else:
|
||||||
|
masterhostip[h] = i
|
||||||
|
if error:
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
for router in routerlist:
|
||||||
|
USERHOST = routeruser+"@"+router
|
||||||
|
iphosts = masteriphosts.copy()
|
||||||
|
hostip = masterhostip.copy()
|
||||||
|
addrname = {}
|
||||||
|
nameaddr = {}
|
||||||
|
|
||||||
|
# Step2 SSH to EACH DNS Router and Export the DNS static table and Parse
|
||||||
|
print("# Getting router DNS entries: ssh",USERHOST, SSHCMD)
|
||||||
|
ssh = subprocess.Popen(["ssh", "%s" % USERHOST, SSHCMD],
|
||||||
|
shell=False,
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.PIPE)
|
||||||
|
result = ssh.stdout.readlines()
|
||||||
|
if result == []:
|
||||||
|
error = ssh.stderr.readlines()
|
||||||
|
# print >>sys.stderr, "ERROR: %s" % error
|
||||||
|
else:
|
||||||
|
if debug: print("# Parsing DNS Static Export")
|
||||||
|
for line in result:
|
||||||
|
if line.startswith(b'\n') :
|
||||||
|
line=re.sub(r'add address=', '', line).rstrip()
|
||||||
|
line=re.sub(r'name=', '', line)
|
||||||
|
a,n = line.split()
|
||||||
|
# Check name is a Host
|
||||||
|
if (n in hostip):
|
||||||
|
i = hostip[n]
|
||||||
|
# Check for duplicate DNS names
|
||||||
|
if (n in nameaddr):
|
||||||
|
command = "ssh "+USERHOST+" /ip dns static remove [find name="+n+" address="+a+"]; # Delete Duplicate"
|
||||||
|
print(command)
|
||||||
|
os.system(command)
|
||||||
|
# Changed address for name
|
||||||
|
elif (a != i):
|
||||||
|
command = "ssh "+USERHOST+" /ip dns static set address="+i+" [find name="+n+" address="+a+"]; # Changed Address"
|
||||||
|
print(command)
|
||||||
|
os.system(command)
|
||||||
|
addrname[i] = n
|
||||||
|
nameaddr[n] = i
|
||||||
|
# Delete key from hostip after used so they are gone before step3
|
||||||
|
del hostip[n]
|
||||||
|
else:
|
||||||
|
# Delete it if not Host
|
||||||
|
command = "ssh "+USERHOST+" /ip dns static remove [find name="+n+" address="+a+"]; # Delete Entry"
|
||||||
|
print(command)
|
||||||
|
os.system(command)
|
||||||
|
|
||||||
|
# Step3 Remaining keys in hostip need to be added.
|
||||||
|
if debug: print("# Generate Add Commands")
|
||||||
|
for h in hostip:
|
||||||
|
i = hostip[h]
|
||||||
|
command = "ssh "+USERHOST+" /ip dns static add address="+i+" name="+h+"; # Add Entry"
|
||||||
|
print(command)
|
||||||
|
os.system(command)
|
||||||
|
|
||||||
|
if debug: print("# Finished")
|
||||||
|
exit(0)
|
Reference in New Issue
Block a user