Make the port for DNS queries per server configurable.
While it might not be that common to have a DNS server listening on a non-standard port for DNS queries, it's also useful for local testing. I used the opportunity to add model migrations as well to enable smooth model upgrades.
This commit is contained in:
parent
8082262871
commit
77eda58f37
|
@ -14,6 +14,15 @@ class BindServerAdminForm(ModelForm):
|
||||||
return self.cleaned_data["statistics_port"]
|
return self.cleaned_data["statistics_port"]
|
||||||
|
|
||||||
|
|
||||||
|
def clean_dns_port(self):
|
||||||
|
port = self.cleaned_data["dns_port"]
|
||||||
|
if port < 1 or port > 65535:
|
||||||
|
raise ValidationError("Invalid port number %(port)s. Please enter "
|
||||||
|
"a valid one between 1 and 65535.",
|
||||||
|
params={'port': port})
|
||||||
|
return self.cleaned_data["dns_port"]
|
||||||
|
|
||||||
|
|
||||||
class BindServerAdmin(admin.ModelAdmin):
|
class BindServerAdmin(admin.ModelAdmin):
|
||||||
form = BindServerAdminForm
|
form = BindServerAdminForm
|
||||||
list_display = ['hostname', 'statistics_port', 'default_transfer_key']
|
list_display = ['hostname', 'statistics_port', 'default_transfer_key']
|
||||||
|
|
|
@ -83,6 +83,8 @@ def add_cname_record(dns_server, zone_name, cname, originating_record, ttl, key_
|
||||||
def delete_record(dns_server, rr_list, key_name):
|
def delete_record(dns_server, rr_list, key_name):
|
||||||
"""Delete a list of DNS records passed as strings in rr_items."""
|
"""Delete a list of DNS records passed as strings in rr_items."""
|
||||||
|
|
||||||
|
server = models.BindServer.objects.get(hostname=dns_server)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
transfer_key = models.Key.objects.get(name=key_name)
|
transfer_key = models.Key.objects.get(name=key_name)
|
||||||
except models.Key.DoesNotExist:
|
except models.Key.DoesNotExist:
|
||||||
|
@ -99,7 +101,7 @@ def delete_record(dns_server, rr_list, key_name):
|
||||||
domain = ".".join(record_list[1:])
|
domain = ".".join(record_list[1:])
|
||||||
dns_update = dns.update.Update(domain, keyring=keyring, keyalgorithm=algorithm)
|
dns_update = dns.update.Update(domain, keyring=keyring, keyalgorithm=algorithm)
|
||||||
dns_update.delete(record)
|
dns_update.delete(record)
|
||||||
output = send_dns_update(dns_update, dns_server, key_name)
|
output = send_dns_update(dns_update, dns_server, server.dns_port, key_name)
|
||||||
|
|
||||||
delete_response.append({ "description" : "Delete Record: %s" % current_rr,
|
delete_response.append({ "description" : "Delete Record: %s" % current_rr,
|
||||||
"output" : output })
|
"output" : output })
|
||||||
|
@ -109,6 +111,8 @@ def delete_record(dns_server, rr_list, key_name):
|
||||||
def create_update(dns_server, zone_name, record_name, record_type, record_data, ttl, key_name):
|
def create_update(dns_server, zone_name, record_name, record_type, record_data, ttl, key_name):
|
||||||
""" Update/Create DNS record of name and type with passed data and ttl. """
|
""" Update/Create DNS record of name and type with passed data and ttl. """
|
||||||
|
|
||||||
|
server = models.BindServer.objects.get(hostname=dns_server)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
transfer_key = models.Key.objects.get(name=key_name)
|
transfer_key = models.Key.objects.get(name=key_name)
|
||||||
except models.Key.DoesNotExist:
|
except models.Key.DoesNotExist:
|
||||||
|
@ -120,7 +124,7 @@ def create_update(dns_server, zone_name, record_name, record_type, record_data,
|
||||||
|
|
||||||
dns_update = dns.update.Update(zone_name, keyring=keyring, keyalgorithm=algorithm)
|
dns_update = dns.update.Update(zone_name, keyring=keyring, keyalgorithm=algorithm)
|
||||||
dns_update.replace(record_name, ttl, record_type, record_data)
|
dns_update.replace(record_name, ttl, record_type, record_data)
|
||||||
output = send_dns_update(dns_update, dns_server, key_name)
|
output = send_dns_update(dns_update, dns_server, server.dns_port, key_name)
|
||||||
|
|
||||||
return output
|
return output
|
||||||
|
|
||||||
|
@ -144,7 +148,7 @@ def ip_info(host_name):
|
||||||
|
|
||||||
return info
|
return info
|
||||||
|
|
||||||
def send_dns_update(dns_message, dns_server, key_name):
|
def send_dns_update(dns_message, dns_server, port, key_name):
|
||||||
""" Send DNS message to server and return response.
|
""" Send DNS message to server and return response.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
|
@ -157,7 +161,7 @@ def send_dns_update(dns_message, dns_server, key_name):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
output = dns.query.tcp(dns_message, dns_server)
|
output = dns.query.tcp(dns_message, dns_server, port=port)
|
||||||
except dns.tsig.PeerBadKey:
|
except dns.tsig.PeerBadKey:
|
||||||
output = ("DNS server %s is not configured for TSIG key: %s." %
|
output = ("DNS server %s is not configured for TSIG key: %s." %
|
||||||
(dns_server, key_name))
|
(dns_server, key_name))
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='BindServer',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
|
('hostname', models.CharField(help_text=b'Host name or IP address of the BIND server.', unique=True, max_length=255)),
|
||||||
|
('statistics_port', models.IntegerField(help_text=b'Port where the BIND server is serving statistics on.')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['hostname'],
|
||||||
|
},
|
||||||
|
bases=(models.Model,),
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='Key',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||||
|
('name', models.CharField(help_text=b'A human readable name for the key to store, used for further references to the key.', unique=True, max_length=255)),
|
||||||
|
('data', models.CharField(help_text=b'The private part of the TSIG key.', max_length=255)),
|
||||||
|
('algorithm', models.CharField(help_text=b'The algorithm which has been used for the key.', max_length=255, choices=[(b'HMAC-MD5.SIG-ALG.REG.INT', b'MD5'), (b'hmac-sha1', b'SHA1'), (b'hmac-sha256', b'SHA256'), (b'hmac-sha384', b'SHA384'), (b'hmac-sha512', b'SHA512')])),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['name'],
|
||||||
|
},
|
||||||
|
bases=(models.Model,),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='bindserver',
|
||||||
|
name='default_transfer_key',
|
||||||
|
field=models.ForeignKey(blank=True, to='binder.Key', help_text=b'The default key to use for all actions with this DNS server as long as no other key is specified explicitly.', null=True),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,20 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import models, migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('binder', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='bindserver',
|
||||||
|
name='dns_port',
|
||||||
|
field=models.IntegerField(default=53, verbose_name='DNS port', help_text=b'The port where the BIND server is listening for DNSrequests. binder especially uses that port for the dynamic zone updates. In most cases you should always leave it at the default port 53.'),
|
||||||
|
preserve_default=True,
|
||||||
|
),
|
||||||
|
]
|
|
@ -63,6 +63,12 @@ class BindServer(models.Model):
|
||||||
hostname = models.CharField(max_length=255,
|
hostname = models.CharField(max_length=255,
|
||||||
unique=True,
|
unique=True,
|
||||||
help_text="Host name or IP address of the BIND server.")
|
help_text="Host name or IP address of the BIND server.")
|
||||||
|
dns_port = models.IntegerField(default=53,
|
||||||
|
verbose_name="DNS port",
|
||||||
|
help_text="The port where the BIND server is listening for DNS "
|
||||||
|
"requests. binder especially uses that port for the dynamic "
|
||||||
|
"zone updates. In most cases you should always leave it at the "
|
||||||
|
"default port 53.")
|
||||||
statistics_port = models.IntegerField(help_text="Port where the BIND server is serving "
|
statistics_port = models.IntegerField(help_text="Port where the BIND server is serving "
|
||||||
"statistics on.")
|
"statistics on.")
|
||||||
default_transfer_key = models.ForeignKey(Key,
|
default_transfer_key = models.ForeignKey(Key,
|
||||||
|
@ -115,7 +121,11 @@ class BindServer(models.Model):
|
||||||
algorithm = transfer_key.algorithm
|
algorithm = transfer_key.algorithm
|
||||||
|
|
||||||
try:
|
try:
|
||||||
zone = dns.zone.from_xfr(dns.query.xfr(self.hostname, zone_name, keyring=keyring, keyalgorithm=algorithm))
|
zone = dns.zone.from_xfr(dns.query.xfr(self.hostname,
|
||||||
|
zone_name,
|
||||||
|
port=self.dns_port,
|
||||||
|
keyring=keyring,
|
||||||
|
keyalgorithm=algorithm))
|
||||||
except dns.tsig.PeerBadKey:
|
except dns.tsig.PeerBadKey:
|
||||||
# The incorrect TSIG key was selected for transfers.
|
# The incorrect TSIG key was selected for transfers.
|
||||||
raise exceptions.TransferException("Unable to list zone records because of a TSIG key mismatch.")
|
raise exceptions.TransferException("Unable to list zone records because of a TSIG key mismatch.")
|
||||||
|
|
Loading…
Reference in New Issue