From 6a2dfde086bdda62964a9737a300818d2ab24a4b Mon Sep 17 00:00:00 2001 From: Martin Kosek Date: Aug 31 2011 14:46:12 +0000 Subject: Let Bind track data changes Integrate new bind-dyndb-ldap features to automatically track DNS data changes: 1) Zone refresh Set --zone-refresh in installation to define number of seconds between bind-dyndb-ldap polls for new DNS zones. User now doesn't have to restart name server when a new zone is added. 2) New zone notifications Use LDAP persistent search mechanism to immediately get notification when any new DNS zone is added. Use --zone-notif install option to enable. This option is mutually exclusive with Zone refresh. To enable this functionality in existing IPA installations, update a list of arguments for bind-dyndb-ldap in /etc/named.conf. An example when zone refresh is disabled and DNS data change notifications (argument psearch of bind-dyndb-ldap) are enabled: dynamic-db "ipa" { ... arg "zone_refresh 0"; arg "psearch yes"; }; This patch requires bind-dyndb-ldap-1.0.0-0.1.b1 or later. https://fedorahosted.org/freeipa/ticket/826 --- diff --git a/install/share/bind.named.conf.template b/install/share/bind.named.conf.template index e843b4c..f133b08 100644 --- a/install/share/bind.named.conf.template +++ b/install/share/bind.named.conf.template @@ -44,4 +44,6 @@ dynamic-db "ipa" { arg "auth_method sasl"; arg "sasl_mech GSSAPI"; arg "sasl_user DNS/$FQDN"; + arg "zone_refresh $ZONE_REFRESH"; + arg "psearch $PERSISTENT_SEARCH"; }; diff --git a/install/tools/ipa-dns-install b/install/tools/ipa-dns-install index cf400dd..09006a2 100755 --- a/install/tools/ipa-dns-install +++ b/install/tools/ipa-dns-install @@ -29,6 +29,7 @@ from ipapython import version from ipapython import ipautil, sysrestore from ipalib import api, errors, util from ipapython.config import IPAOptionParser +from ipalib.constants import DNS_ZONE_REFRESH import krbV import ldap @@ -49,6 +50,14 @@ def parse_options(): default=False, help="Do not create reverse DNS zone") parser.add_option("--zonemgr", dest="zonemgr", help="DNS zone manager e-mail address. Defaults to root") + parser.add_option("--zone-notif", dest="zone_notif", + action="store_true", default=False, + help="Let name server receive notification when a new zone is added." \ + "Zone refresh is turned off when zone notification is enabled") + parser.add_option("--zone-refresh", dest="zone_refresh", + default=DNS_ZONE_REFRESH, type="int", + help="A delay between checks for new DNS zones. Defaults to %d" \ + % DNS_ZONE_REFRESH) parser.add_option("-U", "--unattended", dest="unattended", action="store_true", default=False, help="unattended installation never prompts the user") @@ -64,6 +73,12 @@ def parse_options(): if not options.forwarders and not options.no_forwarders: parser.error("You must specify at least one --forwarder option or --no-forwarders option") + if options.zone_refresh < 0: + parser.error("negative numbers not allowed for --zone-refresh") + + if options.zone_notif: # mutually exclusive features + options.zone_refresh = 0 + return safe_options, options def main(): @@ -179,7 +194,10 @@ def main(): print "Please wait until the prompt is returned." print "" - bind.setup(api.env.host, ip_address, api.env.realm, api.env.domain, dns_forwarders, conf_ntp, reverse_zone, zonemgr=options.zonemgr) + bind.setup(api.env.host, ip_address, api.env.realm, api.env.domain, + dns_forwarders, conf_ntp, reverse_zone, zonemgr=options.zonemgr, + zone_refresh=options.zone_refresh, + zone_notif=options.zone_notif) bind.create_instance() diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install index 3828a9c..e8a48fa 100755 --- a/install/tools/ipa-server-install +++ b/install/tools/ipa-server-install @@ -61,6 +61,7 @@ from ipalib.parameters import IA5Str from ipapython.config import IPAOptionParser from ipalib.dn import DN from ipalib.x509 import load_certificate_from_file, load_certificate_chain_from_file +from ipalib.constants import DNS_ZONE_REFRESH pw_name = None uninstalling = False @@ -140,6 +141,14 @@ def parse_options(): parser.add_option("--zonemgr", action="callback", callback=zonemgr_callback, type="string", help="DNS zone manager e-mail address. Defaults to root") + parser.add_option("--zone-notif", dest="zone_notif", + action="store_true", default=False, + help="Let name server receive notification when a new zone is added." \ + "Zone refresh is turned off when zone notification is enabled") + parser.add_option("--zone-refresh", dest="zone_refresh", + default=DNS_ZONE_REFRESH, type="int", + help="A delay between checks for new DNS zones. Defaults to %d" \ + % DNS_ZONE_REFRESH) parser.add_option("-U", "--unattended", dest="unattended", action="store_true", default=False, help="unattended installation never prompts the user") parser.add_option("", "--uninstall", dest="uninstall", action="store_true", @@ -247,6 +256,12 @@ def parse_options(): if not options.pkinit_pkcs12 and not options.selfsign: options.setup_pkinit = False + if options.zone_refresh < 0: + parser.error("negative numbers not allowed for --zone-refresh") + + if options.zone_notif: # these 2 features are mutually exclusive + options.zone_refresh = 0 + return safe_options, options def signal_handler(signum, frame): @@ -992,7 +1007,10 @@ def main(): # Create a BIND instance bind = bindinstance.BindInstance(fstore, dm_password) - bind.setup(host_name, ip_address, realm_name, domain_name, dns_forwarders, options.conf_ntp, reverse_zone, zonemgr=options.zonemgr) + bind.setup(host_name, ip_address, realm_name, domain_name, dns_forwarders, + options.conf_ntp, reverse_zone, zonemgr=options.zonemgr, + zone_refresh=options.zone_refresh, + zone_notif=options.zone_notif) if options.setup_dns: api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=dm_password) diff --git a/install/tools/man/ipa-dns-install.1 b/install/tools/man/ipa-dns-install.1 index e8c53bf..3e98dbe 100644 --- a/install/tools/man/ipa-dns-install.1 +++ b/install/tools/man/ipa-dns-install.1 @@ -49,6 +49,12 @@ Do not create reverse DNS zone \fB\-\-zonemgr\fR The e\-mail address of the DNS zone manager. Defaults too root@host.domain .TP +\fB\-\-zone\-notif\fR +Let name server receive notifications when a new zone is added. New zone is then immediately loaded by the name server. This feature uses an LDAP Persistent Search mechanism to receive the data. Zone refresh is turned off when zone notifications are enabled. +.TP +\fB\-\-zone\-refresh=\fIZONE_REFRESH\fR +Number of seconds between regular checks for new DNS zones. When set to 0 the name server does not check for new zones and it needs to be reloaded when a new DNS zone is added. +.TP \fB\-U\fR, \fB\-\-unattended\fR An unattended installation that will never prompt for user input .SH "EXIT STATUS" diff --git a/install/tools/man/ipa-server-install.1 b/install/tools/man/ipa-server-install.1 index a06b849..0ea8b01 100644 --- a/install/tools/man/ipa-server-install.1 +++ b/install/tools/man/ipa-server-install.1 @@ -88,6 +88,12 @@ Do not create reverse DNS zone \fB\-\-zonemgr\fR The e\-mail address of the DNS zone manager. Defaults to root@host.domain .TP +\fB\-\-zone\-notif\fR +Let name server receive notifications when a new zone is added. New zone is then immediately loaded by the name server. This feature uses an LDAP Persistent Search mechanism to receive the data. Zone refresh is turned off when zone notifications are enabled. +.TP +\fB\-\-zone\-refresh=\fIZONE_REFRESH\fR +Number of seconds between regular checks for new DNS zones. When set to 0 the name server does not check for new zones and it needs to be reloaded when a new DNS zone is added. +.TP \fB\-U\fR, \fB\-\-unattended\fR An unattended installation that will never prompt for user input .TP diff --git a/ipalib/constants.py b/ipalib/constants.py index b4bb86d..6d24628 100644 --- a/ipalib/constants.py +++ b/ipalib/constants.py @@ -195,3 +195,6 @@ DEFAULT_CONFIG = ( ('log', object), # Path to context specific log file ) + +# Default DNS zone refresh interval in seconds (0 = disabled) +DNS_ZONE_REFRESH = 30 diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index 676b1a4..c91b620 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -31,6 +31,7 @@ from ipaserver.install.dsinstance import realm_to_serverid from ipaserver.install.installutils import resolve_host from ipapython import sysrestore from ipapython import ipautil +from ipalib.constants import DNS_ZONE_REFRESH import ipalib from ipalib import api, util, errors @@ -342,7 +343,9 @@ class BindInstance(service.Service): else: self.fstore = sysrestore.FileStore('/var/lib/ipa/sysrestore') - def setup(self, fqdn, ip_address, realm_name, domain_name, forwarders, ntp, reverse_zone, named_user="named", zonemgr=None): + def setup(self, fqdn, ip_address, realm_name, domain_name, forwarders, ntp, + reverse_zone, named_user="named", zonemgr=None, + zone_refresh=DNS_ZONE_REFRESH, zone_notif=False): self.named_user = named_user self.fqdn = fqdn self.ip_address = ip_address @@ -354,6 +357,8 @@ class BindInstance(service.Service): self.suffix = util.realm_to_suffix(self.realm) self.ntp = ntp self.reverse_zone = reverse_zone + self.zone_refresh = zone_refresh + self.zone_notif = zone_notif if zonemgr: self.zonemgr = zonemgr.replace('@','.') @@ -439,7 +444,9 @@ class BindInstance(service.Service): FORWARDERS=fwds, SUFFIX=self.suffix, OPTIONAL_NTP=optional_ntp, - ZONEMGR=self.zonemgr) + ZONEMGR=self.zonemgr, + ZONE_REFRESH=self.zone_refresh, + PERSISTENT_SEARCH=self.zone_notif and "yes" or "no") def __setup_dns_container(self): self._ldap_mod("dns.ldif", self.sub_dict)