Dynamic DNS with AWS & .net core

bartron on 1/3/2021

Since AWS has both managed DNS and hostname registration via Route 53, I changed over and re-wrote the DNS auto-updater app to work with AWS instead of Azure.  Here was the result.

The code requires nuget package Amazon.Route53.  The parameters are key and secret, which are from Amazon IAM.  The zone is the zone ID from Route 53, and the host is the A record you want to update.

 

using System;
using System.Collections.Generic;
using System.Net;
using System.Threading.Tasks;
using Amazon.Route53;
using Amazon.Route53.Model;

namespace AutoUpdateDNS
{
    class Updater
    {
        private String key;
        private String secret;
        private String zone;
        private String host;

        public Updater(String key, String secret, String zone, String host)
        {
            this.key = key;
            this.secret = secret;
            this.zone = zone;
            this.host = host;
        }

        public async Task UpdateRecord()
        {
            String currentIP = await GetCurrentIP();
            currentIP = currentIP.Trim();
            System.Console.WriteLine("Currently Assigned: " + currentIP);
            String localIP = new WebClient().DownloadString("http://icanhazip.com").Trim();
            System.Console.WriteLine("Local: " + localIP);
            if(currentIP.Equals(localIP) == false) {
                System.Console.WriteLine("Difference Detected");
                Boolean result = await UpdateIP(localIP);
                if(result) System.Console.WriteLine("Updated to " + localIP);
                else System.Console.WriteLine("Update Failed");
            }
            else {
                System.Console.WriteLine("Everything matches, all good!");
            }
        }

        private async Task<Boolean> UpdateIP(String newIP)
        {
            var route53Client = new AmazonRoute53Client(key, secret, Amazon.RegionEndpoint.CACentral1);
            var rs = new ResourceRecordSet()
            {
                Name = host,
                Type = RRType.A,
                TTL = 300,
                ResourceRecords = new List<ResourceRecord>() { new ResourceRecord() { Value = newIP } }
            };
            var c = new Change()
            {
                ResourceRecordSet = rs,
                Action = ChangeAction.UPSERT
            };
            var r = new ChangeResourceRecordSetsRequest()
            {
                HostedZoneId = zone,
                ChangeBatch = new ChangeBatch()
            };
            r.ChangeBatch.Changes.Add(c);

            await route53Client.ChangeResourceRecordSetsAsync(r, new System.Threading.CancellationToken());
            return true;
        }

        private async Task<String> GetCurrentIP()
        {
            String currentIP = "";
            var route53Client = new AmazonRoute53Client(key, secret, Amazon.RegionEndpoint.CACentral1);
            var r = new ListResourceRecordSetsRequest()
            {
                 HostedZoneId = zone,
                 StartRecordType = "A",
                 StartRecordName = host,
                 MaxItems = "1"
            };
            var rr = await route53Client.ListResourceRecordSetsAsync(r, new System.Threading.CancellationToken());
            if (rr.ResourceRecordSets.Count > 0)
            {
                if (rr.ResourceRecordSets[0].Type.Equals("A") && rr.ResourceRecordSets[0].ResourceRecords.Count > 0)
                {
                    currentIP = rr.ResourceRecordSets[0].ResourceRecords[0].Value;
                }
            }
            return currentIP;
        }
    }
}  

Tags