diff --git a/binder/admin.py b/binder/admin.py index d2814c1..7d9de54 100644 --- a/binder/admin.py +++ b/binder/admin.py @@ -14,6 +14,15 @@ class BindServerAdminForm(ModelForm): 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): form = BindServerAdminForm list_display = ['hostname', 'statistics_port', 'default_transfer_key'] diff --git a/binder/helpers.py b/binder/helpers.py index 02877ee..a2aa9eb 100644 --- a/binder/helpers.py +++ b/binder/helpers.py @@ -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): """Delete a list of DNS records passed as strings in rr_items.""" + server = models.BindServer.objects.get(hostname=dns_server) + try: transfer_key = models.Key.objects.get(name=key_name) except models.Key.DoesNotExist: @@ -99,7 +101,7 @@ def delete_record(dns_server, rr_list, key_name): domain = record_list[1] dns_update = dns.update.Update(domain, keyring=keyring, keyalgorithm=algorithm) 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, "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): """ Update/Create DNS record of name and type with passed data and ttl. """ + server = models.BindServer.objects.get(hostname=dns_server) + try: transfer_key = models.Key.objects.get(name=key_name) 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.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 @@ -144,7 +148,7 @@ def ip_info(host_name): 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. Args: @@ -157,7 +161,7 @@ def send_dns_update(dns_message, dns_server, key_name): """ try: - output = dns.query.tcp(dns_message, dns_server) + output = dns.query.tcp(dns_message, dns_server, port=port) except dns.tsig.PeerBadKey: output = ("DNS server %s is not configured for TSIG key: %s." % (dns_server, key_name)) diff --git a/binder/migrations/0002_bindserver_dns_port.py b/binder/migrations/0002_bindserver_dns_port.py new file mode 100644 index 0000000..ffec852 --- /dev/null +++ b/binder/migrations/0002_bindserver_dns_port.py @@ -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, + ), + ] diff --git a/binder/models.py b/binder/models.py index 3ae2693..8083feb 100644 --- a/binder/models.py +++ b/binder/models.py @@ -63,6 +63,12 @@ class BindServer(models.Model): hostname = models.CharField(max_length=255, unique=True, 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 on.") default_transfer_key = models.ForeignKey(Key, @@ -115,7 +121,11 @@ class BindServer(models.Model): algorithm = transfer_key.algorithm 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: # The incorrect TSIG key was selected for transfers. raise exceptions.TransferException("Unable to list zone records because of a TSIG key mismatch.")