On Thu, Apr 14, 2016 at 04:39:37PM +1000, Fraser Tweedale wrote: > Hi all, > > The attached patches configure lightweight CA key replication on IPA > CAs, on upgrade and installation. > > Patches 0051..0052 from my other mail are also needed for the system > to work, but this patchset does not depend on them and can be > reviewed independently. > > There is also no hard dependency on the (unreleased) Dogtag 10.3.0b1 > - it just puts the necessary principals/keys/configuration in place. > > Cheers, > Fraser > New patches attached; 0054-2 changes the service name from 'dogtag-ipa-custodia' to just 'dogtag', and adds an ACI to allow the principal to search server Custodia keys.
Cheers, Fraser
From b30e8d640a03ec81d5a1f962a81076993d9cea69 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale <[email protected]> Date: Mon, 11 Apr 2016 12:42:35 +1000 Subject: [PATCH 53/54] Optionally add service name to Custodia key DNs Lightweight CAs support introduces new service principals for Dogtag, with Custodia keys. The current Custodia key creation uses a DN that contains only they key type and the hostname, so keys for multiple services on the same host cannot be created. Add the 'generate_keys' method to generate keys for a host or an arbitrary service. When a service name is given, include the service name in the DN. This change does not affect searching because all searching is done using the ipaKeyUsage and memberPrincipal attributes. Part of: https://fedorahosted.org/freeipa/ticket/4559 --- ipapython/secrets/kem.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/ipapython/secrets/kem.py b/ipapython/secrets/kem.py index 1025ed7980f055c82c602634e8845fa490cf0514..533121779241d30e19fef4c050bb69c55d29ec22 100644 --- a/ipapython/secrets/kem.py +++ b/ipapython/secrets/kem.py @@ -105,10 +105,11 @@ class KEMLdap(iSecLdap): encoding=serialization.Encoding.DER, format=serialization.PublicFormat.SubjectPublicKeyInfo) - def set_key(self, usage, host, principal, key): + def set_key(self, usage, servicename, host, principal, key): public_key = self._format_public_key(key) conn = self.connect() - name = '%s/%s' % (KEY_USAGE_MAP[usage], host) + service_segment = '~' + servicename if servicename else '' + name = '%s%s/%s' % (KEY_USAGE_MAP[usage], service_segment, host) dn = 'cn=%s,%s' % (name, self.keysbase) try: mods = [('objectClass', ['nsContainer', @@ -170,15 +171,18 @@ class IPAKEMKeys(KEMKeysStore): return conn.get_key(usage, kid) def generate_server_keys(self): - principal = 'host/%s@%s' % (self.host, self.realm) + self.generate_keys() + + def generate_keys(self, servicename=None): + principal = '%s/%s@%s' % (servicename or 'host', self.host, self.realm) # Neutralize the key with read if any self._server_keys = None # Generate private key and store it pubkeys = newServerKeys(self.config['server_keys'], principal) # Store public key in LDAP ldapconn = KEMLdap(self.ldap_uri) - ldapconn.set_key(KEY_USAGE_SIG, self.host, principal, pubkeys[0]) - ldapconn.set_key(KEY_USAGE_ENC, self.host, principal, pubkeys[1]) + ldapconn.set_key(KEY_USAGE_SIG, servicename, self.host, principal, pubkeys[0]) + ldapconn.set_key(KEY_USAGE_ENC, servicename, self.host, principal, pubkeys[1]) @property def server_keys(self): -- 2.5.5
From 8fa16b34e9c866d2f2470d70cb4b265e28013a16 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale <[email protected]> Date: Mon, 11 Apr 2016 16:47:33 +1000 Subject: [PATCH 54/54] Setup lightweight CA key retrieval on install/upgrade To configure Dogtag lightweight CA key replication on installation and upgrade: - add the 'dogtag/$HOSTNAME' service principal - create the pricipal's Custodia keys - add ACI to allow the principal to read server Custodia keys - retrieve keytab - configure the IPACustodiaKeyRetriever in CS.cfg Part of: https://fedorahosted.org/freeipa/ticket/4559 --- install/tools/ipa-ca-install | 4 ++++ install/updates/20-aci.update | 3 +++ ipaplatform/base/constants.py | 1 + ipaserver/install/cainstance.py | 43 +++++++++++++++++++++++++++++++++++++ ipaserver/install/server/install.py | 8 ++++++- ipaserver/install/server/upgrade.py | 6 +++++- 6 files changed, 63 insertions(+), 2 deletions(-) diff --git a/install/tools/ipa-ca-install b/install/tools/ipa-ca-install index 1bc5def03bf687a1e4f9fb38a54363b5429c8fc4..0af5b39116b4649423ed2a51579e2adc767d802b 100755 --- a/install/tools/ipa-ca-install +++ b/install/tools/ipa-ca-install @@ -226,6 +226,10 @@ def install_master(safe_options, options): ca.install_check(True, None, options) ca.install(True, None, options) + CA = cainstance.CAInstance( + api.env.realm, certs.NSS_DIR, host_name=api.env.host) + CA.setup_lightweight_ca_key_retrieval() + def install(safe_options, options, filename): options.promote = False diff --git a/install/updates/20-aci.update b/install/updates/20-aci.update index 4802ae0458e8b870bf3127764ebabac1a48f7cf2..2e9a36da442c392c9161861615b1744eeb6b799c 100644 --- a/install/updates/20-aci.update +++ b/install/updates/20-aci.update @@ -136,3 +136,6 @@ add:aci: (target = "ldap:///cn=replication,cn=etc,$SUFFIX")(targetattr = "nsDS5R dn: cn=ipa,cn=etc,$SUFFIX add:aci: (target = "ldap:///cn=*/($$dn),cn=custodia,cn=ipa,cn=etc,$SUFFIX")(version 3.0; acl "IPA server hosts can create own Custodia secrets"; allow(add) groupdn = "ldap:///cn=ipaservers,cn=hostgroups,cn=accounts,$SUFFIX" and userdn = "ldap:///fqdn=($$dn),cn=computers,cn=accounts,$SUFFIX";) add:aci: (target = "ldap:///cn=*/($$dn),cn=custodia,cn=ipa,cn=etc,$SUFFIX")(targetattr = "ipaPublicKey")(version 3.0; acl "IPA server hosts can manage own Custodia secrets"; allow(write) groupdn = "ldap:///cn=ipaservers,cn=hostgroups,cn=accounts,$SUFFIX" and userdn = "ldap:///fqdn=($$dn),cn=computers,cn=accounts,$SUFFIX";) + +# Dogtag service principals can search Custodia keys +add:aci: (target = "ldap:///cn=*,cn=custodia,cn=ipa,cn=etc,$SUFFIX")(targetattr = "ipaPublicKey || ipaKeyUsage || memberPrincipal")(version 3.0; acl "Dogtag service principals can search Custodia keys"; allow(read, search, compare) userdn = "ldap:///krbprincipalname=dogtag/*@$REALM,cn=services,cn=accounts,$SUFFIX";) diff --git a/ipaplatform/base/constants.py b/ipaplatform/base/constants.py index 3e1c4c6f761444bf1e8d527691aa53282e46f17e..26a9799838a2b3fb2d5ebab9e5e3cf7c4ba041ef 100644 --- a/ipaplatform/base/constants.py +++ b/ipaplatform/base/constants.py @@ -17,6 +17,7 @@ class BaseConstantsNamespace(object): NAMED_GROUP = "named" PKI_USER = 'pkiuser' PKI_GROUP = 'pkiuser' + PKI_GSSAPI_SERVICE_NAME = 'dogtag' # ntpd init variable used for daemon options NTPD_OPTS_VAR = "OPTIONS" # quote used for daemon options diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index a21f7d2671461dfb99797d39fc7ee5706317241f..7e1aaf5d7ae5744d043787d1b5d3ab6bf6fc7333 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -59,6 +59,7 @@ from ipapython.certdb import get_ca_nickname from ipapython.dn import DN from ipapython.ipa_log_manager import log_mgr,\ standard_logging_setup, root_logger +from ipapython.secrets.kem import IPAKEMKeys from ipaserver.install import certs from ipaserver.install import dsinstance @@ -66,6 +67,7 @@ from ipaserver.install import installutils from ipaserver.install import ldapupdate from ipaserver.install import replication from ipaserver.install import service +from ipaserver.install import sysupgrade from ipaserver.install.dogtaginstance import (export_kra_agent_pem, DogtagInstance) from ipaserver.plugins import ldap2 @@ -1356,11 +1358,52 @@ class CAInstance(DogtagInstance): self.step("updating IPA configuration", update_ipa_conf) self.step("Restart HTTP server to pick up changes", self.__restart_http_instance) + self.step("Configure lightweight CA key retrieval", + self.setup_lightweight_ca_key_retrieval) self.step("enabling CA instance", self.__enable_instance) self.start_creation(runtime=210) + def setup_lightweight_ca_key_retrieval(self): + if sysupgrade.get_upgrade_state('dogtag', 'setup_lwca_key_retrieval'): + return + + root_logger.info('[Set up lightweight CA key retrieval]') + + service = constants.PKI_GSSAPI_SERVICE_NAME + principal = '{}/{}@{}'.format(service, api.env.host, self.realm) + pent = pwd.getpwnam(constants.PKI_USER) + + root_logger.info('Creating principal') + installutils.kadmin_addprinc(principal) + self.suffix = ipautil.realm_to_suffix(self.realm) + if not self.admin_conn: + self.ldap_connect() + self.move_service(principal) + + root_logger.info('Retrieving keytab') + keytab = os.path.join(paths.PKI_TOMCAT, service + '.keytab') + installutils.create_keytab(keytab, principal) + os.chmod(keytab, 0o600) + os.chown(keytab, pent.pw_uid, pent.pw_gid) + + root_logger.info('Creating Custodia keys') + keyfile = os.path.join(paths.PKI_TOMCAT, service + '.keys') + keystore = IPAKEMKeys({'server_keys': keyfile}) + keystore.generate_keys(service) + os.chmod(keyfile, 0o600) + os.chown(keyfile, pent.pw_uid, pent.pw_gid) + + root_logger.info('Configuring key retriever') + installutils.set_directive( + paths.CA_CS_CFG_PATH, + 'features.authority.keyRetrieverClass', + 'com.netscape.ca.IPACustodiaKeyRetriever', + quotes=False, separator='=') + + sysupgrade.set_upgrade_state('dogtag', 'setup_lwca_key_retieval', True) + def replica_ca_install_check(config): if not config.setup_ca: diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index f01022c4c3a056513db47f70727aa48157a8c6f2..d9fcd7e6098c1bdd7647c300695f583f43bde9e5 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -892,7 +892,8 @@ def install(installer): ca.install_step_0(False, None, options) # Now put the CA cert where other instances exepct it - ca_instance = cainstance.CAInstance(realm_name, certs.NSS_DIR) + ca_instance = cainstance.CAInstance( + realm_name, certs.NSS_DIR, host_name=host_name) ca_instance.publish_ca_cert(CACERT) else: # Put the CA cert where other instances expect it @@ -922,6 +923,11 @@ def install(installer): # generated ds.add_cert_to_service() + if setup_ca: + # CA was configured before Kerberos; + # add Custodia client princ and keys now + ca_instance.setup_lightweight_ca_key_retrieval() + memcache = memcacheinstance.MemcacheInstance() memcache.create_instance('MEMCACHE', host_name, dm_password, ipautil.realm_to_suffix(realm_name)) diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index 3e60cfd3630c359268cf16219527088b5c63ba86..cc003c7146d547b5778f4d5d8d1c4f7eedc69ec7 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -1463,7 +1463,8 @@ def upgrade_configuration(): if subject_base: sub_dict['SUBJECT_BASE'] = subject_base - ca = cainstance.CAInstance(api.env.realm, certs.NSS_DIR) + ca = cainstance.CAInstance( + api.env.realm, certs.NSS_DIR, host_name=api.env.host) with installutils.stopped_service('pki-tomcatd', 'pki-tomcat'): # Dogtag must be stopped to be able to backup CS.cfg config @@ -1658,6 +1659,9 @@ def upgrade_configuration(): ca_import_included_profiles(ca) add_default_caacl(ca) + if ca.is_configured(): + ca.setup_lightweight_ca_key_retrieval() + set_sssd_domain_option('ipa_server_mode', 'True') if ds_running and not ds.is_running(): -- 2.5.5
-- Manage your subscription for the Freeipa-devel mailing list: https://www.redhat.com/mailman/listinfo/freeipa-devel Contribute to FreeIPA: http://www.freeipa.org/page/Contribute/Code
