User:Datagrok/ddns

ddns.py is a small script that maintains a DNS record that points at one's home network. This process is sometimes called Dynamic DNS.

There are others like it; see The DNS section of API Apps or Dynamic DNS for some. I wrote this one to obtain the following features that I could not find elsewhere:


 * It runs from your DreamHost shell account, and uses your ssh connection to determine your IP.
 * It's implemented in Python.
 * Uses my own Python module to interface with the DreamHost API.

ddns.py listing:

from dreamhostapi import DreamHostServerProxy from os import environ def main: dh_api_key = '6SHU5P2HLDAYECUM' hostname = 'home.mydomain.com' new_ip = environ['SSH_CLIENT'].split[0] server = DreamHostServerProxy(dh_api_key) if __debug__: print "Retrieving list of current domains..." for record in server.dns.list_records: if not (record['record'] == hostname and record['type'] == 'A'): continue if record['value'] == new_ip: if __debug__: print "Old record for %(record)s found with IP %(value)s, no update needed." % record raise SystemExit if __debug__: print "Old record for %(record)s found with IP %(value)s, removing." % record result = server.dns.remove_record(            record=record['record'],             type=record['type'],             value=record['value'],         ) result = server.dns.add_record(        comment='Dynamic DNS IP',         record=hostname,         type='A',         value=new_ip,     ) if result != 'record_added': raise ValueError("There was a problem adding the record.") if __debug__: print "Success" if __name__=="__main__": main
 * 1) !/usr/bin/python -O

Required module
dreamhostapi.py is a small Python module I wrote to interface with the DreamHost API. There are others like it; DreamPyLib is one such. I wrote this one to obtain the following features that I could not find elsewhere:


 * It is implemented as a wrapper around Python's built-in XMLRPC library.
 * It's short.

dreamhost.api listing:

from xmlrpclib import ServerProxy, _Method from uuid import uuid1 class DreamHostMethod(_Method): def __init__(self, send, name): _Method.__init__(self, send, name) def __getattr__(self, name): return DreamHostMethod(self._Method__send, "%s-%s" % (self._Method__name, name)) def __call__(self, **kw): return self._Method__send(self._Method__name, kw) class DreamHostServerProxy(ServerProxy): dh_api_server = 'https://api.dreamhost.com/xmlrpc' def __init__(self, key, verbose=0): ServerProxy.__init__(self, uri=self.dh_api_server, verbose=verbose) self.dh_api_key = key def __getattr__(self, name): return DreamHostMethod(self.__request, name) def __request(self, name, params): if not params: params = {} params['key'] = self.dh_api_key params['uuid'] = str(uuid1) result = ServerProxy._ServerProxy__request(self, name, (params,)) if result['result'] != 'success': raise ValueError("Server returned %(result)s: %(data)s" % result) return result['data']

Installation

 * 1) Copy the text above for ddns.py to a file named ddns.py on your DreamHost webserver.
 * 2) Change the variables dh_api_key and hostname to whatever you're using.
 * 3) Make it executable. (chmod +x ddns.py)
 * 4) Copy the text above for dreamhostapi.py to a file named dreamhostapi.py on your DreamHost webserver.
 * 5) Set up a machine within your home network to periodically connect to your shell account and run the ddns.py script.

Advanced Installation
I prefer to keep dreamhostapi.py in ~/lib/python/datagrok/; ~/lib/python is in my $PYTHONPATH. I then change the import statement to read:

from datagrok.dreamhostapi import DreamHostServerProxy

I set this to run periodically by creating an executable script /etc/cron.daily/ddns-update on a local machine:

ssh mydomain.com "ddns.py"
 * 1) !/bin/sh

Replace mydomain.com everywhere with your own domain name.

For better security, create a separate ssh key just for this automatic process, then restrict the key to run only ddns.py in .ssh/authorized_keys on your DreamHost shell account.