Odysseus - Your Friendly DNS Pathfinder
Like most people I know, one day I decided to buy a Raspberry Pi and just like [some of] those people, I had no idea what I should do with it. I guess that the desire of a small computer to place to the remote corner of my desk was stronger than the actual need of it.
So, given I don’t like to have useless objects getting dusty in my room, I decided to think of something to do with my Pi, so that I could have a useful, still dusty, object.
I wrote down a list of projects I wanted to work on for which the Raspberry Pi would be of perfect use and among them there was the idea to go full ‘80s powerhouse and host my blog at home. The task itself is trivial, it involves no major technical difficulties, except one: my Internet Provider doesn’t sell static IP addresses, at least not to private customers!
What are the viable options then?
Dynamic DNS services such as DynDNS and No-IP could work but they’re paid for if you want to use your own domain name and it would probably cost as much as hosting your website elsewhere.
When I don’t find the right solution, I usually create one and that’s what I did: I created Odysseus.
Odysseus is a small Go application that runs on your workstation and does two basic operations:
- Fetches your current public IP address; and
- Checks with Cloudflare whether the content of a list of DNS A Records is updated
How to use it?
When I went to the whiteboard for the first time, I thought that Odysseus should run as a service and constantly scrape Cloudflare’s API looking for changes but, after a few Google searches, I found out that, as expected, the number of API calls are limited as explained in their documentation.
I am not too fussy about the risk of temporarily lose connection to my server – it’s just a blog – so I thought to execute the app using a Cron job. This gives the user the freedom to set their own intervals without stressing Cloudflare too much.
For the sake of the post, I’ll assume Odysseus will be installed on a Raspberry Pi 3 (Linux, ARM Architecture):
sudo mkdir -p /opt/odysseus cd /opt/odysseus || exit sudo wget https://github.com/darkraiden/odysseus/releases/download/v0.4.4/odysseus_0.4.4_Linux_armv6.tar.gz sudo tar zxvf odysseus_0.4.4_Linux_armv6.tar.gz sudo rm odysseus_0.4.4_Linux_armv6.tar.gz
Once you’ve downloaded Odysseus, it’s time to create your configuration file:
cloudflare: zone_name: example.com email: [email protected] api_key: cloudflareapikeygoeshere records: - www.example.com - api.example.com
I personally saved this file in
/etc/odysseus/cloudflare.yml, however it can be saved anywhere on your filesystem, as long as it’s referenced correctly in the application, but we’ll get there in just a moment.
When creating this file, make sure you replace the values of the following keys:
- zone_name: The name of your DNS Zone
- email: The email address used by the user to login to Cloudflare
- api_key: The Cloudflare API key (it can be found here
- records: A list of DNS A Records that will hold your ISP Public IP Address
Now that the binary is in place and the config file is created, it’s time to test if Odysseus does the job:
/opt/odysseus/odysseus -config-name cloudflare.yml -config-path /etc/odysseus time="2020-05-19T08:15:01+01:00" level=info msg="Welcome to Odysseus" time="2020-05-19T08:15:03+01:00" level=info msg="Your local IP Address is: xx.xx.xx.xx" time="2020-05-19T08:15:03+01:00" level=info msg="Your Zone ID is: cloudflareZoneIDGoesHere" time="2020-05-19T08:15:03+01:00" level=info msg="The DNS Record www.example.com has been updated successfully." time="2020-05-19T08:15:03+01:00" level=info msg="The DNS Record api.example.com has been updated successfully."
If the output looks something like this, the application works great. A few things to note, though. By default, the application tries to load the config file from the folder the binary lives in, however, an alternative filename and path can be specified by using the options showed in the snippet above:
-config-name– the name of the config file (extension included); and
-config-path– the absolute path to the config file (filename excluded)
We’re one step away from making this thing working on its own; it’s time to create the cronjob that executes it. On your terminal, type
sudo crontab -e and append this line to the file:
* * * * * /opt/odysseus/odysseus -config-name cloudflare.yml -config-path /etc/cloudflare >> /var/log/odysseus.log 2>&1
If you’re not familiar with crontab, we’re basically telling the system to run odysseus every minute, of every hour, of every day etc. Also, redirect the STDOUT to a log file called
odysseus.log so that we can inspect it anytime (useful for troubleshooting if things go wrong).
And, that’s pretty much it, I guess. Odysseus is up and running and now you have your custom Dynamic DNS Updater.
As usual, when I write stuff like this, I want to share it with everyone faces similar issues. The repository can be found on here, on GitHub.
Random fact: Why Odysseus?
I was looking for a name and I thought it had to be the name of a famous pathfinder, someone/something that leads the way to the right place. Given my origins [Italian], my first thought was Columbus but then I immediately realised… maybe not, he didn’t land up where he intended to 😁
So, I went back to my origins and my passion: Greek mythology. The Odyssey was one of my favourite books when growing up and Odysseus’ tenacity always inspired me; he fought a war, went through hell (literally), and after 20 years, despite all the trouble, managed to get back home to his family.
That’s it, I don’t think I have much left to add. If you like this project, make sure to star the git repo, or if you’d like to contribute, you can do it by either opening an issue on GitHub or by write some code yourself (make sure to check out the CONTRIBUTING.md file first, though 😊).
Until next time 👋