Friday, September 16, 2011

DDNS for OpenIndiana

In this installment, we are going to make up for a short coming in the No-IP service that I otherwise am very happy with.
I am hosting all kinds of machines on a DHCP connection. Shhh....
So I signed up with No-IP which I like very much.
I put a brand new SFTP server in service to replace my somewhat less secure FTP server I only had access to locally.
With all of it's shiny UNIX security, I tried to make it externally accessible-- but was unable with the tools provided by No-IP.
I will be supplementing my primary paid DDNS with No-IP by also using a free DynDNS account.
I plan on keeping No-IP because of their rock solid service that I have noticed 0 issues or problems with in several years.
Depending on how things go, I may also fork some money over to DynDNS.

On to the task at hand.

I chose DynDNS because I have a few friends that use it.

This is important. To avoid getting shut off for abuse while testing solutions, DynDNS has a few dummy accounts that can be used.
http://dyn.com/support/developers/test-account

There is something to be said about the multitude of solutions to a finite set of problems. It took me three tries to get something new to work. Just keep at it, eventually you will get it.

Plan C

Create a heading in your log just for stuff and giggles.

vi /var/log/updatedns.log

DNS Update Log

Write the script that will do the dirty work.

vi /usr/sbin/updatedns.sh


#!/bin/sh

#Get the data that allows for checking that the DNS service has a good IP.
  #I use no-ip for bradchesney.net, which does not facilitate sftp server DDNS services.
  #However, I can us it to see what my current IP is.
  #I leave finding the immediate value of your current external IP to you.
extip=`dig +short bradchesney.net`
  #Then I retrieve what my second DDNS provider thinks my SFTP server's IP is.
sftpserv=`dig +short sftpserv.dyndns.com`
  #Grab the date for simple logging purposes.
thedate=`date`

#Compare the values.
if [ "$extip" = "$sftpserv" ]; then

  #These lines test that the cron service is running the script and the basic logging works.
  #These are debugging lines and should be commented out during normal usage.
  #echo "#######################################################" >> /var/log/updatedns.log
  #echo "$thedate : EXTIP $extip; SFTPSERV $sftpserv -- Debug" >> /var/log/updatedns.log

#If the both IPs match, do nothing.
exit

else

#If they are different, update the IP with cURL and log the update.
  #Create the string to feed to curl
update="https://DYNDNSLOGIN:DYNDNSPASSWORD@members.dyndns.org/nic/update?system=dyndns&hostname=CHOSENDYNDNSHOSTNAME.dyndns.CHOSENDYNDNSTLD&myip=$extip"

  #This is a good debugging test string to avoid getting banned.
  #update="https://test:test@members.dyndns.org/nic/update?system=dyndns&hostname=test.mine.nu&myip=$extip"

#Update via curl and log the output and/or results
echo "#######################################################" >> /var/log/updatedns.log
echo "$thedate : EXTIP $extip; SFTPSERV $sftpserv" >> /var/log/updatedns.log
curl -k $update >> /var/log/updatedns.log > /dev/null
echo -e /r/n

fi


Change the owner, group, and permissions on the script.
chown root:bin /usr/sbin/updatedns.sh
chmod 751 /usr/sbin/updatedns.sh

Setup a cron job for the script.
I have mine set to check that I have a good IP every six minutes.
chrontab -e

Append the following text to run the script every six minutes.

0,6,12,18,24,30,36,42,48,54 * * * * /usr/bin/updatedns.sh

Boom, a somewhat resilient DDNS updater. --I am open to suggestions regarding a better way, but this should work rather well.

(Also, while building the curl command I noticed that I was contacting members.dyndns.org:8245 for ddclient in Plan B. Port 8245 is an unencrypted http port. I have a feeling that if I were to have changed that to port 443 or no port at all, the ddclient script may have worked. Hindsight.)




Plan B -- Failed

ddclient is a perl script that will meet the needs and supports many DDNS service providers.


Download the script.

http://sourceforge.net/projects/ddclient/files/ddclient/ddclient-3.8.1/ddclient-3.8.1.tar.gz/download



Install ddclient.

cp /file/extraction/location/ddclient /usr/sbin
mkdir /etc/ddclient
mkdir /etc/var/cache/ddclient
cp /file/extraction/location/sample-etc_ddclient /etc/ddclient/ddclient.conf


(! I don't know where you extracted the files. You can find / -name ddclient to have your system tell you where you put them.


Configure ddclient

vi /etc/ddclient/ddclient.conf


######################################################################
##
## $Id: sample-etc_ddclient.conf 125 2011-05-19 20:31:20Z wimpunk $
##
## Define default global variables with lines like:
##      var=value [, var=value]*
## These values will be used for each following host unless overridden
## with a local variable definition.
##
## Define local variables for one or more hosts with:
##      var=value [, var=value]* host.and.domain[,host2.and.domain...]
##
## Lines can be continued on the following line by ending the line
## with a \
##
##
## Warning: not all supported routers or dynamic DNS services
##          are mentioned here.
##
######################################################################
daemon=3600
syslog=no
ssl=no
#ssl=yes                                # use ssl-support.
                                        # Works with ssl-library.
fw-login=ROUTERUSERNAME,             fw-password=ROUTERPASSWORD          # FW login and password

## To obtain an IP address from FW status page (using fw-login, fw-password)
use=fw, fw='https://192.168.1.1/Status_Internet.asp', fw-skip='LAN IP' # found after IP Address

## Above is the web address of a page on my router that shows my external IP.
## After that is fw-skip. The visible text immediately after my external IP is LAN IP.
## ddclient must look for that text and then find my external IP relative to it.

login=DYNDNSLOGIN                     # default login
password=DYNDNSPASSWORD               # default password
server=members.dyndns.org:8245  \       # default server (bypassing proxies)

protocol=dyndns2,               \
CHOSENDYNDNSHOSTNAME.dyndns.CHOSENDYNDNSTLD

Install SUNWopenssl, perl510extra, net-ssleay, pmtools, and perl510 from the package manager if not already installed.
They can be easily found by simply searching for perl in the package manager.


Seemingly unavailable from the packages are the IO-Socket-SSL modules for perl.
The following instructions installed the missing files in places ddclient could find them.

The source (that creates the make files via an initial perl script) can be found at:
http://www.cpan.org/modules/by-module/IO/IO-Socket-SSL-1.44.tar.gz

cd /file/extraction/location/
perl Makefile.PL
make
make test
make install

At this point you can begin attempting to update your DDNS information with ddclient.
You can use /usr/sbin/ddclient -daemon=0 -noquiet -debug to get information if things don't go as expected.
Alternatively the truss -a -f /usr/sbin/ddclient -daemon 600 command is very cool at seeing the system calls if needed.


Start the ddclient daemon and keep it started
I am using a cron job in conjunction with a script to monitor whether ddclient is running or not.

vi /usr/bin/ddnsupdate.sh

##########################################
#!/bin/sh

#Check for ddclient.
#If not running, run ddclient.

if ps | grep ddclient > /dev/null
then
    exit
else
    /usr/bin/ddclient
fi
##########################################

Change the owner, group, and permissions on the script.
chown root:bin /usr/sbin/ddnsupdate.sh
chmod 751 /usr/sbin/ddnsupdate.sh

Create the line of code that will make cron run the script.

vi /var/spool/cron/crontabs/root

Append

*/10 * * * * /usr/bin/updateddns.sh

to the end of the file.


Plan A -- Failed

inadyn requires linux files that are not present on an OpenIndiana installation.
inadyn requires linux files that are very difficult to put on an OpenIndiana installation.

Followers