Dynamically Addressed Web Servers

To use dynamically addressed Web servers, a pointer to the server must be set up on each permanent Web server that links to the dynamically addressed Web server. This is done through a script that determines the externally visible IP address and uses this information to modify a file (either a link file which can be used by the LoadDynamic.cgi script or a home page HTML file that references the dynamically addressed Web server). Whichever kind of file is used, the PropagateIP script (as it is called) then FTPs the file to the appropriate spot on a statically addressed Web server.

A good spot to call the PropagteIP script is from the ppp ip-up or ip-up.local script. This way, the links to the dynamically addressed Web server will be set every time the ppp connection is brought up and its external IP address changes. Another possibility is to add a line to the cron table to cause the PropagateIP script to be invoked every half hour. This can be done for those servers that reside behind an edge router which handles all of the work involved with the Internet connection and which obscures any changes in the external IP address. This also protects against the case where the PPP link comes up and the FTPs fail. If both methods are employed, the chances are that the files will be FTPed to the permanent Web servers, one way or another, are virtually certain.

Note that, to use this feature, you must have a permanently available Web site somewhere (e.g. your own domain on a site hosting company's servers or one of those small user domains that many ISPs offer). It is on this site that the links to the dynamically addressed Web server are set up.

/etc/dyndns/PropagteIP:

A script that is invoked when the dynamic WAN IP address is assigned (e.g. from PPP's ip-up or ip-up.local script or periodically by cron to handle lease renewals by an edge router).

     #!/bin/sh
     #
     # Shell script that can either be called from PPP's ip-up or ip-up.local
     # script, or executed at regular intervals by cron, to set up all of the
     # links to any dynamically addressed Web servers on this machine.
     #
     # Depending on what kind of Internet connection this machine has, this
     # script is normally called from /etc/ppp/ip-up.local each time the PPP
     # link is brought up, or run from a line in crontab at regular intervals
     # (e.g. every couple of hours) to send the machine's assigned WAN IP
     # address to all of the external sites that need to know it.  In either
     # case this script is called with no parameters.  For example, if it is
     # being called from /etc/ppp/ip-up.local, it is called like this:
     #
     #      /etc/dyndns/PropagateIP
     #
     # On the other hand, if it is being invoked at regular intervals, the
     # crontab entry should look something like this:
     #
     #      19 0,2,4,6,8,10,12,14,16,18,20,22 * * * root /etc/dyndns/PropagateIP
     #
     # Or, if you have a version of cron that allows steps after ranges, you
     # can try this:
     #
     #      19 0-23/2 * * * root /etc/dyndns/PropagateIP
     #
     # Note that this script may be called on its own with a paramter of "force"
     # to force new copies of all the dynamic Web pages to the appropriate
     # servers, if said pages are changed.  Or, it may be called with a
     # parameter of "dump" to cause the dynamic Web pages to be dumped to
     # stdout for debugging porpoises.
     #
     # This script may also be called with a parameter of "noip" to force the
     # assigned WAN IP address to be sent to the dynamic DNS site.  No attempt
     # is made to push any copies of the dynamic Web pages to the appropriate
     # servers.  Typically, this would be invoked by cron every 15 days to
     # prevent the DNS entry from expiring.  For example, this crontab entry
     # might be used:
     #
     #      30 10 10,25 * * root /etc/dyndns/PropagateIP noip
     #
     # And, it may also be called with a paramter of "test" and an IP address
     # to test that everything is working correctly.  The IP address given will
     # be used instead of the assigned WAN IP address.
     #
     # Note that this script uses the WANCONNECTION setting in
     # /etc/sysconfig/clustering to determine whether anything should actually
     # be done or not.  If this machine does not connect directly to the Internet
     # via an edge router, ADSL or Diald, nothing is done.  These are the only
     # type of connections that need to have their WAN address broadcast so there
     # is no point in doing anything unless the system connects this way.  If no
     # setting is found, the default is to assume an ADSL connection.
     #
     # Finally, prior to using this script, if you plan on using the no-ip
     # notification feature, you'll need to install the noip program and
     # no-ip.conf in the directory /etc/dyndns.  If this directory doesn't exist,
     # you'll need to create, then populate it like this:
     #
     #      su
     #      mkdir /etc/dyndns
     #      chown root:root /etc/dyndns
     #      chmod u=rwx,go=rx /etc/dyndns
     #      cp ..../noip /etc/dyndns
     #      cp ..../no-ip.conf /etc/dyndns
     #      chown root:root /etc/dyndns/noip /etc/dyndns/no-ip.conf
     #      chmod u=rwx,go=rx /etc/dyndns/noip
     #      chmod u=rw,go= /etc/dyndns/no-ip.conf
     #
     # Once you've installed the noip program and its config file, you will need
     # to configure it by editing the no-ip.conf file as required.
     #
     #
     # Dynamic page type.  This will determine what type of Web page we build
     # for the appropriate remote Web servers.  We can either build a clone of
     # the home page of each of our dynamic Web servers, or we can just build a
     # redirect page which redirects the user straight to the dynamic Web server.
     #
     # Pick either "clone" or "redirect".
     #
     DynPageType="redirect"
     #
     # Check whether the statically addressed Web server is up and connected.
     #
     IsConnected()
     {
     #
     # Ping the Web server and see if we get a response.  If so, its up.
     #
     if ping -c1 -w120 $1 &> /dev/null; then
         return 0  #Success
     else
         return 1  #Failure
     fi
     }
     #
     # Check to see whether the WAN IP address is new.  When the lease is
     # renewed by the ISP and the edge router or when a new PPP connection is
     # brought up, the IP address doesn't always change.  If it doesn't change,
     # there's no sense in doing FTPs for no reason.
     #
     IsIPNew()
     {
     #
     # Put our current IP address into the current file so that we can compare
     # it and it will be there next time around.
     #
     echo $1 >/etc/dyndns/current_ip
     #
     # Check to see if the current IP address is the same as the previous one.
     #
     if [ -f /etc/dyndns/previous_ip ]; then
         if /usr/bin/diff /etc/dyndns/current_ip /etc/dyndns/previous_ip \
                 >/dev/null; then
             return 1  #The same
         else
             return 0  #New
         fi
     else
         return 0  #New
     fi
     }
     #
     # Make a Web page template and then substitute the dynamic addresses within
     # the template to make a dynamic Web page.
     #
     MakeWebPage()
     {
     /var/www/Scripts/HTMLPreProc.pl --intact \
         /var/www/$1/html/$2 /var/www/$1/html/$1.tplt
     sed "s/::::DynURL::::/$IPAddr:$3/" /var/www/$1/html/$1.tplt | \
         sed "s/::::DynIP::::/$IPAddr/" >/etc/dyndns/web_page
     }
     #
     # Substitute the dynamic address within a redirect page.
     #
     MakeRedirectPage()
     {
     echo "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">" \
         >/etc/dyndns/web_page
     echo "<html>" >>/etc/dyndns/web_page
     echo "<head>" >>/etc/dyndns/web_page
     echo "<title>Redirect Page</title>" >>/etc/dyndns/web_page
     echo "<meta http-equiv=\"REFRESH\" content=\"0;url=http://${IPAddr}:${1}/\">" \
         >>/etc/dyndns/web_page
     echo "</head>" >>/etc/dyndns/web_page
     echo "<body>" >>/etc/dyndns/web_page
     echo "</body>" >>/etc/dyndns/web_page
     echo "</html>" >>/etc/dyndns/web_page
     }
     #
     # Source the clustering configuration.  Default to ADSL, if there's no
     # WAN connection information.
     #
     # Note that, even though this script can be used to set up non-ADSL
     # connections, all of the other scripts that use the clustering
     # configuration pick ADSL as the default so we also do so here, for
     # consistency sake.
     #
     if [ -f /etc/sysconfig/clustering ] ; then
         . /etc/sysconfig/clustering
     else
         WANCONNECTION=ADSL
     fi
     #
     # If this machine is the primary server in the cluster and it is connecting
     # to the Internet through an external, gateway/edge router, the user will
     # have specified a tuple consisting of the address of a dedicated network
     # device that connects to the gateway/edge router, an IP address for that
     # local network device, and an IP address for the gateway/edge router.
     # Typically, the gateway/edge router will be an ISP's router (such as an
     # EVDO or FIOS router) that is set to bridge the packets sent to it on one
     # of its ports, to the WAN.
     #
     DEVICE=`echo $WANCONNECTION | grep -e "eth[0-9]\+," -o`
     if [ -n "$DEVICE" ]; then
         DEVICE=${DEVICE%,}
      LOCALADDR=`echo $WANCONNECTION | grep -e ",[^,]\+," -o`
      LOCALADDR=${LOCALADDR#,}
      LOCALADDR=${LOCALADDR%,}
      WANADDR=`echo $WANCONNECTION | grep -e ",[^,]\+\$" -o`
      WANADDR=${WANADDR#,}
  else
      DEVICE=""
      LOCALADDR=""
      WANADDR=$WANCONNECTION

fi
#
# If we're not executing the test or force command, and this system doesn't # connect to the Internet via an edge router or PPP-type connection, we're # all done.
#
if [ "$1" != "test" ] && [ "$1" != "dump" ] && [ -z "$DEVICE" ] \

          && [ x"$WANCONNECTION" != xADSL ] \
          && [ x"$WANCONNECTION" != xDiald ]; then
      exit 0

fi
#
# Get the remote IP address for this machine. #
# If the caller wants to do a test using a particular IP address that they # supply, we'll let them do that now. #
# Otherwise, we either get the external IP address of the PPP connection, # if this is a PPP-type connection, or we call the WANIP Perl script to get # this machine's WAN IP address from the perspective of remote servers on # the Internet, if this machine is connected through an edge router. #
if [ "$1" = "test" ]; then

      IPAddr=$2
  else
      if [ -z "$DEVICE" ]; then
          IPAddr=`/sbin/ifconfig ppp0 | grep "inet addr" | \
              sed "s/ *inet addr://;s/ P-t-P:.//"`
      else
          IPAddr=`/etc/dyndns/WANIP.pl`
      fi

fi
#
# If the caller is just trying to force new copies of the dynamic Web pages # up to the appropriate servers or just wants to dump the dynamic Web pages # for debugging porpoises, do that and exit. #
if [ "$1" = "force" ] || [ "$1" = "dump" ]; then

      #
      # Create either an index page or a redirect page, with our IP address
      # in it.  Either send it to our Web host or dump it on stdout.
      #
      if [ x"$DynPageType" = xclone ]; then
          MakeWebPage xyz123 welcome.html 8180
      else
          MakeRedirectPage 8180
      fi
      if [ "$1" = "dump" ]; then
          cat /etc/dyndns/web_page
      else
          #
          # Note that FTP doesn't set any return code if the connection times
          # out.  Thus, we can't detect any errors by testing the return code.
          # Instead, we capture the output and look for the error string.
          #
          FTPResp=`echo -e "user xyz123 letmein\\nput \
              /etc/dyndns/web_page public_html/welcome.html" | \
              ftp -n members.myisp.net 2>&1`
          echo $FTPResp | grep -q "timed out"
          FTPVal=$?
          if [ $FTPVal = 0 ]; then
              echo "Looks like the FTP to myisp didn't work so good"
          fi
      fi
      exit 0

fi
#
# If the caller just wants to notify no-ip of the new address, do that and # exit.
#
if [ "$1" = "noip" ]; then

      if [ -x /etc/dyndns/noip ]; then
          /etc/dyndns/noip -i $IPAddr -c /etc/dyndns/no-ip.conf
      fi
      exit 0

fi
#
# If the external IP address isn't new, we can get out now. #
if (! IsIPNew $IPAddr); then

      exit 0

fi
#
# FTP either the welcome page or a redirect page, with our IP address in # it, to xyz123 at myisp.
#
FTPMY=""

     if (IsConnected members.myisp.net); then
         if [ x"$DynPageType" = xclone ]; then
             MakeWebPage xyz123 welcome.html 8180
         else
             MakeRedirectPage 8180
         fi
      FTPResp=`echo -e "user xyz123 letmein\\nput \
          /etc/dyndns/web_page public_html/welcome.html" | \
          ftp -n members.myisp.net 2>&1`
      echo $FTPResp | grep -q "timed out"
      FTPVal=$?
      if [ $FTPVal = 0 ]; then
          FTPMY="FTP"
      fi
  else
      FTPMY="not connected"

fi
#
# FTP the IP address to Domain1. This way, we can always find it, even # if no-ip is down.
#
FTPDM1=""

     if (IsConnected ftp ftp.domain1.com); then
         echo $IPAddr:8280 >/etc/dyndns/web_ip
      FTPResp=`echo -e "user xxxxx yyyyyy\\nput \
          /etc/dyndns/web_ip www/mysys.dyn" | \
          ftp -n ftp ftp.domain1.com 2>&1`
      echo $FTPResp | grep -q "timed out"
      FTPVal=$?
      if [ $FTPVal = 0 ]; then
          FTPDM1="FTP"
      fi
  else
      FTPDM1="not connected"

fi
#
# FTP the IP address to Domain2. This way, we can always find it, # even if no-ip is down.
#
FTPDM2=""

     if (IsConnected ftp ftp.domain2.com); then
         echo $IPAddr:8380 >/etc/dyndns/web_ip
      FTPResp=`echo -e "user xxxxx yyyyyy\\nput \
          /etc/dyndns/web_ip www/mysys.dyn" | \
          ftp -n ftp ftp.domain2.com 2>&1`
      echo $FTPResp | grep -q "timed out"
      FTPVal=$?
      if [ $FTPVal = 0 ]; then
          FTPDM2="FTP"
      fi
  else
      FTPDM2="not connected"

fi
#
# Notify no-ip of the new address.
#
if [ -x /etc/dyndns/noip ]; then

      if [ "$1" = "test" ]; then
          /etc/dyndns/noip -l -i $IPAddr -c /etc/dyndns/no-ip.conf
      else
          /etc/dyndns/noip -i $IPAddr -c /etc/dyndns/no-ip.conf
      fi

fi
#
# Check to see if all of the FTPs went well. #
if [ x"$FTPMY" = x ] && [ x"$FTPDM1" = x ] && [ x"$FTPDM2" = x ]; then

      if [ -f /etc/dyndns/current_ip ]; then
          cp -f /etc/dyndns/current_ip /etc/dyndns/previous_ip
      fi
  else
      #
      # Construct a status message.
      #
      FTPStr=""
      if [ x"$FTPMY" != x ]; then
          FTPStr="${FTPStr}FTP of home page to members.myisp.net failed \
              (${FTPMY})"$'\n'
      fi
      if [ x"$FTPDM2" != x ]; then
          FTPStr="${FTPStr}Push of IP address to domain1.com failed \
              (${FTPDM2})"$'\n'
      fi
      if [ x"$FTPDM1" != x ]; then
          FTPStr="${FTPStr}Push of IP address to domain2.com failed \
              (${FTPDM1})"$'\n'
      fi
      HostStr=`hostname -s`
      #
      # Email the message to root-ski.
      #
      /bin/mail -s "Problem with PropagateIP" root <<-ENDMSG
          The PropagateIP script, running on $HostStr, seeems to have
          encountered a problem with one or more of the servers that it
          contacts.  Here is a synopsis:
          ${FTPStr}
          To rerun the script, after you correct any errors, you should
          delete the /etc/dyndns/previous_ip file (if it exists) and then
          run /etc/dyndns/PropagateIP.
          ENDMSG
      exit 1

fi

     exit 0

Note: be sure to use tabs on the beginning of the lines between <<-ENDMSG and ENDMSG (including ENDMSG itself).

/etc/ppp/no-ip.conf:

If you are using no-ip.com to point to your Web site, the config file for the noip program (invoked in the PropagteIP script) should look something like this.

     LOGIN    = user@host.com
     PASSWORD = mypass
     GROUP    = ;
     HOSTNAME = user-webserv
     DOMAIN   = zapto.org
     DAEMON   = N
     PROXY    = Y
     INTERVAL = 10
     NAT      = Y
     DEVICE   = unused

/etc/ppp/ip-up or ip-up.local:

You'll need to hack this script if you use PPP or some other non-permanent link to run the PropagateIP script (above). Add the following lines near the end of the file:

.

       .

#
# Set up all of the dynamically addressed Web server links and advertise # our WAN IP address.
#
/etc/dyndns/PropagateIP

/etc/crontab:

If your system is situated behind an edge router or you just want to ensure that your external address is always up to date (even if the ip-up call fails), you can add something like this to crontab:

     #
     # Every couple of hours, propagate this system's WAN IP address to the
     # external servers that need to know what it is.  Note that this only does
     # something if this system is directly connected to the Internet via an
     # edge router or PPP link.  And, the propagation of the IP address is only
     # carried out if the WAN IP address has changed since the last time.
     # Consequently, it is harmless to run this command every couple of hours,
     # and on systems that are not the primary system in a cluster.
     #
     19 0,2,4,6,8,10,12,14,16,18,20,22 * * * root /etc/dyndns/PropagateIP