Post

AWS - boto3 - router53client


router53


example


update53 - DynDNS with AWS Route53

please go to the link for the origin git repo, below is just a copy of it.

ref: update53-pub

update AWS Route53 record by your current public ip (from ipinfo.io web service)

  1. requirements
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# install boto3
sudo pip install boto3

# IAM Role attached to your EC2 instance or IAM User with AccessKey/SecretKey

# SNS Topic (Alerting purpose)

# Configure your server with AWS CLI : aws configure with your AccessKey ID and SecretAccess ID
aws configure

# Create your AWS Route 53 Zone first

# create your DNS A Record to update (home.example.com)

# Configure your server with AWS CLI : aws configure with your AccessKey ID and SecretAccess ID

$ git clone https://github.com/z0ph/update53-pub.git
$ cd update53-pub/python/
$ sudo pip install -r requirements.txt

  1. run
1
2
3
4
5
6
7
8
9
# syntax:
update53.py [YOUR_HOSTED_ZONE_ID] [YOUR_DNS] -b [YOUR_BUCKET_NAME]

# Example with only Route53
Run python update53.py ZLJT68NZ2IYSF home.example.com

# Example with S3 Bucket
Run python update53.py ZLJT68NZ2IYSF home.example.com -b privatewebsite.example.com
  1. the code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# update53.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from sys import exit
from requests import get
import boto3
import json
from botocore.exceptions import ClientError as BotoClientError
import argparse
import datetime

__version__ = '0.3'
__author__ = 'Victor GRENU'
__license__ = "GPLv3+"
__maintainer__ = "Victor GRENU"
__email__ = "victor.grenu@gmail.com"

# GetIp Function
def getIp():
	'''
    Simple function to get your ip, using ipinfo.co
	API and JSON and then update your AWS Route53 DNS A Record
    '''
	return(get(('https://ipinfo.io')).json()['ip'])

# Arguments Parser
parser = argparse.ArgumentParser(description="Update your AWS Route53 A record and S3 Bucket Policy with your new public IP address")
parser._action_groups.pop()
required = parser.add_argument_group('required arguments')
optional = parser.add_argument_group('optional arguments')

# Required args
required.add_argument('id', help='AWS Route53\'s hosted-zone-id hosting your A record')
required.add_argument('dns', help='AWS Route53\'s A record you want to update')

# Optional args
optional.add_argument('-b','--b','-bucket','--bucket', dest='bucket', help='S3 Bucket Name to update permissions (Bucket Policy)')
optional.add_argument('-v', '--version', action='version', version="%(prog)s - "+ __version__ +"")

args = vars(parser.parse_args())

# Missing Args Checker
if not args['id']:
	parser.print_help()
	exit(1)

if not args['dns']:
	parser.print_help()
	exit(1)


# setup the Variables
r53client = boto3.client('route53')
snsclient = boto3.client('sns')
hostedZoneId = args['id']
currentIp = getIp()
date = datetime.datetime.now().strftime("%d-%m-%y-%H:%M")
myRecord = args['dns']

# --------- unit test: Check Hosted Zone ID exist -----------
try:
	hz = r53client.get_hosted_zone(Id=hostedZoneId)

except BotoClientError:
	print(date + " - Hosted-Zone-ID " + hostedZoneId + " is incorrect.")
	exit(1)




# Get old IP from API Call (not DNS resolution)
try:
  record = r53client.list_resource_record_sets(
    HostedZoneId=hostedZoneId,
    StartRecordType='A',
    StartRecordName=myRecord,
    MaxItems="1"
)

except BotoClientError:
	print(date + " - A Record " + myRecord + " does not exist.")
	exit(1)



# Set Variable oldIP
oldIp = record['ResourceRecordSets'][0]['ResourceRecords'][0]['Value']



# Try to update route53
try:
    if oldIp != currentIp:
        message = {"Update53 - New IP set to": currentIp}
        input = r53client.change_resource_record_sets(
            HostedZoneId=hostedZoneId,
            ChangeBatch={
                'Comment': date,
                'Changes': [
                    {
                        'Action': 'UPSERT',
                        'ResourceRecordSet': {
                            'Name': myRecord,
                            'Type': 'A',
                            'TTL': 60,
                            'ResourceRecords': [{'Value': currentIp},],
                        },
                    },
                ]
            }
        )
        print(date + " - Current IP: " +currentIp+ " was successfully updated to Route53. Old was: " + oldIp)

        # Publish Alert to sns topic if ip change
        response = sns.publish(
            TargetArn='arn:aws:sns:eu-west-1:567589703415:Alert-me',
            Message=json.dumps({'default': json.dumps(message)}),
            MessageStructure='json'
        )
    else:
        print(date + " - Current IP: " +currentIp+ " is equal to old IP: " +oldIp+ ". Nothing to do with Route53.")

except BotoClientError:
	print(date + " - Malformed IP Address:", oldIp)
	exit(1)

# Try to update bucket policy
try:
    if oldIp != currentIp:
        s3 = boto3.client('s3')
        bucket_name = args['bucket']
        # Create the bucket policy
        bucket_policy = {
            'Version': '2012-10-17',
            'Statement': [{
                'Sid': 'AddPerm',
                'Effect': 'Allow',
                'Principal': '*',
                'Action': ['s3:GetObject'],
                'Resource': "arn:aws:s3:::%s/*" % bucket_name,
                'Condition': {'IpAddress': {'aws:SourceIp': [''+ currentIp + '/32']}}
            }]
        }
        # Convert the policy to a JSON string
        bucket_policy = json.dumps(bucket_policy)

        # Set the new policy on the given bucket
        s3.put_bucket_policy(Bucket=bucket_name, Policy=bucket_policy)
        print(date + " - Bucket Policy of S3 Bucket: " +bucket_name+ " was successfully updated")
    else:
        print(date + " - Current IP: " +currentIp+ " is equal to old IP: " +oldIp+ ". Nothing to do with the S3 bucket policy.")

except BotoClientError:
		print(date + " - Malformed Bucket Name:", bucket_name)
		exit(1)

exit(0)

.

This post is licensed under CC BY 4.0 by the author.

Comments powered by Disqus.