15 January 2015

Using Tasker to Update a Google Domains Dynamic DNS Record

Google Domains left its private beta on Tuesday (in the US, at least) making it possible for "normal" folks to sign up for the service - no invite required.  The announcement included a lot of new features as well but the most interesting for me was the inclusion of support for dynamic DNS.  I became even more excited when I scrolled further down and saw that Google included an API for updating the DDNS record with a specially-crafted HTTP GET or POST request.

This immediately got me thinking about Tasker, and I set to work on a Tasker-driven method for automatically updating a DDNS record for my phone.  This serves no real purpose for me (yet) but it was a bit of fun to work out.





This page has the full details on how to create a Dynamic DNS synthetic record on your Google Domains-registered domain.  Each of these dynamic synthetic records will have a subdomain/hostname (that you specify) as well as an auto-generated username+password pair.  Once created, you should be able to put the pieces together to make an HTTP request that looks like this:

https://username:password@domains.google.com/nic/update?hostname=subdomain.yourdomain.com&myip=1.2.3.4


That's the easy part.  The fun part is getting it into Tasker:
Note: This profile doesn't require root but it does depend upon busybox to provide the "nslookup" command.



Don't worry, I'll break this description down a bit by line number - and maybe even include some images if you're nice:


  1. Profile: DynDNS
    The name given to the profile.
  2. Notification: no
    This profile will be a "fire-and-forget" sort of thing, so I don't want an ongoing notification when it's active.
  3. State: Wifi Connected [ SSID:* MAC:* IP:* ]
    I'm going to attempt to update DynDNS when connected to Wifi.
  4. Enter: DDNS
    Name of the Enter (and only) Task.
  5. A1: Wait [ MS:0 Seconds:5 Minutes:0 Hours:0 Days:0 ]
    Wait 5 seconds after connecting to Wifi (to allow time to receive local DHCP IP and establish Internet connection).
  6. A2: HTTP Get [ Server:Port:http://ipv4.icanhazip.com/ Path: Attributes: Cookies: User Agent: Timeout:20 Mime Type: Output File: Trust Any Certificate:Off ]
    Connect to a dead-simple service for resolving the phone's public-facing IP. icanhazip.com returns just the IP address in plain-text with no filler, which means I don't have to do any crazy string parsing (yay!).  Tasker automatically stores the returned data of an HTTP GET request into the global variable %HTTPD.  Only the Server:Port field is required.

  7. A3: If [ %HTTPD !~ %PUB_IP ]
    I don't want to run the rest of the task (and submit repeated DynDNS updates) if the current public IP matches what I've already registered.  I store the current IP in the %PUB_IP variable.  For this If statement, I'm just checking to see if the HTTP GET return does not match the value of %PUB_IP.  If TRUE (if it doesn't match), I run the rest of the Task; if FALSE (if it does match), I just skip to the end.

  8. A4: Variable Set [ Name:%PUB_IP To:%HTTPD Do Maths:Off Append:Off ]
    Store the public IP as %PUB_IP.

  9. A5: HTTP Post [ Server:Port:https://username:password@domains.google.com Path:/nic/update?hostname=nexusXXXXX.codesplice.net&myip=%PUB_IP Data / File: Cookies: User Agent: Timeout:10 Content Type: Output File: Trust Any Certificate:Off ]
    This is the heavy lifter.  Username and password should be the autogenerated values obtained from Google's Dynamic DNS Synthetic Records Creator Thing - NOT your Google credentials (pls).  Replace nexusXXXXX.codesplice.net with your DynDNS record's subdomain (duh).



  10. A6: Wait [ MS:0 Seconds:0 Minutes:2 Hours:0 Days:0 ]
    I'm feeling patient, so let's wait two minutes before we check to see if the DNS change has propagated.

  11. A7: Variable Set [ Name:%newline To:
  12. Do Maths:Off Append:Off ] Set the local %newline variable to a newline character (carriage return - just press Enter on your Android keyboard).  This will come in handy shortly.

  13. A8: Run Shell [ Command:nslookup nexusXXXXX.codesplice.net Timeout (Seconds):0 Use Root:Off Store Output In:%NSLOOKUP Store Errors In: Store Result In: ]
    Run the nslookup command against the hopefully-updated DynDNS record and store the returned data (command output) in %NSLOOKUP.  The output of nslookup will look something like this:
    Server: google-public-dns-a.google.com
    Address: 8.8.8.8 
    Name: nexusXXXXX.codesplice.net
    Address: 71.228.X.X 


  14. A9: Variable Split [ Name:%NSLOOKUP Splitter:%newline Delete Base:Off ] Split the variable %NSLOOKUP into multiple variables at each newline character.  We're really only interested in the last two lines of the nslookup output.

  15. A10: Notify [ Title:%NSLOOKUP4 Text:%NSLOOKUP5 Icon:hd_ab_navigation_accept Number:0 Permanent:Off Priority:1 ] Create a low-priority notification to display the name of the DynDNS record (%NSLOOKUP4) and the public-facing IP (%NSLOOKUP5).


  16. A11: Variable Clear [ Name:%NSLOOKUP* Pattern Matching:On ]
    Clean up some of the variable mess.
  17. A12: End If
    FIN.
So now, my phone will have a nice dynamic DNS record any time that it's connected to a Wifi network.  What will I do with this? Not a clue! But hey, it was a fun little project.