When I got my NAS, I had clear that I wanted to access it from anywhere in the world, as I’m a person who loves travelling and from time to time I’ll need the documents, photos and files in general stored in it. It just made sense for me.
To make things easier, I purchased a domain in Alibaba Cloud and got an A Record pointing to my home’s public IP. In this way I can even automate a Let’s Encrypt SSL Certificate to ensure the authenticity of the connection. Yes, you are right, as the majority of home connections, mine also uses a dynamic IP, and changes from time to time. The solution? To update the “A Record” every time that IP changes in what is called “Dynamic DNS“.
According to Wikipedia, “Dynamic DNS (DDNS or DynDNS) is a method of automatically updating a name server record, often in real time, with the active Dynamic DNS configuration of its configured hostnames, addresses or other information“.
Typically, a server has a static IP, and the related domain name contains an A Record stating which one it is. An illustration as example of how a machine resolves the IP of wikipedia.org is shown below:
As you can see, there are a lot of steps involved for the visitors’ machine to “translate” wikipedia.org into 184.108.40.206. After the DNS resolves wikipedia.org into its IP address, the computer can locate where the page is hosted in the Internet. This is also the common case for most of websites.
Why We Need a Dynamic DNS solution
For the most part, static IPs work well for accessing the Internet. The problem arises when we don’t have a static, but a Dynamic IP, like in our home connection. In this article I’ll show you how I solved this issue by using Alibaba Cloud’s API.
What Do We Need
This tutorial assumes that you already have the following products with Alibaba Cloud:
- A domain with the DNS managed by Alibaba Cloud
- An ECS instance with Apache & PHP (Because you have a small website or something else)
The whole idea will be to schedule a cron job in the NAS running curl to a URL as a webhook, which will run a PHP script hosted in our ECS instance that uses Alibaba Cloud DNS API to update the A Record of the given domain. Sounds complex, but is not.
The standardized method for dynamically updating a domain name server record is defined in RFC2136, commonly known as dynamic DNS update. This method is a network protocol for use with managed DNS servers, and it includes a security mechanism. Check the relevant documents for RFC2136 if you want to dig more about it.
So, knowing how the DNS works and why we need to setup a Dynamic DNS for our home NAS, let’s dive into the details. We will use alicloud-php-dns-updater, a PHP script class I made specifically for this purpose. It is ready to use.
Clone the Repo
Go ssh into your Alibaba Cloud ECS instance and go to the
/var/www/html directory (or whichever one of your choice serving public content).
Once there, type
git clone https://github.com/roura356a/alicloud-php-dns-updater.git dyndns-updater.
Get Your Access Keys from Alibaba Cloud
Getting a key pair is easy, and lets you to use more API features apart from the DNS one.
In order to get one, log into your Alibaba Cloud console and in the top navigation bar, hover with your mouse in your email address and click “AccessKey” as illustrated below.
Once in the keys screen, copy the Access Key ID and the Access Key Secret into a safe place. To show the Secret Key to need to click on “Show“. Be careful where you save this data, as it is very sensitive and could potentially cause irreversible damages if mishandled. Also you should consider creating more limited keys using their policies, but that’s a topic for another entry.
Setting the Dynamic DNS Updater Script up in the ECS
Going back to our ECS, we need to open the index.php file and replace the placeholders with the information you gathered before, such as
In this example, I have assumed that our
CjKaN02Ann9maMmiauusmoGOI7mn, and the domain
index.php file should look like this:
<?php date_default_timezone_set('UTC'); include_once 'alicloud-php-updaterecord/V20150109/AlicloudUpdateRecord.php'; use Roura\Alicloud\V20150109\AlicloudUpdateRecord; $AccessKeyId = 'CAmKUmIUGiMO83mS'; $AccessKeySecret = 'CjKaN02Ann9maMmiauusmoGOI7mn'; $updater = new AlicloudUpdateRecord($AccessKeyId, $AccessKeySecret); $newIp = $_SERVER['REMOTE_ADDR']; // New IP $updater->setDomainName('customnasathome.com'); $updater->setRecordType('A'); $updater->setRR('@'); $updater->setValue($newIp); print_r($updater->sendRequest());
Testing the Updater
Now that we have finished all the steps above, it’s time to test if everything is correctly set up. By this moment, you should have a public URL (http://220.127.116.11/dyndns-updater/), which will run the updater just by visiting it. Open it in your browser and look at the output.
If the API response is positive, the output should look like this:
Array ( [RecordId] => 3666544576879860 [RequestId] => F4VDF8A-D2DF-49VV-ER00-458D6918FDDE )
Hooray! You successfully updated the A Record of your domain by using Alibaba Cloud DNS API. Easy, right?
Securing the Script
So we are able to change the A Record of a given domain by only opening a URL as if it were a webhook, either from a browser or using curl, but the URL by default is publicly accessible, and, even if you don’t tell the URL to anyone, is a really bad practice to leave it like that. To secure the access we will use Apache .htaccess and .htpasswd.
Put this file (.htaccess) in the same folder as index.php:
AuthType Basic AuthName "DNS Updater Access" AuthUserFile /var/www/dyndns-updater/.htpasswd Require valid-user
For this step you need to run a command to create the user and its password.
Type, in any location,
htpasswd -c /var/www/dyndns-updater/.htpasswd updater_user.
This will create the file for the first time. “updater_user” is the username you are adding. It will ask you for the password when you run it. According to the official Apache documentation, htpasswd encrypts passwords using either bcrypt, a version of MD5 modified for Apache, SHA1, or the system’s crypt() routine, so the password will never be saved in plain text. This is important to know, as you will need to keep the password in a safe place after executing the command. You won’t be able to recover it if you forget it because it is encrypted.
After that you should be able to access the URL by providing the username and password in a Basic Authentication fashion.
Cron is a time-based job scheduler utility in Unix-like operating systems. It comes in very handy for running automatic backups or other routine tasks. It suits perfectly in our case, as we will need to check from time to time if the external public IP changed to update the A Record of our domain accordingly.
The location of the crontab in your instance does not matter, as we will add the cronjob by using the command line.
crontab -e and select your favorite editor (if not sure, choose
nano, as it is the easiest one out there).
If you choose
nano, remember that to exit and save the file, you need to press ctrl + x, then y and enter.
For this tutorial, we are setting the scheduled job to run every 30 minutes. You can see that in the variable
/30. If you want to set it every 15 minutes, you should update that part to
/15. For more advanced cron adjustments check the official Linux cron guide.
Go to the bottom of the crontab file and add
/30 * curl http://18.104.22.168/dyndns-updater/.
In this case, we will need to add the credentials for basic authentication to curl in order to get access. Go to the bottom of the crontab file and add
/30 * curl -u "updater_user:YOUR_PASSWORD" http://22.214.171.124/dyndns-updater/.
By default, Alibaba Cloud sends you an email whenever there is any record changes. So you will be able to keep track of all the automated updates the moment they happen. If you want to know more about Alibaba Cloud API, you can visit the official Developer Resources, where you can check all the Alibaba Cloud API references.