Initial check-in: This is currently working but needs improvements.
authorPhilipp Spitzer <philipp@spitzer.priv.at>
Wed, 5 Mar 2014 21:06:46 +0000 (22:06 +0100)
committerPhilipp Spitzer <philipp@spitzer.priv.at>
Wed, 5 Mar 2014 21:06:46 +0000 (22:06 +0100)
bin/nsupdate_dyndns [new file with mode: 0755]
bin/nsupdate_dyndns_del [new file with mode: 0755]
cgi-bin/dyndns.py [new file with mode: 0755]

diff --git a/bin/nsupdate_dyndns b/bin/nsupdate_dyndns
new file mode 100755 (executable)
index 0000000..dd9d5f0
--- /dev/null
@@ -0,0 +1,9 @@
+#!/bin/bash
+
+hostname=$1
+myip=$2
+type=$3 # A or AAAA
+ttl=600
+domain=dyn.colgarra.priv.at
+
+echo -e "update delete $hostname.$domain $type\nupdate add $hostname.$domain $ttl IN $type $myip\n" | nsupdate -l
diff --git a/bin/nsupdate_dyndns_del b/bin/nsupdate_dyndns_del
new file mode 100755 (executable)
index 0000000..a2e788f
--- /dev/null
@@ -0,0 +1,7 @@
+#!/bin/bash
+
+hostname=$1
+type=$2 # A or AAAA
+domain=dyn.colgarra.priv.at
+
+echo -e "update delete $hostname.$domain $type\n" | nsupdate -l
diff --git a/cgi-bin/dyndns.py b/cgi-bin/dyndns.py
new file mode 100755 (executable)
index 0000000..6087beb
--- /dev/null
@@ -0,0 +1,68 @@
+#!/usr/bin/python2.7
+"""Dynamic DNS script. Expects URLs from routers in the form
+https://info.colgarra.priv.at/dyndns/dyndns.py?username=<username>&password=<pass>&hostname=<domain>&myip=<ipaddr>
+"""
+
+import re
+import cgi
+import pwd
+from subprocess import call
+import ipaddr
+
+
+# Configuration
+PASSWORD = 'hygCithOrs5'
+
+
+# Just for debugging:
+# import cgitb
+# cgitb.enable()
+
+
+fields = cgi.FieldStorage()
+
+username = fields.getvalue('username')
+password = fields.getvalue('password')
+hostname = fields.getvalue('hostname')
+myip     = fields.getvalue('myip')
+
+# Strip zone
+hostname = re.sub('\.dyn\.colgarra\.priv\.at\s*$', '', hostname)
+
+try:
+       # check username
+       user_info = pwd.getpwnam(username) # returns a key error if the user does not exist
+       if user_info.pw_uid < 1000:
+               raise RuntimeError('Invalid user name')
+
+       # check password
+       if password != PASSWORD:
+               raise RuntimeError('Invalid password')
+
+       # check hostname
+       if re.match(r'[-0-9a-z]+(\.[-0-9a-z]+)*$', hostname) is None:
+               raise RuntimeError('Invalid host name')
+
+       # check IP address
+       ip = ipaddr.IPAddress(myip) # throws axception if the IP address is not valid
+       if isinstance(ip, ipaddr.IPv4Address):
+               type = 'A'
+       elif isinstance(ip, ipaddr.IPv6Address):
+               type = 'AAAA'
+       else:
+               raise RuntimeError('Unknown IP address type')
+
+       # access granted
+       print "Content-Type: text/html"
+       print
+       call(['sudo', '/usr/local/bin/nsupdate_dyndns', hostname, myip, type])
+       print "OK"
+
+
+except:
+       # access denied
+       print "Content-Type: text/html"
+       print "Status: 403 Forbidden"
+       print
+       print "Denied"
+