Posts Tagged ‘Ash’

Linode Dynamic DNS Ash Script

Monday, May 11th, 2009

After my post last night regarding a bash script to update Linode's DNS Manager, opello from #linode on OFTC provided some sed commands to parse the JSON output. Using his commands, I made another version of the script.  I've tested this on my router running the Tomato firmware (which runs BusyBox).

I found that the wget command built into the version of BusyBox does not support HTTP POST. It also does not support https urls, only http. This means your Linode API key would be transmitted in clear text, which probably isn't a good thing.

Another solution that was suggested was to simply wget a CGI script running on your webserver, which could update the Linode DNS Manager using perl or python over secure channels. That would reduce the complexity on the home router side and allow you to use the developed Linode API libraries.

Therefor, I wouldn't recommend using this unless you are able to send the requests over ssl channels. I am glad to have a slightly better understanding of sed. I'll probably modify the original bash script to use that as well.

#!/bin/ash
#
# Script to update Linode's DNS Manager for a given name.
#

# Things you need to change.
APIKEY=$(cat /home/root/linode-apikey)
LASTIP="/tmp/lastip"
DOMAIN="domain.com"
SOAEMAIL="hostmaster@domain.com"
STATUS="1"
RRTYPE="A"
RRNAME="home"
IFACE="vlan1"

# Shouldn't need to change anything below here.

WGET="wget -qO - http://api.linode.com/api/?api_key=$APIKEY"
NEWIP=$(ifconfig $IFACE | head -n2 | tail -n1 | cut -d: -f2 | cut -d' ' -f1)
test -e $LASTIP && OLDIP=$(cat $LASTIP) || OLDIP=""

if [ x"$OLDIP" = x"$NEWIP" ]; then
  logger "No IP address change detected. Keeping $NEWIP"
else
   DOMAINID=$($WGET"&action=domainList" | 
        sed -nr "s#.*"DOMAIN":"$DOMAIN","DOMAINID":([0-9]+),.*#1#p")
   RESOURCEID=$($WGET"&action=domainResourceList&DomainID=$DOMAINID" | 
        sed -nr "s#.*"RESOURCEID":([0-9]+),"DOMAINID":$DOMAINID,"TYPE":"$RRTYPE","NAME":"$RRNAME".*#1#p")
   $WGET"&action=domainResourceSave&ResourceID=$RESOURCEID&DomainID=$DOMAINID&Name=$RRNAME&Type=$RRTYPE&Target=$NEWIP"; echo
   $WGET"&action=domainSave&DomainID=$DOMAINID&Domain=$DOMAIN&Type=master&Status=$STATUS&SOA_Email=$SOAEMAIL"; echo
   echo $NEWIP > $LASTIP
   logger "Updated IP address to $NEWIP"
fi

Linode Dynamic DNS Bash Script

Monday, May 11th, 2009

So Mark Walling was working on an ash script for his router running OpenWRT to update Linode's DNS Manager with his IP address. I liked the idea of a simple shell script to update without needing to install libraries for Perl or Python.  I took his script and tried to adapt it to get the DOMAINID and RESOURCEID using sed or awk.  Those utilities seem great for manipulating multiline files of text, but I wasn't getting anywhere trying to parse one line of JSON from wget.  So I used perl to extract the id numbers.  I believe OpenWRT has some sort of perl with limited functionality, so maybe this will work with that or at least be easily adapted.  This could also be easily modified to use curl instead of wget. I suspect someone out there will find this useful.

#!/bin/bash
#
# Script to update Linode's DNS Manager for a given name.
#

# Things you need to change.
APIKEY=$(cat ~/.linode-apikey)
LASTIP="/tmp/lastip"
DOMAIN="domain.com"
SOAEMAIL="hostmaster@domain.com"
STATUS="1"
RRTYPE="A"
RRNAME="home"
IFACE="eth0"

# Shouldn't need to change anything below here.

WGET="wget -qO - https://api.linode.com/api/"
NEWIP=$(ifconfig $IFACE | head -n2 | tail -n1 | cut -d: -f2 | cut -d' ' -f1)
test -e $LASTIP && OLDIP=$(cat $LASTIP) || OLDIP=""

if [ x"$OLDIP" = x"$NEWIP" ]; then
  logger "No IP address change detected. Keeping $NEWIP"
else
   DOMAINID=$($WGET --post-data "api_key=$APIKEY&action=domainList" | 
        perl -e 'if ( =~ /"DOMAIN":"'"$DOMAIN"'","DOMAINID":([0-9]+),/) { print $1; }')
   RESOURCEID=$($WGET --post-data "api_key=$APIKEY&action=domainResourceList&DomainID=$DOMAINID" | 
        perl -e 'if ( =~ /"RESOURCEID":([0-9]+),"DOMAINID":'"$DOMAINID"',"TYPE":"'"$RRTYPE"'","NAME":"'"$RRNAME"'"/) { print $1; }')
   $WGET --post-data "api_key=$APIKEY&action=domainResourceSave&ResourceID=$RESOURCEID&DomainID=$DOMAINID&Name=$RRNAME&Type=$RRTYPE&Target=$NEWIP"; echo
   $WGET --post-data "api_key=$APIKEY&action=domainSave&DomainID=$DOMAINID&Domain=$DOMAIN&Type=master&Status=$STATUS&SOA_Email=$SOAEMAIL"; echo
   echo $NEWIP > $LASTIP
   logger "Updated IP address to $NEWIP"
fi

css.php