Dynamic DNS With Dreamhost
Most home ISP’s assign you a dynamic IP address that changes periodically. So, what do you do if you want to run a server at home and access it remotely, but don’t know your IP address? If you already own a domain name and an account with a hosting provider that provides an API and DNS services, you can create your own dynamic DNS solution that you can automate on a Raspberry Pi. This article will show you how with a Dreamhost account and Python. (Disclaimer: Dreamhost is the provider I use, and the link is a referral link.)
Dreamhost provides an API that can create, remove, and edit DNS records. Our application will use the API to update the A record of a domain with your home’s IP address. Let’s take a look at the API’s DNS functions:
dns-list_records
returns a list of all DNS records in your account.dns-add_record
adds a DNS record.dns-remove_record
removes a DNS record.
We will be using these API functions to update the A record of a domain with your home’s IP address.
Before we get started, you’ll need a domain name with its DNS hosted by Dreamhost. You will also need an API key from Dreamhost with permission to use the DNS API functions.
The Code
Now, let’s dive into the code. First, import the modules we’ll need and define our API key:
For maintainability and reusability, we’ll divide our code into functions. One of the required tasks is finding out our current IP address. An easy way to do this is to get our IP address from a web service using the requests
library. We’ll be using IPInfo, which returns a JSON document containing your IP address.
We’ll also need a function to send commands to the Dreamhost API.
Each API requests requires a unique id. uuid.uuid1()
generates this ID.
To obtain the IP stored in the current DNS A record, we’ll need to call send_dreamhost_command
with a dns-list_records
command sent to the API. dns-list_records
returns a JSON document that looks like:
Each DNS record will be a JSON subdocument in the data array. We will find the record in this array that lists the IP for the domain we’re using for dynamic DNS.
If the IP address returned by get_dns_ip()
does not match the IP address returned by get_ip()
, we’ll also to update the DNS record by removing the old record and adding a new A record. The function update_ip(old_ip, new_ip)
does this by sending the API commands dns-remove_record
followed by dns-add_record
.
Finally, let’s write the logic that will connect these functions:
We call get_ip()
to get our current home IP, and we call get_dns_ip()
to get the IP in our DNS record. We compare the two IP addresses. If they are not the same, we call update_ip()
to update the DNS record. Now, all that’s left is to put it in a cron job on a Raspberry Pi or any other server you run at home, and you’ll be running your own dynamic DNS service.
My full code, which uses configuration files to store global constants, is available on Github.