Last active
April 6, 2020 16:04
-
-
Save sphaero/8423100 to your computer and use it in GitHub Desktop.
Simple DynDNS Service using (apache) webserver and DNSMasq
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Simple Dynamic DNS update script for use with DNSMasq | |
# | |
# Install this WSGI script on a (apache) webserver. Make sure | |
# DNSMasq runs as the same user as this script does on the webserver | |
# E.g: /etc/default/dnsmasq add: (Debian and deriatives) | |
# DNSMASQ_USER='wsgiuser' | |
# | |
# ### DNSMASQ.CONF ### | |
# domain-needed | |
# bogus-priv | |
# filterwin2k | |
# no-resolv | |
# no-dhcp-interface=eth0 | |
# bind-interfaces | |
# no-hosts | |
# addn-hosts=/tmp/dynhosts | |
# domain=dyn.z25.org | |
# expand-hosts | |
# ### END DNSMASQ.CONF ### | |
# | |
# ### APACHE EXAMPLE CONF ### | |
# # This file defines the apache configuration for the dyndns.example.com domain | |
# # (change example.com to your own domain name, of course) | |
# <VirtualHost *:80> | |
# ServerName dyndns.example.com | |
# # dyndns interface | |
# ServerAdmin support@example.com | |
# | |
# DocumentRoot /var/www/dyndns/ | |
# WSGIScriptAlias /nic/update /var/www/dyndns/dyn_dns.py | |
# <Directory /var/www/dyndns/> | |
# Options FollowSymLinks MultiViews +ExecCGI | |
# AllowOverride FileInfo | |
# AddHandler wsgi-script .py | |
# Order allow,deny | |
# allow from all | |
# </Directory> | |
# | |
# LogLevel warn | |
# ErrorLog /var/log/apache2/dyndns.error.log | |
# CustomLog /var/log/apache2/dyndns.access.log combined | |
# ServerSignature On | |
# </VirtualHost> | |
# ### END APACHE EXAMPLE CONF ### | |
from cgi import parse_qs, escape | |
import psutil | |
import os | |
import signal | |
def signal_dnsmasq(): | |
pids = psutil.get_pid_list() | |
for pid in pids: | |
if psutil.Process(pid).name == "dnsmasq": | |
os.kill(pid,signal.SIGHUP) | |
break | |
def update_host(hostname, ip): | |
line_to_update = "%s\t%s\n" %(ip, hostname) | |
with open('/tmp/dynhosts', 'r') as f: | |
data = f.readlines() | |
updated = False | |
# need to enumerate list iter to update data | |
for idx, line in enumerate(data): | |
# split tab delimiter | |
hn = line.split('\t')[1] | |
# remove end of line char | |
hn = hn.split('\n')[0] | |
if line == line_to_update: | |
return | |
elif hn == hostname: | |
data[idx] = line_to_update | |
updated = True | |
if not updated: | |
data.append(line_to_update) | |
with open('/tmp/dynhosts', 'w') as f: | |
f.writelines(data) | |
signal_dnsmasq() | |
def dyn_dns_app(environ, start_response): | |
status = '404 Not Found' # HTTP Status | |
headers = [('Content-type', 'text/plain')] # HTTP Headers | |
# The returned object is going to be printed | |
ip = environ['REMOTE_ADDR'] | |
d = parse_qs(environ['QUERY_STRING']) | |
hostname = d.get('hostname') | |
if hostname: | |
status = '200 OK' | |
update_host(hostname[0], ip) | |
start_response(status, headers) | |
return ["good"] | |
else: | |
start_response(status, headers) | |
return [""] | |
application = dyn_dns_app | |
if __name__ == '__main__': | |
from wsgiref.simple_server import make_server | |
httpd = make_server('', 8000, dyn_dns_app) | |
print "Serving on port 8000..." | |
# Serve until process is killed | |
httpd.serve_forever() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment