-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfltr-iana-allocated-v6.py
executable file
·159 lines (140 loc) · 5.59 KB
/
fltr-iana-allocated-v6.py
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
#!/usr/bin/python
# IPv6 RPSL object updater
# Written by Job Snijders <[email protected]> in June 2012
configuration = { 'email_from': '[email protected]',
'filtername': 'AS15562:fltr-iana-allocated-v6',
'email_to': '[email protected]',
'gpg_keyid': 'C46D1B1C',
'mnt_by': ('SNIJDERS-ROBOT-MNT', 'SNIJDERS-MNT'),
'admin_c': 'JWJS1-RIPE',
'tech_c': 'JWJS1-RIPE',
'org': 'ORG-SNIJ1-RIPE',
'gpg_homedir': '/home/job/.gnupg' }
import sys
import urllib2
from BeautifulSoup import BeautifulStoneSoup
import datetime, pytz, time
import ipaddr
import gnupg
import smtplib
from email.mime.text import MIMEText
# todo:
# - do whois on current object and compare how much it differs from new one
# whois code: http://code.activestate.com/recipes/577364-whois-client/
print "+--------------------------------------------------------------------------+"
print "+ IPv6 IANA Allocated updater:"
print """+ This program will attempt to fetch up2date allocations list from IANA,
+ parse it, sign it, upload it to the RIPE IRR DB."""
print "+--------------------------------------------------------------------------+"
try:
print 'progress: dowloading list...'
f = urllib2.urlopen('http://www.iana.org/assignments/ipv6-unicast-address-assignments/ipv6-unicast-address-assignments.xml')
except:
print 'error: downloading prefix list failed'
sys.exit(1)
utc = pytz.timezone("UTC")
unixtimestamp = str(int(time.time()))
timestamp = str(datetime.datetime.now(tz=utc))
timestamp = unixtimestamp + ' - ' + timestamp
print 'timestamp: ' + timestamp
# fetch all ALLOCATED entries
###
#<registry xmlns="http://www.iana.org/assignments" id="ipv6-unicast-address-assignments">
# <title>IPv6 Global Unicast Address Assignments</title>
# <updated>2012-05-30</updated>
# <description>The allocation of Internet Protocol version 6 (IPv6) unicast address space
# </description>
# <note>The assignable Global Unicast Address space is defined in...
# </note>
# <record date="1999-07-01">
# <prefix>2001:0000::/23</prefix>
# <description>IANA</description>
# <whois>whois.iana.org</whois>
# <status>ALLOCATED</status>
# <xref type="note" data="1"/>
# </record>
###
valid_prefixes = []
registry = BeautifulStoneSoup(f)
iana_stamp = registry.updated.contents[0]
for record in registry('record'):
if record.status.contents[0] == 'ALLOCATED':
prefix = record.prefix.contents[0]
description = record.description.contents[0]
date = record['date']
if prefix == '2001:4600::/23':
found_magic_prefix = True
try:
if ipaddr.IPv6Network(prefix):
new_entry = { 'prefix': prefix, 'descr': description, 'date': date }
valid_prefixes.append(new_entry)
except ValueError:
print 'entry is not valid: %s' % record.prefix.contents[0]
pass
amount = len(valid_prefixes)
if amount < 30 :
print "error: we expect more than 40 prefixes"
sys.exit(1)
else:
print "pass: seems we have enough prefixes"
# - contains 2001:4600::/23
if found_magic_prefix is True:
print "pass: 2001:4600::/23 is in the list"
else:
print "error: the list seems corrupt, 2001:4600::/23 is missing"
sys.exit(1)
# loop through all the valid entries
# add some RPSL suger (we accept up to /16 and no smaller than /48)
# make sure the last entry doesn't end with a comma
formatted_prefixes = str()
networksize = "^16-48"
for filter_entry in valid_prefixes:
if filter_entry is not valid_prefixes[-1]:
string = "\t%s%s,\t# %s - %s\n" % (filter_entry['prefix'], networksize, filter_entry['descr'], filter_entry['date'])
formatted_prefixes += string
else:
string = "\t%s%s\t# %s - %s\n" % (filter_entry['prefix'], networksize, filter_entry['descr'], filter_entry['date'])
formatted_prefixes += string
# construct object
# RPSL object:
header = """filter-set: """ + configuration['filtername'] + """
descr: All IPv6 prefixes IANA has allocated to the RIRs
mp-filter: {
"""
maintainers = ""
for maintainer in configuration['mnt_by']:
maintainers += "mnt-by: " + maintainer + "\n"
footer = """ }
remarks: last IANA update: """ + iana_stamp + """
remarks: filter generated: """ + timestamp + """
remarks: source www.iana.org/assignments/ipv6-unicast-address-assignments/ipv6-unicast-address-assignments.xml
remarks: this object is automatically updated the first day of every month
org: """ + configuration['org'] + """
tech-c: """ + configuration['tech_c'] + """
admin-c: """ + configuration['admin_c'] + """
""" + maintainers + """changed: """ + configuration['email_from'] + """
source: RIPE"""
rpslobject = header + formatted_prefixes + footer
# sign with PGPKEY-C46D1B1C on irime
gpg = gnupg.GPG(gnupghome=configuration['gpg_homedir'])
try:
signed_rpslobject = str(gpg.sign(rpslobject,keyid=configuration['gpg_keyid'],clearsign=True))
print "pass: signed the new object"
except:
print "error: something went wrong with signing"
sys.exit(1)
# email to [email protected]
msg = MIMEText(signed_rpslobject, 'plain')
msg['Subject'] = 'IPv6 Bogons: %s' % timestamp
msg['From'] = configuration['email_from']
msg['To'] = configuration['email_to']
s = smtplib.SMTP('localhost')
try:
print signed_rpslobject
s.sendmail(configuration['email_from'], configuration['email_to'], msg.as_string())
s.quit()
print "pass: sent the email succesfully to the MTA"
print "done: a new version has been uploaded"
except:
print "error: Unable to send email. Error: %s" % str(e)
sys.exit(1)