Tuesday, May 17, 2016

Dynamic DNS

The Domain Name System allows us to take an easily remembered name like kevintedesco.com and translate it to an IP address of a connected server. In this post we explore how to make a Linux server update the Internet dynamically when it's IP address changes. 

To accomplish this amazing feat we will modify the zone record of type A stored on a Domain Name Server. (In a later post we will explore the AAAA record for IPv6 but for now we will stick with IPv4.) Before the record gets updated we need to programmatically identify when our public IPv4 address changes. This is done with the help of BASH. The first few lines will set some variables. 

The first variable is output for this script and input for an iMacro that will be called to do the zone record updates. 

#!/bin/bash
DATASOURCEFILE="/home/user/iMacros/Datasources/domainip.csv"

The next line will utilize command substitution to populate the variable PrevIPAddress with the short output of the dig command for kevintedesco.com.  The dig command queries domain name servers for information regarding a registered domain name. We use the short option to keep the results brief and populate the variable with only the information we are looking for which is the current IP address defined in the zone record of A type. 

### Get previous WAN IP Address
PrevIPAddress=$(dig +short kevintedesco.com)

Next we set a variable to what public IPv4 address is currently assigned by the ISP to our internet gateway courtesy of ipecho.net. 

### Get current WAN IP Address
CurrIPAddress=$(wget http://ipecho.net/plain -O - -q ; echo)

With both variables set we have identified where we were previously and where we are now. These variables are echoed to the screen for human review then logically compared. If changes are detected we log the changes to the file defined earlier and call upon the Firefox add-on iMacros to update the cPanel interface of GoDaddy with the new information. 

### Compare previous to current, if change run UpdateDomainIP macro
echo "Previous IPAddress:$PrevIPAddress"
echo "Current IPAddress:$CurrIPAddress"

if [ "$CurrIPAddress" == "$PrevIPAddress" ]; then
        echo "IP address has not changed"
else
        echo "IP Address has changed"
        ### Write Current IP Address to imacro input file
        printf "$CurrIPAddress" > $DATASOURCEFILE
        ### Run iMacro to update domain entry
        DISPLAY=:0.0 /usr/bin/firefox imacros://run/?m=UpdateDomainIP.iim
fi

The iMacro portion of this tool automates the points and clicks of HTML tags required to modify the zone record. Once it is complete DNS propagation begins and the new public IPv4 address will be available as the previous TTL expires. 

'Location of source information
SET !DATASOURCE domainip.csv
'Identify which tab is in use.
TAB T=1
'Goto website address
URL GOTO=https://dcc.godaddy.com/dcc50/DomainDetails.aspx?domainid=xyz
SET !ENCRYPTION NO
'Login
TAG POS=1 TYPE=INPUT:TEXT FORM=ID:login-form ATTR=ID:username CONTENT=xyz
TAG POS=1 TYPE=INPUT:PASSWORD FORM=ID:login-form ATTR=ID:password CONTENT=password
TAG POS=1 TYPE=BUTTON FORM=ID:login-form ATTR=ID:submitBtn
'Edit DNS settings
TAG POS=1 TYPE=A ATTR=TXT:DNS<SP>Zone<SP>File
TAG POS=5 TYPE=A ATTR=HREF:javascript:%20void(0);
WAIT SECONDS =3
FRAME NAME="ifrmDuel"
TAG POS=1 TYPE=INPUT:TEXT FORM=ID:form1 ATTR=ID:txtData CONTENT={{!COL1}}
FRAME F=0
TAG POS=1 TYPE=BUTTON ATTR=TXT:Finish
WAIT SECONDS =3
TAG POS=1 TYPE=BUTTON ATTR=TXT:Save<SP>Changes
'Logout
TAG POS=1 TYPE=SPAN ATTR=ID:uxh-s-name
TAG POS=1 TYPE=A ATTR=TXT:Log<SP>Out
TAB CLOSE