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_recordsreturns a list of all DNS records in your account.
dns-add_recordadds a DNS record.
dns-remove_recordremoves 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.
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
Finally, let’s write the logic that will connect these functions:
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.