You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
Brett Woodruff 106024bcb4
Inital Commit
6 months ago
Function Source Files Inital Commit 6 months ago
On Prem Client Agent/AWS_DDNS Inital Commit 6 months ago
AWS-DDNS.zip Inital Commit 6 months ago
Function.zip Inital Commit 6 months ago
README.md Inital Commit 6 months ago

README.md

Simple Dynamic DNS Client for AWS Route53

This Dynamic DNS client for AWS Route53 hosted DNS utilizes a lambda function to update the DNS records for a single hosted zone.

The script is designed in fashion that it will only call the AWS Lambda function to execute in the event that your public ip address has changed since the last time the script is ran. This limits the lambda function execution to only when needed, which saves money, as you will only be charged for when the function is actually executed.

If multiple hosted zone updates are need, you can simply copy the "On Prem Client" files to multiple directories, like:

/opt/DDNS/domain1 /opt/DDNS/domain2 /opt/DDNS/domain3

Edit the setting.conf file located in each instance of the script that you placed in the different subdirectories. And create multiple cron table entries pointing to the different iteration of the script. This will then allow you to have multiple different hosted zones being updated, and will use the same AWS Lambda function (Only 1 lambda function deployed in AWS) as the scripts will all be calling the same lambda function to push updates. You'll simply run the aws_ddns_update.py script from each sub-directory to update each respective hosted zone.

Requirements

AWS

  • A DNS Zone (domain) hosted in AWS Route53
  • Domain is pointed to use AWS's Nameservers (If your domain is registered with AWS also, this would be default).
  • Domain and sub-domain "A" records defined within AWS Hosted Zone that will be updated via these scripts.
  • An AWS IAM Group for the Service Account
  • AWSLambdaRole AWS Managed role attached to the AWS IAM Group
  • AWS IAM user to use as a AWS-CLI service account
  • Auth Token generated within AWS IAM for the serivces user account AWS IAM user (Noting the Key and Secret that is generated, you will need it when setting up AWS-CLI on th on-prem host).
  • Service account AWS IAM user added to the AWS IAM Group for service account.

On-Prem Host

  • An on premises host to run the "On Prem" script from that has internet access. (I use a small dedicated Ubuntu container located on my proxmox cluster).
  • Python installed
  • Python Modules installed -- requests -- boto3 -- os -- json -- datetime -- configparser
  • AWS-CLI installed on the "On-Prem" host
  • AWS-CLI auth setup to use the Auth-Token Key and Secret for service account as the default profile.

Installation / Setup

AWS Lambda Function

There are two items associated with the lambda function here. there is a zip file named Function.zip. This is the archived AWS Lambda Function code we will need to put into place within AWS Lambda.

Note: You can unzip the archive as normal and inspect it's contents for nefarious code, should you choose to. The function itself is called function.py within the archive, and the rest of the files and folders are supporting code for the function such as python modules that set up the entire lambda function environment when it's ran.

Creation of The Lambda Function

  • Within AWS Lambda, create a new function. -- Select Author from Scratch -- Define the functions's name (Note: remember this, you'll need it later.) -- Define the runtime as Python 3.9 -- Click Create Function
  • Along the right-hand side of the page you'll see a Upload From drop down box. Select it, and click .zip file. -- Locate and select the included Function.zip and upload.
  • Now go to AWS IAM and along the left hand menu, select Roles. -- WIthin the list given, look for the role that begins with the name you game your lamda function and click on it. -- Along the right-hand side you'll see an Add Permissions button. Select it, and then click on Create Inline Policy. We will need to give the lambda function explicit permission to interact with Route53's domains. -- Along the top right corner of the page, click json -- Paste this json code: { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "route53:ChangeResourceRecordSets", "Resource": "arn:aws:route53:::hostedzone/*" }, { "Effect": "Allow", "Action": [ "route53:ListHostedZones", "route53:ListResourceRecordSets" ], "Resource": "*" } ] } -- At the bottom right-hand corner of the page, click Next -- Define a name for the inline policy. -- At the bottom right-hand corner of the page select Create Policy.

The permissions defined within the above inline policy gives the lambda function the explicit permission to modify existing recordsets of any hosted zone within associated AWS account.

The lambda function setup is now complete.

On-Prem Host

  • On the on-prem host, copy the entire folder named aws_ddns and it's contents that is located within the On Prem Client Agent folder to your on premises machine.
  • Within the AWS_DDNS folder there is a settings.conf file. Edit this file and define the following parameters. -- function_name: Lambda Function name defined earlier in AWS -- HostedZoneId: The Zone ID for the hosted zone. (Found in the Route53 zone details) -- TTL: The Time to Live setting (In seconds) to set the "A" records to when updating. Set this to the same schedule that you'll be running the script. -- domain_list: A comma separated list of the domain/sub-domains records you wish to update (No Spaces between domain names. (EXAMPLE: example.com,domain1.example.com,domain2.example.com -- Edit the cron table and add the follwing entry: */5 * * * * /usr/bin/python3 {PathToFiles}/aws_ddns/aws_ddns_update.py >> /opt/aws_ddns/dns_updates.log 2>&1 -- Edit the cron schedule portion of the entry to match the TTL time you listed in settings.conf (The */5 of the cron entry denotes 5 minutes or 300 seconds. -- Edit the {PathToFiles} portion of the entry to match the location where you placed the files. Such as /root. and save the cron table.

Usage

Right now the script should be ran auto-magically at the interval you set in the cron table. but the script can be called at any time manually also.

Operation

First run:

  • The on-prem script will check the public IP address associated with the location of the on-prem host.
  • It then will invoke the lambda function to update the domain's IP address and the TTL , of the hosted zone that matches the HostZoneID defined also within settings.conf.
  • It then will write the public IP address found to a file named last_ip in the same directory as the script.
  • if the first run was ran via cron, all the output will be written to a logfile named: dns_updates.log in the same directory as the script.
  • If the script is manually ran, the output is only to the terminal.

Subsequent runs:

  • The on-prem script will check the public IP address associated with the location of the on-prem host.
  • If the file last_ip does not exist, or the public IP found does not match the entry within last_ip: -- It then will invoke the lambda function to update the domain's IP address and the TTL , of the hosted zone that matches the HostZoneID defined also within settings.conf. -- It then will write/update the public IP address found to a file named last_ip in the same directory as the script.
  • If the public IP found matches the entry within last_ip -- The lambda function will NOT be invoked, and domains will not be updated.

Logging

  • if the script run was ran via cron, all the output will be written to a logfile named: dns_updates.log in the same directory as the script.
  • If the script is manually ran, the output is only to the terminal.

AWS Charges

The costs associated with the lambda function deployed should be negligible as it will only be invoked when there is a change of IP detected, or if the last_ip file is deleted, essentially making the script believe it's the first time it's ran. So the cost should be free depending on the schedule that your ISP changes your IP address since the lambda function is only called "If" there is a change detected. With Lambda being within the "Free Tier" if the total invocations are below 1,000,000/Mo and the total runtime of those invocations are below 400,000 Seconds/Mo total, there should be any charges. The lambda function in most cases I've encountered take about 2 seconds to update about 8 domain records.

Powered by BW's shoe-string budget.