mirror of
https://github.com/cwinfo/powerdns-admin.git
synced 2024-12-30 15:05:39 +00:00
dyndns: accept and validate both A and AAAA records; default to client address
This commit is contained in:
parent
5b88ec58ec
commit
98f1e96d1a
@ -2,6 +2,7 @@ import re
|
|||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
import hashlib
|
import hashlib
|
||||||
|
import ipaddress
|
||||||
|
|
||||||
from app import app
|
from app import app
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
@ -291,3 +292,14 @@ def display_setting_state(value):
|
|||||||
return "OFF"
|
return "OFF"
|
||||||
else:
|
else:
|
||||||
return "UNKNOWN"
|
return "UNKNOWN"
|
||||||
|
|
||||||
|
|
||||||
|
def validate_ipaddress(address):
|
||||||
|
try:
|
||||||
|
ip = ipaddress.ip_address(address)
|
||||||
|
except ValueError:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if isinstance(ip, (ipaddress.IPv4Address, ipaddress.IPv6Address)):
|
||||||
|
return [ip]
|
||||||
|
return []
|
||||||
|
@ -1666,7 +1666,7 @@ class Record(object):
|
|||||||
jrecords = jdata['records']
|
jrecords = jdata['records']
|
||||||
|
|
||||||
for jr in jrecords:
|
for jr in jrecords:
|
||||||
if jr['name'] == self.name:
|
if jr['name'] == self.name and jr['type'] == self.type:
|
||||||
self.name = jr['name']
|
self.name = jr['name']
|
||||||
self.type = jr['type']
|
self.type = jr['type']
|
||||||
self.status = jr['disabled']
|
self.status = jr['disabled']
|
||||||
|
80
app/views.py
80
app/views.py
@ -5,6 +5,7 @@ import traceback
|
|||||||
import re
|
import re
|
||||||
import datetime
|
import datetime
|
||||||
import json
|
import json
|
||||||
|
import ipaddress
|
||||||
from distutils.util import strtobool
|
from distutils.util import strtobool
|
||||||
from distutils.version import StrictVersion
|
from distutils.version import StrictVersion
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
@ -1742,6 +1743,11 @@ def dyndns_update():
|
|||||||
hostname = request.args.get('hostname')
|
hostname = request.args.get('hostname')
|
||||||
myip = request.args.get('myip')
|
myip = request.args.get('myip')
|
||||||
|
|
||||||
|
if not hostname:
|
||||||
|
history = History(msg="DynDNS update: missing hostname parameter", created_by=current_user.username)
|
||||||
|
history.add()
|
||||||
|
return render_template('dyndns.html', response='nohost'), 200
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# get all domains owned by the current user
|
# get all domains owned by the current user
|
||||||
domains = User(id=current_user.id).get_domain()
|
domains = User(id=current_user.id).get_domain()
|
||||||
@ -1765,37 +1771,51 @@ def dyndns_update():
|
|||||||
history.add()
|
history.add()
|
||||||
return render_template('dyndns.html', response='nohost'), 200
|
return render_template('dyndns.html', response='nohost'), 200
|
||||||
|
|
||||||
r = Record()
|
myip_addr = []
|
||||||
r.name = hostname
|
if myip:
|
||||||
# check if the user requested record exists within this domain
|
for address in myip.split(','):
|
||||||
if r.exists(domain.name) and r.is_allowed_edit():
|
myip_addr += utils.validate_ipaddress(address)
|
||||||
if r.data == myip:
|
|
||||||
# record content did not change, return 'nochg'
|
|
||||||
history = History(msg="DynDNS update: attempted update of {0} but record did not change".format(hostname), created_by=current_user.username)
|
|
||||||
history.add()
|
|
||||||
return render_template('dyndns.html', response='nochg'), 200
|
|
||||||
else:
|
|
||||||
oldip = r.data
|
|
||||||
result = r.update(domain.name, myip)
|
|
||||||
if result['status'] == 'ok':
|
|
||||||
history = History(msg='DynDNS update: updated record {0} in zone {1}, it changed from {2} to {3}'.format(hostname,domain.name,oldip,myip), detail=str(result), created_by=current_user.username)
|
|
||||||
history.add()
|
|
||||||
return render_template('dyndns.html', response='good'), 200
|
|
||||||
else:
|
|
||||||
return render_template('dyndns.html', response='911'), 200
|
|
||||||
elif r.is_allowed_edit():
|
|
||||||
ondemand_creation = DomainSetting.query.filter(DomainSetting.domain == domain).filter(DomainSetting.setting == 'create_via_dyndns').first()
|
|
||||||
if (ondemand_creation != None) and (strtobool(ondemand_creation.value) == True):
|
|
||||||
record = Record(name=hostname,type='A',data=myip,status=False,ttl=3600)
|
|
||||||
result = record.add(domain.name)
|
|
||||||
if result['status'] == 'ok':
|
|
||||||
history = History(msg='DynDNS update: created record {0} in zone {1}, it now represents {2}'.format(hostname,domain.name,myip), detail=str(result), created_by=current_user.username)
|
|
||||||
history.add()
|
|
||||||
return render_template('dyndns.html', response='good'), 200
|
|
||||||
|
|
||||||
history = History(msg='DynDNS update: attempted update of {0} but it does not exist for this user'.format(hostname), created_by=current_user.username)
|
remote_addr = utils.validate_ipaddress(request.headers.get('X-Forwarded-For', request.remote_addr).split(', ')[:1])
|
||||||
history.add()
|
|
||||||
return render_template('dyndns.html', response='nohost'), 200
|
response='nochg'
|
||||||
|
for ip in myip_addr or remote_addr:
|
||||||
|
if isinstance(ip, ipaddress.IPv4Address):
|
||||||
|
rtype='A'
|
||||||
|
else:
|
||||||
|
rtype='AAAA'
|
||||||
|
|
||||||
|
r = Record(name=hostname,type=rtype)
|
||||||
|
# check if the user requested record exists within this domain
|
||||||
|
if r.exists(domain.name) and r.is_allowed_edit():
|
||||||
|
if r.data == str(ip):
|
||||||
|
# record content did not change, return 'nochg'
|
||||||
|
history = History(msg="DynDNS update: attempted update of {0} but record did not change".format(hostname), created_by=current_user.username)
|
||||||
|
history.add()
|
||||||
|
else:
|
||||||
|
oldip = r.data
|
||||||
|
result = r.update(domain.name, str(ip))
|
||||||
|
if result['status'] == 'ok':
|
||||||
|
history = History(msg='DynDNS update: updated {0} record {1} in zone {2}, it changed from {3} to {4}'.format(rtype,hostname,domain.name,oldip,str(ip)), detail=str(result), created_by=current_user.username)
|
||||||
|
history.add()
|
||||||
|
response='good'
|
||||||
|
else:
|
||||||
|
response='911'
|
||||||
|
break
|
||||||
|
elif r.is_allowed_edit():
|
||||||
|
ondemand_creation = DomainSetting.query.filter(DomainSetting.domain == domain).filter(DomainSetting.setting == 'create_via_dyndns').first()
|
||||||
|
if (ondemand_creation is not None) and (strtobool(ondemand_creation.value) == True):
|
||||||
|
record = Record(name=hostname,type=rtype,data=str(ip),status=False,ttl=3600)
|
||||||
|
result = record.add(domain.name)
|
||||||
|
if result['status'] == 'ok':
|
||||||
|
history = History(msg='DynDNS update: created record {0} in zone {1}, it now represents {2}'.format(hostname,domain.name,str(ip)), detail=str(result), created_by=current_user.username)
|
||||||
|
history.add()
|
||||||
|
response='good'
|
||||||
|
else:
|
||||||
|
history = History(msg='DynDNS update: attempted update of {0} but it does not exist for this user'.format(hostname), created_by=current_user.username)
|
||||||
|
history.add()
|
||||||
|
|
||||||
|
return render_template('dyndns.html', response=response), 200
|
||||||
|
|
||||||
|
|
||||||
@app.route('/', methods=['GET', 'POST'])
|
@app.route('/', methods=['GET', 'POST'])
|
||||||
|
Loading…
Reference in New Issue
Block a user