Here is a DDNS update script for a unix environment that should be useful for your users. It allows a user to update the ddns of a router from a server behind an ethernet firewall. It allows the user to modify several different domains at once, and to put the access passwords into a secret file for security purposes. The name of the script is DDNS_UPDATE.pl #! /usr/bin/perl -w ############################################################### # # Copyright (C) 2003 Philip Lawrence # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # version 1.0 ddns_update.pl for systems with an ethernet router # (WGR614 specifically, but it is easily changed to work with others) # # This allows a system to have an ethernet router, with port # forwarding, and a server hidden behind the router firewall. # # this version uses curl to get the router status info, then uses that # ip to update one or more domains on the server. # # The servers hidden behind the firewall can use dynamic or static # ip addresses assigned by the router, as long as the router can # route to them with port forwarding. # # The router status command, domain names, userids, and passwords # are hidden in a secret file (which is checked at runtime). # # A log file is appended to after completion of the update command # ############################################################### use Date::Format; #$verbose = 'false'; $verbose = 'true'; $ruid = ''; $rpwd = ''; $cuid = ''; $cpwd = ''; $rurl = ''; @domain = (); $CFGDIR = '/etc/changeip'; $LOGFILE = '/var/log/cip.log'; $DNSSERVER = 'www.changeip.com:443'; sub get_pwd { # this file MUST be owned by root with mode 600 my $sfile = "$CFGDIR/changeip.secret"; my $statstr = `stat -c "%U %a" $sfile`; my $dstr = ''; ($statstr ne 'root 600') or die "$sfile MUST be set to mode 600 and root"; # the format of the file is: # url to the router status (http:///s_status.htm) # colon separated list of domain names (domain.com:www.domain.com) # router user id # router password # changeip account user id # changeip account password open(IN, "<$sfile") or die "unable to open $sfile"; my @lines = ; close(IN); ($rurl) = ($lines[0] =~ /\s*([\w:.\/]*)\s*/); ($dstr) = ($lines[1] =~ /\s*([\w:.]*)\s*/); @domain = split(/:/,$dstr); ($ruid) = ($lines[2] =~ /\s*(\w*)\s*/); ($rpwd) = ($lines[3] =~ /\s*(\w*)\s*/); ($cuid) = ($lines[4] =~ /\s*(\w*)\s*/); ($cpwd) = ($lines[5] =~ /\s*(\w*)\s*/); if ($verbose eq 'true') { print "rurl - $rurl\n"; print "dstr - $dstr\n"; print "ruid - $ruid\n"; print "rpwd - $rpwd\n"; print "cuid - $cuid\n"; print "cpwd - $cpwd\n"; } } sub get_router_ip { my $line = ''; my @lines; my $cnt = 0; @lines = `/usr/bin/curl -s --user $ruid:$rpwd $rurl | grep -A 1 "IP Address"`; while ($#lines < 1 && $cnt < 3) { $cnt++; sleep(1); } if ($#lines < 1) { print "unable to get the router ip\n"; exit 1; } if ($verbose eq 'true') { print "router line: $lines[1]\n"; } $_ = $lines[1]; ($line) = ($lines[1] =~ /[\s\w]*>([\w.]*)<\w*/); if ($verbose eq 'true') { print "router_ip: $line\n"; } return $line; } sub get_ns_ip { my $str = ''; my $dnsstr = `host $_[0]`; ($str) = ($dnsstr =~ /(\S+)\n?$/); if ($verbose eq 'true') { print "domain: $_[0] ns_ip: $str\n"; } return $str; } sub update_ns { my $successstr = 'Successful Update!'; my $ip = $_[0]; my $dname = $_[1]; my $getstring = "GET /update.asp?u=$cuid&p=$cpwd&cmd=update&hostname=$dname&ip=$ip"; my $cmd = qq~echo "$getstring" | openssl s_client -quiet -connect $DNSSERVER 2>&1~; # run the update command if ($verbose eq 'true') { print "updating dns server with command:\n"; print "$cmd\n"; } my @output = `$cmd | grep "" | grep "$successstr"`; if ($verbose eq 'true') { print "response from cmd:\n"; print "$output[0]\n"; } open(LOGFIL, ">>$LOGFILE"); print LOGFIL time2str("%D %H:%M", time()) . "\n"; if (index($output[0],$successstr) >= 0) { print LOGFIL "$successstr for domain ip: $router_ip\n"; } else { print LOGFIL "update failed for domain ip: $router_ip\n"; } close(LOGFIL); } get_pwd(); $router_ip = get_router_ip(); foreach my $tname (@domain) { $ns_ip = get_ns_ip($tname); # only modify the ddns ip address if it has changed if ($router_ip ne $ns_ip) { update_ns($router_ip,$tname); } }