-
-
Save bmacauley/1ae11430ca02a9e51dd8f1fcf49e2c13 to your computer and use it in GitHub Desktop.
Dynamic DNS using AWS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Run this script as a cron job on a machine inside your network that is always on | |
# Prerequisites: | |
# - Python | |
# - boto3 module for AWS access | |
# - Route 53 DNS hosted zone that you use as the target | |
# - SNS topic to send notifications when the DNS is updated (IP changed) | |
# | |
# Assumes that you have the AWS configuration directory available (~/.aws/) | |
# with a default profile that has API access Route 53 and SNS access | |
import boto3 # Boto3 library for AWS access | |
import requests # Library for making HTTP requests | |
import socket # LIbrary for DNS resolution | |
HOSTZONE = 'AWS_DNS_HOSTED_ZONE_ID' # AWS hosted zone ID | |
subject = "" # SNS subject variable | |
message = "" # SNS message body variable | |
bastion_dns = 'bastion.example.com.' # DNS hostname to be updated | |
sns_topic_arn = arn:aws:sns:<region>:<accoundid>:<SNS_Topic_Name> # The ARN of the SNS topic for notifications | |
# Create a custom Boto3 session using the default profile | |
boto3.setup_default_session(profile_name='default') | |
# Retrieve the current IP address of the bastion DNS hostname | |
current_bastion_ip = socket.gethostbyname(bastion_dns) | |
# Get the current IP address of the local host (using AWS checkip address) | |
current_local_ip = requests.get('http://checkip.amazonaws.com').text.rstrip() | |
# Route 53 Update Record Set request, with the appropriate IP address and DNS | |
batch = { | |
'Comment': 'Changed by update-dns.py', | |
'Changes': [ { | |
'Action': 'UPSERT', | |
'ResourceRecordSet': { | |
'Name': bastion_dns, 'Type': 'A', 'TTL': 60, 'ResourceRecords': [ { 'Value': current_local_ip }, ] | |
} | |
} ] | |
} | |
# If the IP returned by the DNS check is different from the current IP address | |
if current_bastion_ip != current_local_ip: | |
# Create a route53 client session | |
client = boto3.client('route53') | |
# Request an update to the DNS using the batch dict defined earlier | |
resp = client.change_resource_record_sets(HostedZoneId=HOSTZONE,ChangeBatch=batch) | |
# Get the status of the request | |
status = resp['ChangeInfo']['Status'] | |
# Set the SNS subject name and message | |
subject = "DNS for " + bastion_dns + " changed" | |
message = "DNS (" + bastion_dns + ") changed from " + current_bastion_ip + " to " + current_local_ip + "\n" | |
message = message + "Status: " + status + "\n" | |
# Create an SNS resource and Topic object | |
sns = boto3.resource('sns') | |
topic = sns.Topic(sns_topic_arn) | |
# Send the message to the topic | |
snsresp = topic.publish(Subject=subject,Message=message) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment