bvstone

Why I Cancelled my DynDNS Service and How I Replaced It with an IBM i Application

Posted:

Why I Cancelled my DynDNS Service and How I Replaced It with an IBM i Application

For years I have been using DynDNS for automatic updating of my Domain Name hosts and their IP addresses. I used this because I was in the unfortunate position of not being able to get a static IP address for my business account from my ISP.

The DynDNS service worked great for years.  I would simply install a client on my PC and it would monitor my IP address and update the DNS records hosted by DynDNS when needed.

But, a couple years ago I installed the latest Client (after Oracle bought out DynDNS) and noticed that not only did I have problems installing it, but once it was running it wouldn't automatically update my IP address when it changed.  This wasn't good and caused many issues, as you can imagine.  Most of the time my IP address would change after a power outage.  This was normally at night and being a heavy sleeper I would sleep through it, only to wake up to realize my web sites were down.  With customers accessing my main BVSTools.com site for information, downloads and license keys, this would simply to do and I needed to find a more reliable method of keeping my IP address up to date.  And as they say, if you want something done right, do it yourself.

Seeing as how I've created many Web Service interfaces for RESTful applications ranging from Google to HubSpot to Ebay, I checked and my Domain Registrar (GoDaddy) now has APIs available that will allow me to update my IP addresses using a simple RESTful call to one of their APIs.

In a few hours I had some tests up and running and was successfully:

1.  Retrieving my public IP address using an ILE subprocedure (from https:///api.ipify.org using GETURI, but if this changes it's easy enough to find another provider).

2.  Retrieving the current IP address for my multiple A records from GoDaddy using one of their RESTful APIs

3.  Comparing the two, and if need be, updating the IP addresses.

I then created a CL that runs the program to check and update the IP addresses if needed, checking the status every hour.  Every 10th check a status report is also sent just as a reminder that the application is still running.  (I also did use JOBWATCH to monitor my system to make sure the job is running, and if not send me an email message to let me know).

The program is as follows:

**FREE
ctl-opt DFTACTGRP(*NO) ACTGRP('GODADDY') BNDDIR('GODADDY');

// Imports
/COPY QCOPYSRC,P.GODADDY
/COPY MAILTOOL/QCOPYSRC,P.MAILTOOL
/COPY QCOPYSRC,P.SQL

// Work Variables
dcl-s DNSIP char(256);
dcl-s PublicIP char(256);
dcl-s rc int(10);
dcl-s errorCount int(10);
dcl-s updateCount int(10);
dcl-s runCount int(10);
dcl-s errMsg char(256);
dcl-s emailSubject char(65535);
dcl-s emailBody char(65535);
dcl-s nwBody char(65535);

dcl-ds GDDOMDS extname('GDDOMPF') end-ds;

DNSIP = ' ';
PublicIP = ' ';
rc = 0;
errorCount = 0;
updateCount = 0;
errMsg = ' ';
emailSubject = ' ';
emailBody = ' ';
nwBody = ' ';
runCount += 1;

rc = #gd_getPublicIP(PublicIP:errMsg);

if (rc < 0) or (PublicIP = ' ');
  errMsg = 'Error retrieving Public IP address.';
  exsr $Error;
endif;

exec sql declare C1 cursor for                    
  select GDMDOMAIN, GDMTYPE, GDMNAME from GDDOMPF        
    order by GDMDOMAIN;
    
exec sql open C1;      

exec sql fetch from C1               
   into :GDMDOMAIN, :GDMTYPE, :GDMNAME;         
                                     
dow (xSQLState2 = Success_On_Sql);   

  nwBody = %trim(nwBody) + 
           'Checking Domain ' + %trim(GDMDOMAIN) + 
           ' Type ' + %trim(GDMTYPE) + 
           ' Name ' + %trim(GDMNAME) + '.\n';
              
  rc = #gd_getDNSServerIP(GDMDOMAIN:GDMTYPE:GDMNAME:DNSIP:errMsg);

  nwBody = %trim(nwBody) + 
           'Public: ' + %trim(PublicIP) + '\n' + 
           'DNS: ' + %trim(DNSIP) + '\n'; 

  if (rc < 0);
    exec sql close C1;
    errMsg = 'Error retrieving DNS IP address:' + 
              '\nDomain:' + 
              %trim(GDMDOMAIN) + 
              '\nType:' + 
              %trim(GDMTYPE) +
              '\nName:' + 
              %trim(GDMNAME) + 
              '\n\n' + 
              'Error:' + %trim(errMsg);
    exsr $Error;
  endif;

  if (PublicIP <> DNSIP);
    nwBody = %trim(nwBody) + 
            'Change Required!  Attempting change...\n'; 
    exsr $UpdateIP;
  else;
    nwBody = %trim(nwBody) + 
             'No change needed.\n\n'; 
  endif;
  
  exec sql fetch from C1               
     into :GDMDOMAIN, :GDMTYPE, :GDMNAME;         
enddo;

exec sql close C1;

if (errorCount <= 0) and (updateCount <= 0) and (runCount = 10);
  exsr $NoWorries;
  runCount = 0;
endif;

exsr $Return;

//***************************************************************              
//* Send No Worries Email                                                        
//***************************************************************              
begsr $NoWorries;   

  if (#mailtool_init() >= 0);                                      
    rc = #mailtool_setValue('configuration_file':                  
                            '/bvstools/bvstone_mailtool.json');                     
    rc = #mailtool_loadDefaults();                                 
    rc = #mailtool_addTORecipient('bvstone@bvstools.com');         
    rc = #mailtool_setValue('subject':'IP Address Update Status Report');     
    rc = #mailtool_setValue('message':nwBody);
    rc = #mailtool_sendMail(errMsg);                               
  endif;     
                                                                                
endsr;

//***************************************************************              
//* Update IP Address                                                         
//***************************************************************              
begsr $UpdateIP;   

  updateCount += 1;

  emailBody = 'Domain ' + %trim(GDMDOMAIN) + 
              ' Type ' + %trim(GDMTYPE) + 
              ' Name ' + %trim(GDMNAME) + 
              ' requires an IP address change from ' + 
              %trim(DNSIP) + ' to ' + %trim(PublicIP) + '.';

  rc = #gd_updateDNSServerIP(GDMDOMAIN:GDMTYPE:GDMNAME:PublicIP:errMsg);
  
  if (rc < 0);
    emailSubject = '**ERROR Updating Dynamic IP for ' + %trim(GDMDOMAIN);
    emailBody = %trim(EmailBody) + '\n\n' + 
                'Status: ERROR\n' + 
                'Error Details: ' + %trim(errMsg);
    nwBody = %trim(nwBody) + 
            'Error updating IP Address!\n\n';
  else;
    emailSubject = '**SUCCESS Updating Dynamic IP for ' + %trim(GDMDOMAIN);
    emailBody = %trim(EmailBody) + '\n\n' + 
                'Status: SUCCESS';
    nwBody = %trim(nwBody) + 
            'Change Successful.\n\n';                
  endif;

  if (#mailtool_init() >= 0);                                      
    rc = #mailtool_setValue('configuration_file':                  
                            '/bvstools/bvstone_mailtool.json');                     
    rc = #mailtool_loadDefaults();                                 
    rc = #mailtool_addTORecipient('bvstone@bvstools.com');         
    rc = #mailtool_setValue('subject':emailSubject);     
    rc = #mailtool_setValue('message':emailBody);
    rc = #mailtool_sendMail(errMsg);                               
  endif;     
                                                                                
endsr;

//***************************************************************              
//* Return Error                                                               
//***************************************************************              
begsr $Error;       

  errorCount += 1;
                                                                                 
  if (#mailtool_init() >= 0);                                      
    rc = #mailtool_setValue('configuration_file':                  
                            '/bvstools/bvstone_mailtool.json');                     
    rc = #mailtool_loadDefaults();                                 
    rc = #mailtool_addTORecipient('bvstone@bvstools.com');         
    rc = #mailtool_setValue('subject':'Check DNS Error');      
    rc = #mailtool_setValue('message':errMsg);                   
    rc = #mailtool_sendMail(errMsg);                               
  endif;     
  
  exsr $Return;
                                                                                 
endsr;
  
//***************************************************************
//* Return
//***************************************************************
begsr $Return;

  // we're not setting on *INLR so that we can count and send messages if needed
  //  every 10 hours
  //*INLR = *ON;
  return;

endsr;

As you can see, this isn't very complicated and uses MAILTOOL to send any messages such as errors, successful updates, or simple messages that let me know everything is ok that will be sent every 10 times the application runs.  Because the application is set to run every hour, then every 10 hours I should receive a status email.

The functions starting with #gd_ are the GoDaddy functions I created to specifically deal with GoDaddy's RESTful APIs.  GETURI is used to make the requests, and YAJL is used to build and parse the JSON data, which in this case is very simple.

The following functions are available in the F.GODADDY service program:

  • #gd_getControlValue - Get a Control Value.  These are system wide control values such as the API locations, if Debug is on, etc.   
  • #gd_getDomainControlValue - Get a Domain Level Control Value.  These control values are at the domain level.  This is so that if I ever want to set up this monitor for domains that may be outside of my GoDaddy account, it's as simple as adding them in here.  The main value used here is the API Key and Secret for my account.
  • #gd_getPublicIP - Get Public IP Address.  This function will retrieve the current public IP address for my system.
  • #gd_getDNSServerIP -  Get DNS Server IP Address.  This function will get the currently specified IP address for the domain and host specified (type A records only).         
  • #gd_updateDNSServerIP - Update DNS Server IP Address.   This function will update the current IP address for the domain and host specified (type A records only).

So, the functionality is, at a high level, very simple.  Just get the public IP, get the DNS IP and compare them.  If they are different, issue an update.

If you have any questions feel free to contact us!  We plan on letting this run on our own system for a while before we decide if it will be something we will offer to customers.  


Last edited 07/17/2019 at 11:43:25



Latest Posts:

MAILTOOL Errors with Microsoft Office 365 (2020) MAILTOOL Errors with Microsoft Office 365 (2020)
Posted by September 3, 2020
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Using MAILTOOL With Office 365 and Two Factor Authentication (2FA or MFA) Using MAILTOOL With Office 365 and Two Factor Authentication (2FA or MFA)
Posted by August 17, 2020
BVSTools >> BVSTools Software Discussion >> Email Tools (MAILTOOL) Specific Discussion
Updating DNS With Dynamic IP Addresses After a Router Reboot/Power Outage Updating DNS With Dynamic IP Addresses After a Router Reboot/Power Outage
Posted by August 16, 2020
Programming >> Proof of Concept (POC)
GETURI v10.10 Released with New ILE Functions GETURI v10.10 Released with New ILE Functions
Posted by August 12, 2020
BVSTools >> BVSTools Announcements >> Get URI (GETURI) Specific Announcements
MAILTOOL Updated to Allow G4GSMAIL as Option in Routers File MAILTOOL Updated to Allow G4GSMAIL as Option in Routers File
Posted by June 28, 2020
BVSTools >> BVSTools Announcements >> eMail Tool (MAILTOOL) Specific Announcements
BVSTools Now Offers Interface with Infor's ION APIs BVSTools Now Offers Interface with Infor's ION APIs
Posted by May 15, 2020
BVSTools >> BVSTools Announcements
More V7R4 IFS File CCSID Issues and The Fix More V7R4 IFS File CCSID Issues and The Fix
Posted by March 4, 2020
IBM Power Systems >> (QGPL) IBM i
Error Retrieving IP Address by Name Error Retrieving IP Address by Name
Posted by February 25, 2020
BVSTools >> BVSTools Software Discussion
Logging jobs that hit an outq Logging jobs that hit an outq
Posted by February 13, 2020
Programming >> CL Programming
GreenTools for Google Apps (G4G) v12.60 Released with Shared Drive Features and More... GreenTools for Google Apps (G4G) v12.60 Released with Shared Drive Features and More...
Posted by February 4, 2020
BVSTools >> BVSTools Announcements >> GreenTools for G Suite (Google Apps) (G4G) Specific Announcements
Allowing Requests over Port 80 For SSL Validation (ie, Namecheap, etc) Allowing Requests over Port 80 For SSL Validation (ie, Namecheap, etc)
Posted by January 31, 2020
Programming >> Web Programming
GreenTools for Slack (G4SLK) v3.00 Released GreenTools for Slack (G4SLK) v3.00 Released
Posted by January 17, 2020
BVSTools >> BVSTools Announcements >> GreenTools for Slack (G4SLK) Specific Announcements
Calling a QSH Command from RPG Calling a QSH Command from RPG
Posted by December 26, 2019
Programming >> RPG Programming
SPLTOOL Print Range (PRTRNG) Function Updated to Handle Spooled Files up to 999,999,999 Pages SPLTOOL Print Range (PRTRNG) Function Updated to Handle Spooled Files up to 999,999,999 Pages
Posted by December 14, 2019
BVSTools >> BVSTools Announcements >> Spooled File Tools (SPLTOOL) Specific Announcements
GreenTools for Microsoft Apps (G4MS) Updated to v6.00 - Now Uses Microsoft Graph APIs GreenTools for Microsoft Apps (G4MS) Updated to v6.00 - Now Uses Microsoft Graph APIs
Posted by November 24, 2019
BVSTools >> BVSTools Announcements >> GreenTools for Microsoft Apps (G4MS) Specific Announcements

Reply




Copyright 1983-2020 BVSTools
GreenBoard(v3) Powered by the eRPG SDK, MAILTOOL Plus!, GreenTools for Google Apps, jQuery, jQuery UI, BlockUI, CKEditor and running on the IBM i (AKA AS/400, iSeries, System i).