Saturday, April 1, 2017

Amazon AWS Lambda function to update DNS-O-Matic

Overview


Here's the Amazon AWS Lambda function code to update your IP address in the services you have defined (other than OpenDNS) in DNS-O-Matic. DNS-O-Matic does have an API you can use directly (https://www.dnsomatic.com/wiki/api), but if you want to do some other stuff with your IP address (sending via mail or text message, call some other function etc.), Lambda function can help you with that.

DNS-O-Matic does not update OpenDNS (3.4.2017) but throws the following error (because you are coming from AWS instead of a computer in you own network):
"The IP Address you have supplied to DNS-O-Matic differs from the IP Address that you are coming from. OpenDNS does not allow you to update to an IP Address that you don't actually own.".
This behavior has been reported to DNS-O-Matic and hopefully in the future there's a way to update OpenDNS from AWS as well.

Instructions


You can see your Lambda function log (if using us-east-1) in https://console.aws.amazon.com/cloudwatch/home?region=us-east-1#logs:

1. Get Serverless from https://serverless.com/
2. Create Amazon AWS account.
3. Put the code in the handler.js -file.
4. Edit the serverless.yml -file



3. "serverless deploy -r us-east-1 -s prod", you'll get [Lambda function ID] (see Command to call the Lambda function)

Command to call the Lambda function:

"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe" -ExecutionPolicy unrestricted -Command "(New-Object Net.WebClient).DownloadString('https://[Lambda function ID].execute-api.us-east-1.amazonaws.com/prod/updatednsomatic?username=[your DNS-O-Matic username]&password=[your DNS-O-Matic password]&hostname=[your hostname or value 'all'])"

Lambda function code (handler.js):

'use strict';
module.exports.updatednsomatic = (event, context, callback) => {
   
    var sSourceIPAddr = event.requestContext.identity.sourceIp;
    //User's values from GET request
    var sUser = event.queryStringParameters.username;
    var sPwd = event.queryStringParameters.password;
    var sMyHostNameToUpdate = event.queryStringParameters.hostname;
    //Don't change this
    var sDNSOMaticHost = 'updates.dnsomatic.com';
    var sAuthorization = 'Basic ' + new Buffer(sUser + ':' + sPwd).toString('base64');
    var sPath = '';
    if (sMyHostNameToUpdate === 'all') {
        sPath = '/nic/update?';
    } else {
        sPath = '/nic/update?hostname=' + sMyHostNameToUpdate + '&';
    }
    sPath = sPath + 'myip=' + sSourceIPAddr + '&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG';
    console.log('Path: ' + sPath);
    var https = require('https');
    var optionsGET = {
        host: sDNSOMaticHost,
        path: sPath,
        method: 'GET',
        headers: {
            Authorization: sAuthorization
        }
    };
    var reqGET = https.get(optionsGET, (res) => {
        res.setEncoding('utf8');
        console.log('Updating IP: ' + sSourceIPAddr);
        res.on('data', (d) => {
            console.log('Response from DNS-O-Matic: ' + d);
        });
    });
    const response = {
        statusCode: 200,
        body: JSON.stringify({
            ip: sSourceIPAddr,
            username: sUser,
            hostname: sMyHostNameToUpdate,
        }),
    };
    callback(null, response);
};