DNSSEC: opendnssec services
Tickets: https://fedorahosted.org/freeipa/ticket/3801 https://fedorahosted.org/freeipa/ticket/4417 Design: https://fedorahosted.org/bind-dyndb-ldap/wiki/BIND9/Design/DNSSEC Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: David Kupka <dkupka@redhat.com>
This commit is contained in:
1 parent
eb54814741
commit
9101cfa60f
6 files changed
+716
No files matched your search
@@ -56,6 +56,8 @@ app_DATA = \
|
||||
memberof-task.ldif \
|
||||
memberof-conf.ldif \
|
||||
nis.uldif \
|
||||
opendnssec_conf.template \
|
||||
opendnssec_kasp.template \
|
||||
unique-attributes.ldif \
|
||||
schema_compat.uldif \
|
||||
ldapi.ldif \
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- Managed by IPA - do not edit! -->
|
||||
<Configuration>
|
||||
|
||||
<RepositoryList>
|
||||
|
||||
<Repository name="SoftHSM">
|
||||
<Module>$SOFTHSM_LIB</Module>
|
||||
<TokenLabel>$TOKEN_LABEL</TokenLabel>
|
||||
<PIN>$PIN</PIN>
|
||||
<AllowExtraction/>
|
||||
</Repository>
|
||||
|
||||
</RepositoryList>
|
||||
|
||||
<Common>
|
||||
<Logging>
|
||||
<Syslog><Facility>local0</Facility></Syslog>
|
||||
</Logging>
|
||||
|
||||
<PolicyFile>/etc/opendnssec/kasp.xml</PolicyFile>
|
||||
<ZoneListFile>/etc/opendnssec/zonelist.xml</ZoneListFile>
|
||||
|
||||
<!--
|
||||
<ZoneFetchFile>/etc/opendnssec/zonefetch.xml</ZoneFetchFile>
|
||||
-->
|
||||
</Common>
|
||||
|
||||
<Enforcer>
|
||||
<Privileges>
|
||||
<User>ods</User>
|
||||
<Group>ods</Group>
|
||||
</Privileges>
|
||||
|
||||
<Datastore><SQLite>$KASP_DB</SQLite></Datastore>
|
||||
<Interval>PT3600S</Interval>
|
||||
<!-- <ManualKeyGeneration/> -->
|
||||
<!-- <RolloverNotification>P14D</RolloverNotification> -->
|
||||
|
||||
<!-- the <DelegationSignerSubmitCommand> will get all current
|
||||
DNSKEYs (as a RRset) on standard input
|
||||
-->
|
||||
<!-- <DelegationSignerSubmitCommand>/usr/sbin/eppclient</DelegationSignerSubmitCommand> -->
|
||||
</Enforcer>
|
||||
|
||||
</Configuration>
|
||||
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<!--
|
||||
|
||||
NOTE: The default policy below is a TEMPLATE ONLY and should be reviewed
|
||||
before used in any production environment. The administrator should
|
||||
consult the OpenDNSSEC documentation before changing any parameters.
|
||||
|
||||
If you can read this message, it is likely that this file has not
|
||||
been reviewed nor updated.
|
||||
|
||||
-->
|
||||
|
||||
<KASP>
|
||||
|
||||
<Policy name="default">
|
||||
<Description>A default policy that will amaze you and your friends</Description>
|
||||
<Signatures>
|
||||
<Resign>PT2H</Resign>
|
||||
<Refresh>P3D</Refresh>
|
||||
<Validity>
|
||||
<Default>P14D</Default>
|
||||
<Denial>P14D</Denial>
|
||||
</Validity>
|
||||
<Jitter>PT12H</Jitter>
|
||||
<InceptionOffset>PT3600S</InceptionOffset>
|
||||
</Signatures>
|
||||
|
||||
<Denial>
|
||||
<NSEC3>
|
||||
<!-- <TTL>PT0S</TTL> -->
|
||||
<!-- <OptOut/> -->
|
||||
<Resalt>P100D</Resalt>
|
||||
<Hash>
|
||||
<Algorithm>1</Algorithm>
|
||||
<Iterations>5</Iterations>
|
||||
<Salt length="8"/>
|
||||
</Hash>
|
||||
</NSEC3>
|
||||
</Denial>
|
||||
|
||||
<Keys>
|
||||
<!-- Parameters for both KSK and ZSK -->
|
||||
<TTL>PT3600S</TTL>
|
||||
<RetireSafety>PT3600S</RetireSafety>
|
||||
<PublishSafety>PT3600S</PublishSafety>
|
||||
<!-- <ShareKeys/> -->
|
||||
<Purge>P14D</Purge>
|
||||
|
||||
<!-- Parameters for KSK only -->
|
||||
<KSK>
|
||||
<Algorithm length="2048">8</Algorithm>
|
||||
<Lifetime>P1Y</Lifetime>
|
||||
<Repository>SoftHSM</Repository>
|
||||
</KSK>
|
||||
|
||||
<!-- Parameters for ZSK only -->
|
||||
<ZSK>
|
||||
<Algorithm length="2048">8</Algorithm>
|
||||
<Lifetime>P90D</Lifetime>
|
||||
<Repository>SoftHSM</Repository>
|
||||
<!-- <ManualRollover/> -->
|
||||
</ZSK>
|
||||
</Keys>
|
||||
|
||||
<Zone>
|
||||
<PropagationDelay>PT43200S</PropagationDelay>
|
||||
<SOA>
|
||||
<TTL>PT3600S</TTL>
|
||||
<Minimum>PT3600S</Minimum>
|
||||
<Serial>unixtime</Serial>
|
||||
</SOA>
|
||||
</Zone>
|
||||
|
||||
<Parent>
|
||||
<PropagationDelay>PT9999S</PropagationDelay>
|
||||
<DS>
|
||||
<TTL>PT3600S</TTL>
|
||||
</DS>
|
||||
<SOA>
|
||||
<TTL>PT172800S</TTL>
|
||||
<Minimum>PT10800S</Minimum>
|
||||
</SOA>
|
||||
</Parent>
|
||||
|
||||
</Policy>
|
||||
|
||||
<Policy name="lab">
|
||||
<Description>Quick turnaround policy for lab work</Description>
|
||||
<Signatures>
|
||||
<Resign>PT10M</Resign>
|
||||
<Refresh>PT30M</Refresh>
|
||||
<Validity>
|
||||
<Default>PT1H</Default>
|
||||
<Denial>PT1H</Denial>
|
||||
</Validity>
|
||||
<Jitter>PT1M</Jitter>
|
||||
<InceptionOffset>PT3600S</InceptionOffset>
|
||||
</Signatures>
|
||||
|
||||
<Denial>
|
||||
<NSEC/>
|
||||
</Denial>
|
||||
|
||||
<Keys>
|
||||
<!-- Parameters for both KSK and ZSK -->
|
||||
<TTL>PT300S</TTL>
|
||||
<RetireSafety>PT360S</RetireSafety>
|
||||
<PublishSafety>PT360S</PublishSafety>
|
||||
<!-- <ShareKeys/> -->
|
||||
<Purge>P14D</Purge>
|
||||
|
||||
<!-- Parameters for KSK only -->
|
||||
<KSK>
|
||||
<Algorithm length="2048">8</Algorithm>
|
||||
<Lifetime>P1Y</Lifetime>
|
||||
<Repository>SoftHSM</Repository>
|
||||
</KSK>
|
||||
|
||||
<!-- Parameters for ZSK only -->
|
||||
<ZSK>
|
||||
<Algorithm length="2048">8</Algorithm>
|
||||
<Lifetime>PT4H</Lifetime>
|
||||
<Repository>SoftHSM</Repository>
|
||||
<!-- <ManualRollover/> -->
|
||||
</ZSK>
|
||||
</Keys>
|
||||
|
||||
<Zone>
|
||||
<PropagationDelay>PT300S</PropagationDelay>
|
||||
<SOA>
|
||||
<TTL>PT300S</TTL>
|
||||
<Minimum>PT300S</Minimum>
|
||||
<Serial>unixtime</Serial>
|
||||
</SOA>
|
||||
</Zone>
|
||||
|
||||
<Parent>
|
||||
<PropagationDelay>PT9999S</PropagationDelay>
|
||||
<DS>
|
||||
<TTL>PT3600S</TTL>
|
||||
</DS>
|
||||
<SOA>
|
||||
<TTL>PT172800S</TTL>
|
||||
<Minimum>PT10800S</Minimum>
|
||||
</SOA>
|
||||
</Parent>
|
||||
|
||||
</Policy>
|
||||
</KASP>
|
||||
@@ -0,0 +1,40 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import _ipap11helper
|
||||
import random
|
||||
|
||||
def generate_master_key(p11, keylabel=u"dnssec-master", key_length=16,
|
||||
disable_old_keys=True):
|
||||
assert isinstance(p11, _ipap11helper.P11_Helper)
|
||||
|
||||
key_id = None
|
||||
while True:
|
||||
# check if key with this ID exist in LDAP or softHSM
|
||||
# id is 16 Bytes long
|
||||
key_id = "".join(chr(random.randint(0, 255)) for _ in xrange(0, 16))
|
||||
keys = p11.find_keys(_ipap11helper.KEY_CLASS_SECRET_KEY,
|
||||
label=keylabel,
|
||||
id=key_id)
|
||||
if not keys:
|
||||
break # we found unique id
|
||||
|
||||
p11.generate_master_key(keylabel,
|
||||
key_id,
|
||||
key_length=key_length,
|
||||
cka_wrap=True,
|
||||
cka_unwrap=True)
|
||||
|
||||
if disable_old_keys:
|
||||
# set CKA_WRAP=False for old master keys
|
||||
master_keys = p11.find_keys(_ipap11helper.KEY_CLASS_SECRET_KEY,
|
||||
label=keylabel,
|
||||
cka_wrap=True)
|
||||
|
||||
for handle in master_keys:
|
||||
# don't disable wrapping for new key
|
||||
# compare IDs not handle
|
||||
if key_id != p11.get_attribute(handle, _ipap11helper.CKA_ID):
|
||||
p11.set_attribute(handle, _ipap11helper.CKA_WRAP, False)
|
||||
@@ -0,0 +1,179 @@
|
||||
#
|
||||
# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import service
|
||||
import installutils
|
||||
import os
|
||||
import pwd
|
||||
import grp
|
||||
|
||||
import ldap
|
||||
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
from ipapython import sysrestore, ipautil, ipaldap
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform import services
|
||||
from ipalib import errors
|
||||
|
||||
|
||||
class ODSExporterInstance(service.Service):
|
||||
def __init__(self, fstore=None, dm_password=None):
|
||||
service.Service.__init__(
|
||||
self, "ipa-ods-exporter",
|
||||
service_desc="IPA OpenDNSSEC exporter daemon",
|
||||
dm_password=dm_password,
|
||||
ldapi=False,
|
||||
autobind=ipaldap.AUTOBIND_DISABLED
|
||||
)
|
||||
self.dm_password = dm_password
|
||||
self.ods_uid = None
|
||||
self.ods_gid = None
|
||||
self.enable_if_exists = False
|
||||
|
||||
if fstore:
|
||||
self.fstore = fstore
|
||||
else:
|
||||
self.fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
|
||||
suffix = ipautil.dn_attribute_property('_suffix')
|
||||
|
||||
def create_instance(self, fqdn, realm_name):
|
||||
self.backup_state("enabled", self.is_enabled())
|
||||
self.backup_state("running", self.is_running())
|
||||
self.fqdn = fqdn
|
||||
self.realm = realm_name
|
||||
self.suffix = ipautil.realm_to_suffix(self.realm)
|
||||
|
||||
try:
|
||||
self.stop()
|
||||
except:
|
||||
pass
|
||||
|
||||
# get a connection to the DS
|
||||
self.ldap_connect()
|
||||
# checking status step must be first
|
||||
self.step("checking status", self.__check_dnssec_status)
|
||||
self.step("setting up DNS Key Exporter", self.__setup_key_exporter)
|
||||
self.step("setting up kerberos principal", self.__setup_principal)
|
||||
self.step("disabling default signer daemon", self.__disable_signerd)
|
||||
self.step("starting DNS Key Exporter", self.__start)
|
||||
self.step("configuring DNS Key Exporter to start on boot", self.__enable)
|
||||
self.start_creation()
|
||||
|
||||
def __check_dnssec_status(self):
|
||||
ods_enforcerd = services.knownservices.ods_enforcerd
|
||||
|
||||
try:
|
||||
self.ods_uid = pwd.getpwnam(ods_enforcerd.get_user_name()).pw_uid
|
||||
except KeyError:
|
||||
raise RuntimeError("OpenDNSSEC UID not found")
|
||||
|
||||
try:
|
||||
self.ods_gid = grp.getgrnam(ods_enforcerd.get_group_name()).gr_gid
|
||||
except KeyError:
|
||||
raise RuntimeError("OpenDNSSEC GID not found")
|
||||
|
||||
def __enable(self):
|
||||
|
||||
try:
|
||||
self.ldap_enable('DNSKeyExporter', self.fqdn, self.dm_password,
|
||||
self.suffix)
|
||||
except errors.DuplicateEntry:
|
||||
root_logger.error("DNSKeyExporter service already exists")
|
||||
self.enable()
|
||||
|
||||
def __setup_key_exporter(self):
|
||||
installutils.set_directive(paths.SYSOCNFIG_IPA_ODS_EXPORTER,
|
||||
'SOFTHSM2_CONF',
|
||||
paths.DNSSEC_SOFTHSM2_CONF,
|
||||
quotes=False, separator='=')
|
||||
|
||||
def __setup_principal(self):
|
||||
assert self.ods_uid is not None
|
||||
dns_exporter_principal = "ipa-ods-exporter/" + self.fqdn + "@" + self.realm
|
||||
installutils.kadmin_addprinc(dns_exporter_principal)
|
||||
|
||||
# Store the keytab on disk
|
||||
installutils.create_keytab(paths.IPA_ODS_EXPORTER_KEYTAB, dns_exporter_principal)
|
||||
p = self.move_service(dns_exporter_principal)
|
||||
if p is None:
|
||||
# the service has already been moved, perhaps we're doing a DNS reinstall
|
||||
dns_exporter_principal_dn = DN(
|
||||
('krbprincipalname', dns_exporter_principal),
|
||||
('cn', 'services'), ('cn', 'accounts'), self.suffix)
|
||||
else:
|
||||
dns_exporter_principal_dn = p
|
||||
|
||||
# Make sure access is strictly reserved to the ods user
|
||||
os.chmod(paths.IPA_ODS_EXPORTER_KEYTAB, 0440)
|
||||
os.chown(paths.IPA_ODS_EXPORTER_KEYTAB, 0, self.ods_gid)
|
||||
|
||||
dns_group = DN(('cn', 'DNS Servers'), ('cn', 'privileges'),
|
||||
('cn', 'pbac'), self.suffix)
|
||||
mod = [(ldap.MOD_ADD, 'member', dns_exporter_principal_dn)]
|
||||
|
||||
try:
|
||||
self.admin_conn.modify_s(dns_group, mod)
|
||||
except ldap.TYPE_OR_VALUE_EXISTS:
|
||||
pass
|
||||
except Exception, e:
|
||||
root_logger.critical("Could not modify principal's %s entry: %s"
|
||||
% (dns_exporter_principal_dn, str(e)))
|
||||
raise
|
||||
|
||||
# limit-free connection
|
||||
|
||||
mod = [(ldap.MOD_REPLACE, 'nsTimeLimit', '-1'),
|
||||
(ldap.MOD_REPLACE, 'nsSizeLimit', '-1'),
|
||||
(ldap.MOD_REPLACE, 'nsIdleTimeout', '-1'),
|
||||
(ldap.MOD_REPLACE, 'nsLookThroughLimit', '-1')]
|
||||
try:
|
||||
self.admin_conn.modify_s(dns_exporter_principal_dn, mod)
|
||||
except Exception, e:
|
||||
root_logger.critical("Could not set principal's %s LDAP limits: %s"
|
||||
% (dns_exporter_principal_dn, str(e)))
|
||||
raise
|
||||
|
||||
def __disable_signerd(self):
|
||||
signerd_service = services.knownservices.ods_signerd
|
||||
|
||||
self.backup_state("singerd_running", signerd_service.is_running())
|
||||
self.backup_state("singerd_enabled", signerd_service.is_enabled())
|
||||
|
||||
# disable default opendnssec signer daemon
|
||||
signerd_service.stop()
|
||||
signerd_service.mask()
|
||||
|
||||
def __start(self):
|
||||
self.start()
|
||||
|
||||
def uninstall(self):
|
||||
if not self.is_configured():
|
||||
return
|
||||
|
||||
self.print_msg("Unconfiguring %s" % self.service_name)
|
||||
|
||||
running = self.restore_state("running")
|
||||
enabled = self.restore_state("enabled")
|
||||
|
||||
if enabled is not None and not enabled:
|
||||
self.disable()
|
||||
|
||||
if running is not None and running:
|
||||
self.start()
|
||||
|
||||
# restore state of dnssec default signer daemon
|
||||
signerd_enabled = self.restore_state("singerd_enabled")
|
||||
signerd_running = self.restore_state("singerd_runnning")
|
||||
signerd_service = services.knownservices.ods_signerd
|
||||
|
||||
signerd_service.unmask()
|
||||
|
||||
# service was stopped and disabled by setup
|
||||
if signerd_enabled:
|
||||
signerd_service.enable()
|
||||
|
||||
if signerd_running:
|
||||
signerd_service.start()
|
||||
@@ -0,0 +1,299 @@
|
||||
#
|
||||
# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
import random
|
||||
|
||||
import service
|
||||
import os
|
||||
import pwd
|
||||
import grp
|
||||
import stat
|
||||
|
||||
import _ipap11helper
|
||||
|
||||
import installutils
|
||||
from ipapython.ipa_log_manager import *
|
||||
from ipapython.dn import DN
|
||||
from ipapython import sysrestore, ipautil, ipaldap, p11helper
|
||||
from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
from ipalib import errors, api
|
||||
from ipaserver.install import dnskeysyncinstance
|
||||
|
||||
KEYMASTER = u'dnssecKeyMaster'
|
||||
softhsm_slot = 0
|
||||
|
||||
|
||||
def get_dnssec_key_masters(conn):
|
||||
"""
|
||||
:return: list of active dnssec key masters
|
||||
"""
|
||||
assert conn is not None
|
||||
|
||||
dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
|
||||
|
||||
filter_attrs = {
|
||||
u'cn': u'DNSSEC',
|
||||
u'objectclass': u'ipaConfigObject',
|
||||
u'ipaConfigString': [KEYMASTER, u'enabledService'],
|
||||
}
|
||||
only_masters_f = conn.make_filter(filter_attrs, rules=conn.MATCH_ALL)
|
||||
|
||||
try:
|
||||
entries = conn.find_entries(filter=only_masters_f, base_dn=dn)
|
||||
except errors.NotFound:
|
||||
return []
|
||||
|
||||
keymasters_list = []
|
||||
for entry in entries[0]:
|
||||
keymasters_list.append(str(entry.dn[1].value))
|
||||
|
||||
return keymasters_list
|
||||
|
||||
|
||||
def check_inst():
|
||||
if not os.path.exists(paths.ODS_KSMUTIL):
|
||||
print ("Please install the 'opendnssec' package and start "
|
||||
"the installation again")
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
class OpenDNSSECInstance(service.Service):
|
||||
def __init__(self, fstore=None, dm_password=None):
|
||||
service.Service.__init__(
|
||||
self, "ods-enforcerd",
|
||||
service_desc="OpenDNSSEC enforcer daemon",
|
||||
dm_password=dm_password,
|
||||
ldapi=False,
|
||||
autobind=ipaldap.AUTOBIND_DISABLED
|
||||
)
|
||||
self.dm_password = dm_password
|
||||
self.ods_uid = None
|
||||
self.ods_gid = None
|
||||
self.conf_file_dict = {
|
||||
'SOFTHSM_LIB': paths.LIBSOFTHSM2_SO,
|
||||
'TOKEN_LABEL': dnskeysyncinstance.softhsm_token_label,
|
||||
'KASP_DB': paths.OPENDNSSEC_KASP_DB,
|
||||
}
|
||||
self.kasp_file_dict = {}
|
||||
self.extra_config = [KEYMASTER]
|
||||
|
||||
if fstore:
|
||||
self.fstore = fstore
|
||||
else:
|
||||
self.fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
|
||||
suffix = ipautil.dn_attribute_property('_suffix')
|
||||
|
||||
def get_masters(self):
|
||||
if not self.admin_conn:
|
||||
self.ldap_connect()
|
||||
return get_dnssec_key_masters(self.admin_conn)
|
||||
|
||||
def create_instance(self, fqdn, realm_name, generate_master_key=True):
|
||||
self.backup_state("enabled", self.is_enabled())
|
||||
self.backup_state("running", self.is_running())
|
||||
self.fqdn = fqdn
|
||||
self.realm = realm_name
|
||||
self.suffix = ipautil.realm_to_suffix(self.realm)
|
||||
|
||||
try:
|
||||
self.stop()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# get a connection to the DS
|
||||
if not self.admin_conn:
|
||||
self.ldap_connect()
|
||||
# checking status must be first
|
||||
self.step("checking status", self.__check_dnssec_status)
|
||||
self.step("setting up configuration files", self.__setup_conf_files)
|
||||
self.step("setting up ownership and file mode bits", self.__setup_ownership_file_modes)
|
||||
if generate_master_key:
|
||||
self.step("generating master key", self.__generate_master_key)
|
||||
self.step("setting up OpenDNSSEC", self.__setup_dnssec)
|
||||
self.step("setting up ipa-dnskeysyncd", self.__setup_dnskeysyncd)
|
||||
self.step("starting OpenDNSSEC enforcer", self.__start)
|
||||
self.step("configuring OpenDNSSEC enforcer to start on boot", self.__enable)
|
||||
self.start_creation()
|
||||
|
||||
def __check_dnssec_status(self):
|
||||
named = services.knownservices.named
|
||||
ods_enforcerd = services.knownservices.ods_enforcerd
|
||||
|
||||
try:
|
||||
self.named_uid = pwd.getpwnam(named.get_user_name()).pw_uid
|
||||
except KeyError:
|
||||
raise RuntimeError("Named UID not found")
|
||||
|
||||
try:
|
||||
self.named_gid = grp.getgrnam(named.get_group_name()).gr_gid
|
||||
except KeyError:
|
||||
raise RuntimeError("Named GID not found")
|
||||
|
||||
try:
|
||||
self.ods_uid = pwd.getpwnam(ods_enforcerd.get_user_name()).pw_uid
|
||||
except KeyError:
|
||||
raise RuntimeError("OpenDNSSEC UID not found")
|
||||
|
||||
try:
|
||||
self.ods_gid = grp.getgrnam(ods_enforcerd.get_group_name()).gr_gid
|
||||
except KeyError:
|
||||
raise RuntimeError("OpenDNSSEC GID not found")
|
||||
|
||||
def __enable(self):
|
||||
try:
|
||||
self.ldap_enable('DNSSEC', self.fqdn, self.dm_password,
|
||||
self.suffix, self.extra_config)
|
||||
except errors.DuplicateEntry:
|
||||
root_logger.error("DNSSEC service already exists")
|
||||
self.enable()
|
||||
|
||||
def __setup_conf_files(self):
|
||||
if not self.fstore.has_file(paths.OPENDNSSEC_CONF_FILE):
|
||||
self.fstore.backup_file(paths.OPENDNSSEC_CONF_FILE)
|
||||
|
||||
if not self.fstore.has_file(paths.OPENDNSSEC_KASP_FILE):
|
||||
self.fstore.backup_file(paths.OPENDNSSEC_KASP_FILE)
|
||||
|
||||
pin_fd = open(paths.DNSSEC_SOFTHSM_PIN, "r")
|
||||
pin = pin_fd.read()
|
||||
pin_fd.close()
|
||||
|
||||
# add pin to template
|
||||
sub_conf_dict = self.conf_file_dict
|
||||
sub_conf_dict['PIN'] = pin
|
||||
|
||||
ods_conf_txt = ipautil.template_file(
|
||||
ipautil.SHARE_DIR + "opendnssec_conf.template", sub_conf_dict)
|
||||
ods_conf_fd = open(paths.OPENDNSSEC_CONF_FILE, 'w')
|
||||
ods_conf_fd.seek(0)
|
||||
ods_conf_fd.truncate(0)
|
||||
ods_conf_fd.write(ods_conf_txt)
|
||||
ods_conf_fd.close()
|
||||
|
||||
ods_kasp_txt = ipautil.template_file(
|
||||
ipautil.SHARE_DIR + "opendnssec_kasp.template", self.kasp_file_dict)
|
||||
ods_kasp_fd = open(paths.OPENDNSSEC_KASP_FILE, 'w')
|
||||
ods_kasp_fd.seek(0)
|
||||
ods_kasp_fd.truncate(0)
|
||||
ods_kasp_fd.write(ods_kasp_txt)
|
||||
ods_kasp_fd.close()
|
||||
|
||||
if not self.fstore.has_file(paths.SYSCONFIG_ODS):
|
||||
self.fstore.backup_file(paths.SYSCONFIG_ODS)
|
||||
|
||||
installutils.set_directive(paths.SYSCONFIG_ODS,
|
||||
'SOFTHSM2_CONF',
|
||||
paths.DNSSEC_SOFTHSM2_CONF,
|
||||
quotes=False, separator='=')
|
||||
|
||||
def __setup_ownership_file_modes(self):
|
||||
assert self.ods_uid is not None
|
||||
assert self.ods_gid is not None
|
||||
|
||||
# workarounds for packaging bugs in opendnssec-1.4.5-2.fc20.x86_64
|
||||
# https://bugzilla.redhat.com/show_bug.cgi?id=1098188
|
||||
for (root, dirs, files) in os.walk(paths.ETC_OPENDNSSEC_DIR):
|
||||
for directory in dirs:
|
||||
dir_path = os.path.join(root, directory)
|
||||
os.chmod(dir_path, 0770)
|
||||
# chown to root:ods
|
||||
os.chown(dir_path, 0, self.ods_gid)
|
||||
for filename in files:
|
||||
file_path = os.path.join(root, filename)
|
||||
os.chmod(file_path, 0660)
|
||||
# chown to root:ods
|
||||
os.chown(file_path, 0, self.ods_gid)
|
||||
|
||||
for (root, dirs, files) in os.walk(paths.VAR_OPENDNSSEC_DIR):
|
||||
for directory in dirs:
|
||||
dir_path = os.path.join(root, directory)
|
||||
os.chmod(dir_path, 0770)
|
||||
# chown to ods:ods
|
||||
os.chown(dir_path, self.ods_uid, self.ods_gid)
|
||||
for filename in files:
|
||||
file_path = os.path.join(root, filename)
|
||||
os.chmod(file_path, 0660)
|
||||
# chown to ods:ods
|
||||
os.chown(file_path, self.ods_uid, self.ods_gid)
|
||||
|
||||
def __generate_master_key(self):
|
||||
|
||||
with open(paths.DNSSEC_SOFTHSM_PIN, "r") as f:
|
||||
pin = f.read()
|
||||
|
||||
os.environ["SOFTHSM2_CONF"] = paths.DNSSEC_SOFTHSM2_CONF
|
||||
p11 = _ipap11helper.P11_Helper(softhsm_slot, pin, paths.LIBSOFTHSM2_SO)
|
||||
try:
|
||||
# generate master key
|
||||
root_logger.debug("Creating master key")
|
||||
p11helper.generate_master_key(p11)
|
||||
|
||||
# change tokens mod/owner
|
||||
root_logger.debug("Changing ownership of token files")
|
||||
for (root, dirs, files) in os.walk(paths.DNSSEC_TOKENS_DIR):
|
||||
for directory in dirs:
|
||||
dir_path = os.path.join(root, directory)
|
||||
os.chmod(dir_path, 0770 | stat.S_ISGID)
|
||||
os.chown(dir_path, self.ods_uid, self.named_gid) # chown to ods:named
|
||||
for filename in files:
|
||||
file_path = os.path.join(root, filename)
|
||||
os.chmod(file_path, 0770 | stat.S_ISGID)
|
||||
os.chown(file_path, self.ods_uid, self.named_gid) # chown to ods:named
|
||||
|
||||
finally:
|
||||
p11.finalize()
|
||||
|
||||
def __setup_dnssec(self):
|
||||
# run once only
|
||||
if self.get_state("KASP_DB_configured"):
|
||||
root_logger.debug("Already configured, skipping step")
|
||||
|
||||
self.backup_state("KASP_DB_configured", True)
|
||||
|
||||
if not self.fstore.has_file(paths.OPENDNSSEC_KASP_DB):
|
||||
self.fstore.backup_file(paths.OPENDNSSEC_KASP_DB)
|
||||
|
||||
command = [
|
||||
paths.ODS_KSMUTIL,
|
||||
'setup'
|
||||
]
|
||||
|
||||
ods_enforcerd = services.knownservices.ods_enforcerd
|
||||
ipautil.run(command, stdin="y", runas=ods_enforcerd.get_user_name())
|
||||
|
||||
def __setup_dnskeysyncd(self):
|
||||
# set up dnskeysyncd this is DNSSEC master
|
||||
installutils.set_directive(paths.SYSCONFIG_IPA_DNSKEYSYNCD,
|
||||
'ISMASTER',
|
||||
'1',
|
||||
quotes=False, separator='=')
|
||||
|
||||
def __start(self):
|
||||
self.restart() # needed to reload conf files
|
||||
|
||||
def uninstall(self):
|
||||
if not self.is_configured():
|
||||
return
|
||||
|
||||
self.print_msg("Unconfiguring %s" % self.service_name)
|
||||
|
||||
running = self.restore_state("running")
|
||||
enabled = self.restore_state("enabled")
|
||||
|
||||
for f in [paths.OPENDNSSEC_CONF_FILE, paths.OPENDNSSEC_KASP_FILE,
|
||||
paths.OPENDNSSEC_KASP_DB, paths.SYSCONFIG_ODS]:
|
||||
try:
|
||||
self.fstore.restore_file(f)
|
||||
except ValueError, error:
|
||||
root_logger.debug(error)
|
||||
pass
|
||||
|
||||
if enabled is not None and not enabled:
|
||||
self.disable()
|
||||
|
||||
if running is not None and running:
|
||||
self.start()
|
||||
Reference in new issue
Block a user