Add update_mikrotik_dns.py

This commit is contained in:
gru
2025-05-24 11:52:51 +02:00
parent c88b417eb0
commit 2d5838d752

138
update_mikrotik_dns.py Normal file
View 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)