Fill new DNS zone update policy by default

For security reasons, dynamic updates are not enabled for new DNS
zones. In order to enable the dynamic zone securely, user needs to
allow dynamic updates and create a zone update policy.

The policy is not easy to construct for regular users, we should
rather fill it by default and let users just switch the policy
on or off.

https://fedorahosted.org/freeipa/ticket/2441
This commit is contained in:
Martin Kosek 2012-06-04 17:53:34 +02:00
parent 7d9abecbb6
commit c06cbb12ac
7 changed files with 60 additions and 14 deletions

View File

@ -1014,7 +1014,7 @@ option: Int('idnssoaexpire', attribute=True, autofill=True, cli_name='expire', d
option: Int('idnssoaminimum', attribute=True, autofill=True, cli_name='minimum', default=3600, maxvalue=10800, minvalue=0, multivalue=False, required=True)
option: Int('dnsttl', attribute=True, cli_name='ttl', multivalue=False, required=False)
option: StrEnum('dnsclass', attribute=True, cli_name='class', multivalue=False, required=False, values=(u'IN', u'CS', u'CH', u'HS'))
option: Str('idnsupdatepolicy', attribute=True, cli_name='update_policy', multivalue=False, required=False)
option: Str('idnsupdatepolicy', attribute=True, autofill=True, cli_name='update_policy', multivalue=False, required=False)
option: Bool('idnsallowdynupdate', attribute=True, autofill=True, cli_name='dynamic_update', default=False, multivalue=False, required=False)
option: Str('idnsallowquery', attribute=True, autofill=True, cli_name='allow_query', default=u'any;', multivalue=False, required=False)
option: Str('idnsallowtransfer', attribute=True, autofill=True, cli_name='allow_transfer', default=u'none;', multivalue=False, required=False)

View File

@ -79,4 +79,4 @@ IPA_DATA_VERSION=20100614120000
# #
########################################################
IPA_API_VERSION_MAJOR=2
IPA_API_VERSION_MINOR=37
IPA_API_VERSION_MINOR=38

View File

@ -32,7 +32,8 @@ from ipalib.parameters import Flag, Bool, Int, Decimal, Str, StrEnum, Any
from ipalib.plugins.baseldap import *
from ipalib import _, ngettext
from ipalib.util import (validate_zonemgr, normalize_zonemgr,
validate_hostname, validate_dns_label, validate_domain_name)
validate_hostname, validate_dns_label, validate_domain_name,
get_dns_forward_zone_update_policy, get_dns_reverse_zone_update_policy)
from ipapython.ipautil import valid_ip, CheckedIPAddress, is_host_resolvable
from ldap import explode_dn
@ -75,8 +76,11 @@ EXAMPLES:
--admin-email=admin@example.com
Modify the zone to allow dynamic updates for hosts own records in realm EXAMPLE.COM:
ipa dnszone-mod example.com --dynamic-update=TRUE \\
--update-policy="grant EXAMPLE.COM krb5-self * A; grant EXAMPLE.COM krb5-self * AAAA;"
ipa dnszone-mod example.com --dynamic-update=TRUE
This is the equivalent of:
ipa dnszone-mod example.com --dynamic-update=TRUE \\
--update-policy="grant EXAMPLE.COM krb5-self * A; grant EXAMPLE.COM krb5-self * AAAA; grant EXAMPLE.COM krb5-self * SSHFP;"
Modify the zone to allow zone transfers for local network only:
ipa dnszone-mod example.com --allow-transfer=10.0.0.0/8
@ -1510,6 +1514,12 @@ def dns_container_exists(ldap):
return False
return True
def default_zone_update_policy(zone):
if zone_is_reverse(zone):
return get_dns_reverse_zone_update_policy(api.env.realm, zone)
else:
return get_dns_forward_zone_update_policy(api.env.realm)
class dnszone(LDAPObject):
"""
DNS Zone, container for resource records.
@ -1611,6 +1621,8 @@ class dnszone(LDAPObject):
cli_name='update_policy',
label=_('BIND update policy'),
doc=_('BIND update policy'),
default_from=lambda idnsname: default_zone_update_policy(idnsname),
autofill=True
),
Bool('idnszoneactive?',
cli_name='zone_active',

View File

@ -427,11 +427,11 @@ def parse_time_duration(value):
return duration
def gen_dns_update_policy(realm, rrtypes=('A', 'AAAA', 'SSHFP')):
def get_dns_forward_zone_update_policy(realm, rrtypes=('A', 'AAAA', 'SSHFP')):
"""
Generate update policy for a DNS zone (idnsUpdatePolicy attribute). Bind
uses this policy to grant/reject access for client machines trying to
dynamically update their records.
Generate update policy for a forward DNS zone (idnsUpdatePolicy
attribute). Bind uses this policy to grant/reject access for client
machines trying to dynamically update their records.
:param realm: A realm of the of the client
:param rrtypes: A list of resource records types that client shall be
@ -445,6 +445,27 @@ def gen_dns_update_policy(realm, rrtypes=('A', 'AAAA', 'SSHFP')):
return policy
def get_dns_reverse_zone_update_policy(realm, reverse_zone, rrtypes=('PTR',)):
"""
Generate update policy for a reverse DNS zone (idnsUpdatePolicy
attribute). Bind uses this policy to grant/reject access for client
machines trying to dynamically update their records.
:param realm: A realm of the of the client
:param reverse_zone: Name of the actual zone. All clients with IPs in this
sub-domain will be allowed to perform changes
:param rrtypes: A list of resource records types that client shall be
allowed to update
"""
policy_element = "grant %(realm)s krb5-subdomain %(zone)s %(rrtype)s"
policies = [ policy_element \
% dict(realm=realm, zone=reverse_zone, rrtype=rrtype) \
for rrtype in rrtypes ]
policy = "; ".join(policies)
policy += ";"
return policy
def validate_rdn_param(ugettext, value):
try:
rdn = RDN(value)

View File

@ -32,7 +32,8 @@ from ipapython import sysrestore
from ipapython import ipautil
from ipalib.constants import DNS_ZONE_REFRESH
from ipalib.parameters import IA5Str
from ipalib.util import validate_zonemgr, normalize_zonemgr, gen_dns_update_policy
from ipalib.util import (validate_zonemgr, normalize_zonemgr,
get_dns_forward_zone_update_policy, get_dns_reverse_zone_update_policy)
from ipapython.ipa_log_manager import *
import ipalib
@ -185,7 +186,7 @@ def read_reverse_zone(default, ip_address):
def add_zone(name, zonemgr=None, dns_backup=None, ns_hostname=None, ns_ip_address=None,
update_policy=None):
if update_policy is None:
update_policy = gen_dns_update_policy(api.env.realm)
update_policy = get_dns_forward_zone_update_policy(api.env.realm)
if zonemgr is None:
zonemgr = 'hostmaster.%s' % name
@ -229,7 +230,7 @@ def add_reverse_zone(zone, ns_hostname=None, ns_ip_address=None,
ns_replicas=[], update_policy=None, dns_backup=None):
zone = normalize_zone(zone)
if update_policy is None:
update_policy = "grant %s krb5-subdomain %s PTR;" % (api.env.realm, zone)
update_policy = get_dns_reverse_zone_update_policy(api.env.realm, zone)
if ns_hostname is None:
# automatically retrieve list of DNS masters

View File

@ -70,9 +70,9 @@ class update_dnszones(PostUpdate):
# do not open zone transfers by default
update['idnsallowtransfer'] = u'none;'
old_policy = util.gen_dns_update_policy(api.env.realm, ('A', 'AAAA'))
old_policy = util.get_dns_forward_zone_update_policy(api.env.realm, ('A', 'AAAA'))
if zone.get('idnsupdatepolicy', [''])[0] == old_policy:
update['idnsupdatepolicy'] = util.gen_dns_update_policy(\
update['idnsupdatepolicy'] = util.get_dns_forward_zone_update_policy(\
api.env.realm)
if update:

View File

@ -145,6 +145,10 @@ class test_dns(Declarative):
'idnssoaexpire': [fuzzy_digits],
'idnssoaminimum': [fuzzy_digits],
'idnsallowdynupdate': [u'FALSE'],
'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; '
u'grant %(realm)s krb5-self * AAAA; '
u'grant %(realm)s krb5-self * SSHFP;'
% dict(realm=api.env.realm)],
'idnsallowtransfer': [u'none;'],
'idnsallowquery': [u'any;'],
'objectclass': [u'top', u'idnsrecord', u'idnszone'],
@ -202,6 +206,10 @@ class test_dns(Declarative):
'idnssoaexpire': [fuzzy_digits],
'idnssoaminimum': [fuzzy_digits],
'idnsallowdynupdate': [u'FALSE'],
'idnsupdatepolicy': [u'grant %(realm)s krb5-self * A; '
u'grant %(realm)s krb5-self * AAAA; '
u'grant %(realm)s krb5-self * SSHFP;'
% dict(realm=api.env.realm)],
'idnsallowtransfer': [u'none;'],
'idnsallowquery': [u'any;'],
'objectclass': [u'top', u'idnsrecord', u'idnszone'],
@ -293,6 +301,8 @@ class test_dns(Declarative):
'idnssoaexpire': [fuzzy_digits],
'idnssoaminimum': [fuzzy_digits],
'idnsallowdynupdate': [u'FALSE'],
'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;'
% dict(realm=api.env.realm, zone=revdnszone1)],
'idnsallowtransfer': [u'none;'],
'idnsallowquery': [u'any;'],
'objectclass': [u'top', u'idnsrecord', u'idnszone'],
@ -929,6 +939,8 @@ class test_dns(Declarative):
'idnssoaexpire': [fuzzy_digits],
'idnssoaminimum': [fuzzy_digits],
'idnsallowdynupdate': [u'FALSE'],
'idnsupdatepolicy': [u'grant %(realm)s krb5-subdomain %(zone)s PTR;'
% dict(realm=api.env.realm, zone=revdnszone1)],
'idnsallowtransfer': [u'none;'],
'idnsallowquery': [u'any;'],
'objectclass': [u'top', u'idnsrecord', u'idnszone'],